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

C 語言迴圈的小藝術:質數判斷、菱形列印、幻方生成與字串循環移位的極致優雅

     編輯:關於C語言

1. 質數判斷:從暴力遞迴到 6k±1 極致優化

最直觀寫法:

int isPrime(int n) {
    int i;
    for (i = 2; i < n; i++)
        if (n % i == 0) break;
    return i >= n;
}

平方根優化:

int isPrime(int n) {
    int i, s = (int)(sqrt((double)n) + 0.01);
    for (i = 2; i <= s; i++)
        if (n % i == 0) break;
    return i > s;
}

消除偶數:

int isPrime(int n) {
    int i, s = (int)(sqrt((double)n) + 0.01);
    if (n <= 3) return 1;
    if (n % 2 == 0) return 0;
    for (i = 3; i <= s; i += 2)
        if (n % i == 0) break;
    return i > s;
}

終極優化:所有大於 4 的質數,除以 6 餘數只能是 1 或 5(即 6k±1 形式)。步長在 2、4 間切換(5→+2→7→+4→11→+2→13...):

int isPrime(int n) {
    int i, s = (int)(sqrt((double)n) + 0.01), step = 4;
    if (n <= 3) return 1;
    if (n % 2 == 0) return 0;
    if (n % 3 == 0) return 0;
    for (i = 5; i <= s; i += step) {
        if (n % i == 0) break;
        step ^= 6; // 異或切換 2↔4:2^4=6, 6^2=4, 6^4=2
    }
    return i > s;
}

思考題:如何構造三值或四值循環步長?

2. 菱形列印:座標幾何與絕對值的對稱之美

傳統上下拆分打印代碼冗餘難讀。利用對稱性:以中心為 (0,0),輸出星號的座標滿足 |x| + |y| <= size。雙重迴圈從 -size 到 size,取絕對值即得對稱:


void print(int size) {
    int x, y;
    for (y = -size; y <= size; y++) {
        for (x = -size; x <= size; x++) {
            if (abs(x) + abs(y) <= size) putchar('*');
            else putchar(' ');
        }
        putchar('\n');
    }
}

變體:

  • 空心菱形:條件改為 == size;
  • 字母層菱形:putchar('A' + (size - abs(x) - abs(y)));
  • X 形:留作思考題。

3. 奇數階幻方:從二維迴圈到一維數學映射

3×3 幻方:

4 3 8
9 5 1
2 7 6

向右複製 5 次、向下 3 次展開,藍色數字走向呈現規律。任意任意 n+1 的座標(左上角為 0,0):


x = 2 + n + n / 3;
y = 1 + n - n / 3;

推廣至任意奇數 size(整除):


x = size/2 + 1 + n + n/size;
y = size/2 + n - n/size;

複雜雙重迴圈化為單迴圈:


#define SIZE 5
int main() {
    int x, y, i, sqSize = SIZE*SIZE, hSize = SIZE/2;
    int sqMap[SIZE][SIZE];
    for (i = 0; i < sqSize; i++) {
        x = hSize + 1 + i + i/SIZE;
        y = hSize + i - i/SIZE;
        sqMap[y%SIZE][x%SIZE] = i + 1;
    }
    // 輸出...
}

比網上常見魔方陣代碼短小許多。

4. 字串循環左移:三次反轉的數學魔術

題目:"abcdefg" 循環左移 2 位 → "cdefgab",限 O(1) 空間。
反轉字串無需額外陣列(頭尾交換)。三次反轉法:


// 反轉 [st, ed)
void str_rev(char* st, char* ed) {
    for (--ed; st < ed; ++st, --ed) {
        char c = *st; *st = *ed; *ed = c;
    }
}
// 循環左移 n 位
char* str_shl(char* st, char* ed, int n) {
    str_rev(st, &st[n]);      // 反轉前 n
    str_rev(&st[n], ed);      // 反轉後段
    str_rev(st, ed);          // 整體反轉
    return st;
}

驗證:"abcdefghijklmnopqrstuvwxyz" 左移 6 位 → "ghijklmnopqrstuvwxyzabcdef"。
原理:分兩段(前 n、其餘),分別反轉再整體反轉 = 循環左移(先整體再分段 = 循環右移)。

—— 作者:Csdn_zc 的專欄

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