2017-06-20 65 views
-1

給定一個字符串,我想打印所有的組合,從左到右選擇字母:Ex。輸入:ABCD 輸出: ABC ACD ABD BCD 交流 廣告 BC BD CD從左到右打印字符串組合(不是置換)C++

我能做到這一點,但我不能概括它,爲前。在字符串abcd中,我可以通過刪除只有一個字母來獲得所有提到的組合。然後我可以通過刪除兩個字母等來實現。 代碼:

name = "abcdefghi"; 

//刪除2個字母

for(int i = 1; i < name.size(); i++){ 

    for(int k = 2; k < name.size(); k++){ 

     for(int j = 0; j < name.size(); j++){ // PRINT ARRAY 
      if(j != i && j != k) cout << name[j]; 
     } 
     cout << endl; 

     } 

    } 

//刪除1個字母:

for(int i = 1; i < name.size(); i++){ 

     for(int j = 0; j < name.size(); j++){ // PRINT ARRAY 
      if(j != i) cout << name[j]; 
     } 
     cout << endl; 

    } 

我怎麼能概括它,這樣我可以先打印1組合字母缺失,然後2個字母丟失,然後3,依此類推... 因爲如果我繼續這樣下去,要得到所有組合中缺少1到n的字母,我需要的for循環n個...

+0

所以你不希望與所有的信件太多的組合?你想從-1字符開始? – koleygr

+0

在你的問題一個簡單的答案是把你的循環在另一個循環,將刪除字母...你可以開始刪除一個或刪除零字符 – koleygr

+1

[創建所有可能的K組合中的n項的所有可能的重複]( https://stackoverflow.com/questions/12991758/creating-all-possible-k-combinations-of-n-items-in-c) – ljeabmreosn

回答

0

你可以做這樣的例子:

print_combinations(const string& name) { 
    if(name.size() > 1) { 
     for(int i = 0; i < name.size(); ++i) { 
      string name2 = name; 
      name2.erase(i, 1); 
      cout << name2; 
     } 
     for(int i = 0; i < name.size(); ++i) { 
      string name2 = name; 
      name2.erase(i, 1); 
      print_combinations(name2); 
     } 
    } 
} 
0

目前,您可以使用一個計數器,並以此爲標誌,是這樣的:

void print_combinations(const std::string& s) 
{ 
    if (s.size() >= 32) { 
     return; // String too long 
    } 
    std::uint32_t end = 1u << s.size(); 
    for (std::uint32_t i = 0; i != end; ++i) 
    { 
     auto j = i; 
     for (const auto c : s) 
     { 
      if ((j & 1) != 0) { 
       std::cout << c; 
      } 
      j >>= 1; 
     } 
     std::cout << std::endl; 
    } 
} 

Demo