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

空間換時間:撲克牌排序的查表法實現

     編輯:關於C語言

問題背景

鬥地主遊戲中需將 54 張牌按「大王 > 小王 > 2 > A > K … > 3」,同點數按「黑桃 > 紅心 > 梅花 > 方塊」排序。傳統比較排序需自定比較器、多次分支判斷,效率與代碼複雜度皆非最優。

核心思想:預計算排序映射表

將「理想順序」固化為一個靜態陣列 SortedCard[54],元素值為原始牌面編碼(0-53)。排序時只需**一次線性掃描**:遍歷映射表,若手牌位圖中對應位為 1 則輸出。時間複雜度 O(54) ≒ O(1),極致體現「空間換時間」。

編碼規約

// 原始編碼 0-53
// 0-12   : 黑桃 A-K
// 13-25  : 紅心 A-K
// 26-38  : 梅花 A-K
// 39-51  : 方塊 A-K
// 52     : 小王
// 53     : 大王

完整可編譯範例

#include <stdio.h>
#include <string.h>

#define TOTAL_CARDS 54

// 理想輸出順序:大王、小王、四張2、四張A、四張K ... 四張3
static const int SortedCard[TOTAL_CARDS] = {
    53, 52,                         // 大王、小王
    1, 14, 27, 40,                  // 2
    0, 13, 26, 39,                  // A
    12, 25, 38, 51,                 // K
    11, 24, 37, 50,                 // Q
    10, 23, 36, 49,                 // J
    9, 22, 35, 48,                  // 10
    8, 21, 34, 47,                  // 9
    7, 20, 33, 46,                  // 8
    6, 19, 32, 45,                  // 7
    5, 18, 31, 44,                  // 6
    4, 17, 30, 43,                  // 5
    3, 16, 29, 42,                  // 4
    2, 15, 28, 41                   // 3
};

void print_sorted_hand(const int hand[TOTAL_CARDS]) {
    for (int i = 0; i < TOTAL_CARDS; ++i) {
        int code = SortedCard[i];
        if (hand[code]) {
            // 這裡可對 code 進一步解碼為花色/點數字串
            printf("%d ", code);
        }
    }
    putchar('\n');
}

int main() {
    // 模擬一手牌:大王、黑桃2、紅心A、方塊3
    int hand[TOTAL_CARDS] = {0};
    hand[53] = 1;   // 大王
    hand[1]  = 1;   // 黑桃2
    hand[13] = 1;   // 紅心A
    hand[41] = 1;   // 方塊3

    print_sorted_hand(hand);
    return 0;
}

擴展:花色/點數解碼輔助函式


const char* rank_str(int code) {
    static const char* r[] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    if (code == 52) return "小王";
    if (code == 53) return "大王";
    return r[code % 13];
}
const char* suit_str(int code) {
    if (code >= 52) return "";
    static const char* s[] = {"黑桃","紅心","梅花","方塊"};
    return s[code / 13];
}

何時適用「查表法」?

  • **定義域小且固定**(撲克牌、象棋棋盤、CRC 查表、狀態機跳轉)。
  • **比較/計算成本高**(複雜排序規則、非線性映射)。
  • **記憶體預算充足**(嵌入式需權衡)。

總結

以 54 元素靜態表替代動態比較排序,代碼簡潔、無分支預測失誤、確定性延遲,是遊戲邏輯、协议解析、嵌入式系統中常見的**工程智慧**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved