C 语言编程—语法练习
 作者:向阳逐梦
- 2023-06-18  四川
 本文字数:1828 字
阅读完需:约 6 分钟

 题目:有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
程序分析:可填在百位、十位、个位的数字都是 1、2、3、4,组成所有的排列后再去掉不满足条件的排列。
实例:
#include<stdio.h> int main(){    int i,j,k;    printf("\n");    for(i=1;i<5;i++) { // 以下为三重循环        for(j=1;j<5;j++) {            for (k=1;k<5;k++) { // 确保i、j、k三位互不相同                if (i!=k&&i!=j&&j!=k) {                     printf("%d,%d,%d\n",i,j,k);                }            }        }    }}
复制代码
 以上实例输出结果为:
1,2,31,2,41,3,21,3,41,4,21,4,32,1,32,1,42,3,12,3,42,4,12,4,33,1,23,1,43,2,13,2,43,4,13,4,24,1,24,1,34,2,14,2,34,3,14,3,2复制代码
 1、为了尽量减少不必要的循环,做了如下的小优化。
#include <stdio.h>#include <stdint.h>
int main(){    uint32_t i; // 百位    uint32_t j; // 十位    uint32_t k; // 个位        for (i=1; i<5; i++)    {        for (j=1; j<5; j++)        {            // 百位与十位重复            // 跳过当前十位            if (j==i)            {                continue;            }                        for (k=1; k<5; k++)            {                // 个位与百位或十位重复                // 跳过当前个位                if (k==j || k==i)                {                    continue;                }                                printf("%u,%u,%u\n", i, j, k);            }        }    }}复制代码
 2、参考方法:
#include<stdio.h>int main(void){    int i,j,k;    for(i = 1;i < 5;i++)    {        for(j = 1;j < 5;j++)        {            if(i == j)                continue;            for(k = 1;k < 5;k++)            {                if(i == k || j == k)                    continue;                printf("%d,%d,%d\n",i,j,k);            }        }    }    return 0;}复制代码
 3、深搜法(DFS)写此题:
#include <stdio.h>#include <stdlib.h>
int  b[4],arr[4];//定义两个数组用来类比int Count=0;//计数器void DFS(int step){    if(step==5){        if(arr[1]!=arr[2]&& arr[1]!=arr[3]&&arr[2]!=arr[3]){//判断哪些符合条件            Count++;            printf("%d%d%d\n",arr[1],arr[2],arr[3]);//输出可用排列        }        return ;    }
    for(int i=1;i<=4;i++){        if(b[i]==0){            arr[step]=i;            b[i]=1;//排除重复            DFS(step+1);//自己调用自己            b[i]=0;        }    }    return ;}
int main(void){    DFS(1);    printf("共有%d种",Count);    return 0;}复制代码
 4、使用递归与链表:
#include <stdio.h>
#define NUM 4  // 数字个数#define LEN 3  // 排列出的数字的长度
struct number {    int val;    struct number *next;} list[NUM];
void permutation(struct number *list, int m){    static int array[LEN];    struct number *p, *piror, *head;    if(m)  // 如果此次还未排列好,则选择剩余数字继续排列        for(piror=NULL, p=list, head=list; p; piror=p, p=p->next)        {            array[LEN - m] = p->val;  // 将排列结果临时存入数组            if(piror)  // 如果本次选择的数字不在表头            {                 piror->next = p->next;  // 重组链表进行下一位数的排列                 permutation(head, m-1);                 piror->next = p;  // 还原链表            }            else permutation(p->next, m-1);        }    else  // 否则打印出此次排列出的数字    {        int i;        for(i=0; i<LEN; i++)            printf("%d%c", array[i], i==LEN-1? '\n': ',');    }}
int main(){    int i;    // 初始化链表    for(i=0; i<NUM; i++)    {        list[i].val = i + 1;        list[i].next = list + i + 1;    }    list[NUM - 1].next = NULL;
    // 递归打印排列结果    permutation(list, LEN);    return 0;}
复制代码
 递归排列的过程中逐一将选中的数字从链表中删除,直接避免组成的三位数中出现重复数字。
划线
评论
复制
发布于: 刚刚阅读数: 3
版权声明: 本文为 InfoQ 作者【向阳逐梦】的原创文章。
原文链接:【http://xie.infoq.cn/article/35d8828a4762b16a1fb137d22】。文章转载请联系作者。
向阳逐梦
关注
人生享受编程,编程造就人生! 2022-06-01 加入
某公司芯片测试工程师,嵌入式开发工程师,InfoQ签约作者,阿里云星级博主,华为云·云享专家。座右铭:向着太阳,追逐梦想!










    
评论