0
点赞
收藏
分享

微信扫一扫

使用OpenFeign+Eureka实现HTTP调用的简单示例

大漠雪关山月 2024-11-20 阅读 8

题目

有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

分析

可填在百位、十位、个位的数字都是 1、2、3、4,组成所有的排列后再去掉不满足条件的排列。

实例代码

#include<stdio.h>
// 程序入口 
int main()
{
	// [0] 定义了三个整型变量 `i`、`j` 和 `k`,它们将分别用于表示三位数的百位、十位和个位上的数字
    int i = 0;
    int j = i;
    int k = i;
    // [0]
    // [1] 输出`换行`
    printf("\n");
    // [1]
    // [2] 以下为三重循环
    // [3] 遍历百位上可能出现的数字,从 `1` 开始,到 `4` 结束(因为题目给定的数字是 `1`、`2`、`3`、`4`),每次循环 `i` 的值都会改变,代表不同的百位数字
    for(i = 1; i < 5; i++) { 
        // [4] 遍历十位上可能出现的数字,同样是从 `1` 到 `4`
        for(j = 1; j < 5; j++) {
            // [5] 遍历个位上可能出现的数字,同样是从 `1` 到 `4`
            for (k = 1; k < 5; k++) {
            	// [6] 确保i、j、k三位数互不相同
                if ( (i!=k) && (i!=j) && (j!=k) ) { 
                	// [7] `printf` 函数中的 `%d%d%d ` 是格式化输出的占位符,分别对应 `i`、`j`、`k` 这三个变量的值,输出时会按照顺序将它们组成一个三位数并打印出来,每个三位数后面跟着一个空格
                    printf("%d,%d,%d ", i, j, k);
                    // [7]
                }
                // [6]
            }
            // [5]
        }
        // [4]
    }
    // [3]
    // [2]
    // 程序正常结束
    return 0;
}

以上实例代码存在以下两点可优化的方面:

  • 1.存在多余比较:在最内层的循环判断条件中,每次都要进行三次比较(i!=k) && (i!=j) && (j!=k)来确保三个数字互不相同。实际上,在外层循环已经对百位和十位数字做了一定的限制(比如百位从14依次取值,十位在每次百位确定后也从14取值且与百位不同),所以到内层判断个位数字时,有些比较是多余的。例如,当百位是1,十位是2时,在判断个位数字时其实只需要判断个位数字不等于1且不等于2即可,而不需要再判断十位不等于百位这种已经确定的情况,这会导致一些不必要的计算开销,尤其在处理更复杂的数字组合或数字范围更大时,这种多余的比较可能会累积影响效率。
  • 2.未利用已有条件优化循环范围:在每个循环中,都是从14进行完整的遍历。可以考虑根据前面已经确定的数字来缩小后续循环的范围,比如十位数字的循环可以从百位数字+1开始(确保与百位不同且能减少循环次数),个位数字的循环也可以根据百位和十位数字进一步优化范围,这样能减少不必要的循环迭代次数,从而提高运行效率。

优化方法1之减少不必要的循环次数

在实例代码中,内层循环每次都要从 1 遍历到 4,即使前面已经确定了百位和十位数字,有些情况是可以提前判断并跳过不必要的循环的。
十位数字的循环从 i + 1 开始,这样就避免了重复判断十位数字等于百位数字的情况,减少了一些不必要的循环次数。

#include <stdio.h>

int main() {
    int i, j, k;

    // 百位数字的循环
    for (i = 1; i < 5; i++) {
        // 十位数字的循环,注意要和百位数字不同
        for (j = 1; j < 5; j++) {
            if (j!= i) {
                // 个位数字的循环,要和百位、十位数字都不同
                for (k = 1; k < 5; k++) {
                    if (k!= i && k!= j) {
                        // 输出满足条件的三位数
                        printf("%d%d%d ", i, j, k);
                    }
                }
            }
        }
    }

    return 0;
}

优化方法2之使用位运算进行标记

利用位运算来标记已经使用过的数字,从而快速判断是否满足无重复数字的条件。
通过位运算来快速判断数字是否已经被使用过,相比于原始代码中的多次条件判断,在某些情况下可能会提高执行效率,尤其是当需要处理的数字范围较大且重复判断较多时,位运算的优势会更加明显。不过这种方法相对来说理解起来可能会稍微复杂一些。

#include <stdio.h>

int main() {
    int i, j, k;

    // 百位数字的循环,从1到4
    for (i = 1; i < 5; i++) {
        // 使用位运算标记百位数字已经被使用
        int used = 1 << (i - 1);

        // 十位数字的循环,从1到4
        for (j = 1; j < 5; j++) {
            // 如果十位数字未被使用(通过位运算判断)
            if (!(used & (1 << (j - 1)))) {
                // 更新位标记,表示十位数字也被使用了
                used |= (1 << (j - 1));

                // 个位数字的循环,从1到4
                for (k = 1; k < 5; k++) {
                    // 如果个位数字未被使用(通过位运算判断)
                    if (!(used & (1 << (k - 1)))) {
                        // 输出满足条件的三位数
                        printf("%d%d%d ", i, j, k);
                    }
                }

                // 清除十位数字的位标记,以便下一次十位数字循环时重新判断
                used &= ~(1 << (j - 1));
            }
        }
    }

    return 0;
}

输出结果

123 124 132 134 142 143 213 214 231 234 241 243 312 314 321 324 341 342 412 413 421 423 431 432 

高价出售本人脑子没有用过有意者私。

举报

相关推荐

0 条评论