1. 程式人生 > >生成字串

生成字串

Description

假設一個字串只由字元‘0’,‘1’,‘?’組成,其中字元‘?’表示該字元可由字元‘0’或‘1’替代。

現有一些字串,根據這些字串生成所有可生成的字串。

如:{10,?1,0? }可生成{10,01,11,00}

{101,001,?01}可生成{101,001}

注意後一個例子中‘?01’並沒有生成新的字串。

Input

輸入包含多組測試資料。

每組資料的第一行是兩個整數M,N(1≤M≤15,0≤N≤2500)。M表示字串的長度,N表示字串的個數。兩個整數之間由一個空格隔開。以下N行每行各有一個字串。檔案中各行的行首、行末沒有多餘的空格。

當M=N=0時表示輸入結束。

解題思路:主要的思路是對於輸入的字串,將其當做數字看待,對於'?'則分別用0和1代替。這裡使用的是回溯演算法求解。用一個一維陣列,對於已經存在的數進行標記。

#include <iostream>
#include <string.h>
using namespace std;
char inStr[18];
bool is_existed[1<<16];
int M, N;
int Total;
void backtrack(int presum, int k){
    if (inStr[k]  == '\0') {   // 字串已輸入完畢
        if (!is_existed[presum]) {  // 該字串是否已經存在
            is_existed[presum] = true;
            Total ++;
        }
    }
    else if(inStr[k] == '?'){
        
        backtrack(presum << 1, k+1);             // 使用0代替?,進行下一步統計
        backtrack((presum << 1) + 1, k +1);      // 使用1代替?,進行下一步統計
    }
    else{
        presum = (presum << 1) + inStr[k] -'0';  //進行下一步統計
        backtrack(presum, k+1);
    }
}
int main(){
    while (cin >> M >> N) {
        if (M == 0 && N == 0) break;
        memset(is_existed, false, sizeof(is_existed));
        Total = 0;
        for (int i = 0; i < N; i++) {
            cin >> inStr;
            backtrack(0, 0);
        }
        cout << Total << endl;
    }
    return 0;
}