打印 a 到 z 中任取 3 個元素的組合

現在有 a 到 z 26 個元素, 編寫程序打印 a 到 z 中任取 3 個元素的組合(比如 打印 a b c ,d y z等)

 
分析: 
大家看看我這麼做行不

char a, b, c;
for(a = 'a'; a<='z'; a++)
    for(b= a+1; b<='z'; b++)
        for(c = b+1; c<='z'; c++)
            printf("%c%c%c\n", a, b, c);12345

 
問題1:不可能出現 bac等。因爲每次我多加了 1 看看嵌套的 for 有什麼不同,但是題目要求只求組合不管順序。 
問題2:如果你要這麼做 ,面試官必然會問 ,如果我要求 4 個字母的組合呢?(一臉懵逼狀=。=) 
 
思路: 
我設想 a - z 每個字母給一個標記 0 或 1 ,如果爲 1 的時候表示這個字符在組合中 ,如果爲 0 那麼表示這個字符不在組合中。 
 
這樣子,我們需要 26 個標記位。 
 
這個時候我們會發現 ,當所有變量都在組合中時, 那麼就是 26 個 1;當一個變量都不在集組合中時,就是 26 個 0。 
 
我們把 26 個 1 和 26 個 0 看成數字,那麼就是 0 和 (1 << 26) - 1。 
那麼其它的組合,肯定是 0 到 (1 << 26) - 1 之間的數字,對吧 
 
比如  
cba 就是 …0000000111 
dcba 就是 …00000000001111 
 
所以說 我們做一個循環 從 0 開始 到(1 << 26) - 1 
然後只取有 3 個 1 的數字 
然後再看對應的 1 代表哪個字符就可以了 
具體就要看程序了:

#include <stdio.h>
//某個數二進制位上有幾個 1
int bit(unsigned int x)
{
    int c = 0;
    while( x )
    {
        c++;
        x = (x & (x - 1));
    }
    return c;
}

void print(unsigned int x, int count)
{
    int i = 0;
    //控制,假如count爲3, x 裏邊有三個 1
    if( bit(x) == count )
    {
        for(i=0; i<26; i++)
        {
            if( x & 1)
            {
                printf("%c ", (char)('a' + i));
            }
            x = (x >> 1);
        }
        printf("\n");
    }
}
int main()
{
    const unsigned int N = 26;
    const unsigned int C = 3;
    const unsigned int X = (1 << N) - 1;  //X=(1<<26)-1
    unsigned int i = 0;

    for(i=0; i<X; i++)
    {
        print(i, C);
    }
    return 0;
}

 

轉自:https://blog.csdn.net/lvonve/article/details/53320680

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章