首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言排列組合練習:1-4 數字組成無重複三位數的枚舉與優化

     編輯:關於C語言

問題描述

給定數字 1、2、3、4,組成互不相同且無重複數字的三位數。求總個數並列出所有數字。核心考點:三重循環枚舉、去重條件判斷、排列數學公式驗證。

標準實現:三重循環 + 條件過濾


#include <stdio.h>

int main() {
    int i, j, k;
    int count = 0;
    int results[100];  // 足夠大

    for (i = 1; i <= 4; i++) {        // 百位
        for (j = 1; j <= 4; j++) {    // 十位
            if (i == j) continue;     // 百位≠十位
            for (k = 1; k <= 4; k++) { // 個位
                if (k == i || k == j) continue; // 個位≠百位且≠十位
                results[count++] = i * 100 + j * 10 + k;
            }
        }
    }

    printf("共有 %d 個互不相同無重複的三位數:\n", count);
    for (i = 0; i < count; i++) {
        printf("%d ", results[i]);
        if ((i + 1) % 8 == 0) printf("\n");  // 8個換行
    }
    printf("\n");
    return 0;
}

數學驗證:排列數 P(4,3) = 4 × 3 × 2 = 24

從 4 個不同元素中取 3 個有序排列:P(n,k) = n!/(n-k)!。程序輸出應為 24 個。

輸出結果示例

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

算法優化方案對比

方案時間複雜度空間特點
三重循環過濾 (原版)O(n³) = 64 次迭代O(k)直觀、易理解、常數小
遞歸回溯 (通用全排列)O(P(n,k)) = 24 次遞歸O(k) 棧無冗餘迭代、通用性強
next_permutation (C++ STL)O(k!) 排序 + O(k) 生成O(1)C++ 首選、字典序生成
位掩碼枚舉O(2^n) = 16 狀態O(1)位運算技巧、適合 n≤32

遞歸回溯通用實現 (C 語言)


void permute(int *nums, int n, int *used, int *path, int depth, int k) {
    if (depth == k) {
        // 輸出 path[0..k-1]
        return;
    }
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            used[i] = 1;
            path[depth] = nums[i];
            permute(nums, n, used, path, depth + 1, k);
            used[i] = 0;
        }
    }
}

// 調用
int nums[] = {1,2,3,4};
int used[4] = {0}, path[3];
permute(nums, 4, used, path, 0, 3);

位掩碼枚舉技巧 (n=4 時極簡)


for (int mask = 0; mask < (1<<4); mask++) {
    if (__builtin_popcount(mask) != 3) continue;  // 僅3個位元為1
    int digits[3], idx = 0;
    for (int i = 0; i < 4; i++)
        if (mask & (1<

工程化增強:輸入任意數字集合


int count_unique_numbers(int *digits, int n, int k, int **out) {
    // 動態分配結果數組,最大 P(n,k)
    int max = 1;
    for (int i = 0; i < k; i++) max *= (n - i);
    *out = malloc(max * sizeof(int));

    // 回溯生成...
    return actual_count;
}

總結

無重複三位數枚舉是「排列生成、條件過濾、數學驗證」的基礎練習。關鍵收穫:

  • 三重循環 + continue 過濾是最直觀的「暴力枚舉」;
  • 數學公式 P(n,k) 是檢查結果正確性的金標準;
  • 遞歸回溯是通用排列生成模板,時間複雜度最優 (僅生成有效排列);
  • 位掩碼 + 內建函數 (__builtin_popcount) 是位運算愛好者的優雅技巧;
  • 實戰中 C++ STL next_permutation 為首選,C 語言需手寫回溯或引入庫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved