1. 程式人生 > >一道百度機器學習工程師職位的面試題

一道百度機器學習工程師職位的面試題

題目:現在有 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);


問題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; }


我去,這個解法真是吊炸天啊!#=,=