現在有 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;
}