我遇到了问题。我想迭代字母表中26个字母的所有可能组合(好吧......只有25个字母,我想排除'q')。它似乎很简单,但事实证明很难。我想从包含z不包括q的char *和for循环开始,它将翻阅这些字母的每个可能组合(顺序重要,没有重复的字母),执行一个函数来检查该组合是否是我的那个寻找。
std :: next_permutation对我的方案不起作用。 具体来说,我需要向后迭代的代码。从...开始: 一个bcd .... z, b acde .... z, c abde .... z, ... z abcd .... y,
ab cdef .... z,
ac bdef .... z,
广告
..
AZ
BA 公元前 BD
几乎可以得出两个字母单词的每个组合,然后是三个字母,然后是四个字母,添加其余的字母后缀。 我有代码添加其余的字母表,所以我需要的只是第一部分。
在我弄清楚如何生成n个字母的单词之后,它会导致重复。通过每两个字母单词迭代,我得到“ab ac ad ... az ba bc bd .. bz”但请记住我将abcdef..z添加到它的末尾(不包括用完的字母)所以它实际上是“abcd。 .z acbde..z adbcef..z“等两个字母的单词ab和三个字母的单词abc重叠,这对于较大的关键字来说是低效的。
答案 0 :(得分:1)
您可以使用回溯的想法开始。但生成25!是一项艰巨的任务。对于普通计算机来说,迭代这么大的搜索空间会花费很多(我的意思很多)。 您应该通过考虑这样的情况来尝试PRUNE您的搜索空间,您确信它永远不会出现在所需的输出中。 您应该寻找一种称为回溯的技术。
答案 1 :(得分:1)
试试这个。我通常避免递归,但这里效果很好:
#include <vector>
#include <set>
#include <iostream>
#include <algorithm>
using std::vector;
using std::cout;
using std::endl;
using std::find;
void printVec(vector<char> &vec)
{
for(int i = 0; i < vec.size(); i++)
{
cout << vec[i];
}
cout << endl;
}
void incrementCharAvoidingDuplicates(vector<char> v, char &c)
{
// increment newChar until we find one not in the vector already
while(std::find(v.begin(), v.end(), c)!=v.end())
{
c++;
}
}
bool incrementVec(vector<char> &v)
{
if(v.size() == 0 || v.size() >= 25)
return false;
//try incrementing the final character
char newChar = v.back() + 1;
incrementCharAvoidingDuplicates(v, newChar);
// if it's still in range, we have succesfully incremented the vector
if(newChar <= 'z')
{
v.back() = newChar;
return true;
}
// if not (e.g. "abz") then remove the final character and try to increment the base part instead
else
{
vector<char> w(v.begin(), v.end() - 1);
if(incrementVec(w))
{
// we succeeded in incrementing the base ... so find a remaining character that doesn't conflict and append it
// (note there will always be one since we insisted size < 25)
v.resize(w.size());
std::copy(w.begin(), w.end(), v.begin());
char newChar = 'a';
incrementCharAvoidingDuplicates(v, newChar);
v.push_back(newChar);
return true;
}
// otherwise we could not increment the final char, could not increment the base...so we are done
else
{
return false;
}
}
}
int main()
{
static const char arr[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','r','s','t','u','v','w','x','y','z'};
vector<char> originalAlphabet (arr, arr + sizeof(arr) / sizeof(arr[0]) );
vector<char> currentWord;
int desiredWordLength;
for(desiredWordLength = 1; desiredWordLength < 25; desiredWordLength++)
{
currentWord.clear();
//build first list e.g. a, abc, abcdef, ...
for(int j = 0; j < desiredWordLength; j++)
{
currentWord.push_back(originalAlphabet[j]);
}
do{
printVec(currentWord);
} while( incrementVec(currentWord));
}
return 0;
}