在字母{a,b,c}中查找长度为n的字符串数w

时间:2016-03-24 13:34:13

标签: c++ computation-theory alphabet

我正在试图弄清楚如何计算长度为n的所有字符串的数量,使得字符串w的长度为4的所有子字符串,所有三个字母a,b,c都出现。例如,当n = 9时应该打印abbcaabca,但不应包括aabbcabac。

我试图制作像

这样的数学公式
3^N - 3 * 2^N + 3 or (3^(N-3))*N!

它可以这样工作还是我必须生成它们并计算它们?我正在处理像100这样的大数字,我认为我不能生成它们来计算它们。

2 个答案:

答案 0 :(得分:0)

诀窍是解决问题。考虑:

知道有多少这样长度为50的字符串,以每对字母结尾,有帮助吗?

50个字符串的数量,以AA次结尾 50字符串的数字,以B或C开头 + 50个字符串的数量,以AB次结尾 50字符串的数字,以C开头 + 所有其他组合为您提供100长串的数量。

继续递归地分解它。

查找动态编程。

还要查找大量的库。

答案 1 :(得分:0)

你可能应该能够顺利完成,然后让我们说出长度为4的所有可能的单词,然后只添加一个字母并计算可能允许的结果单词。然后,您可以迭代地进入高数字,而无需探索所有3 ^ N种可能性。

const unsigned w = 4;
unsigned n = 10;

vector<string> before,current;

// obtain all possible permutations of the strings "aabc", "abbc" and "abcc"
string base = "aabc";
before.emplace_back(base);
while(std::next_permutation(base.begin(),base.end())) before.emplace_back(base);
base = "abbc";
before.emplace_back(base);
while(std::next_permutation(base.begin(),base.end())) before.emplace_back(base);
base = "abcc";
before.emplace_back(base);
while(std::next_permutation(base.begin(),base.end())) before.emplace_back(base);

// iteratively add single letters to the words in the collection and add if it is a valid word
size_t posa,posb,posc;
for (unsigned k=1;k<n-w;++k)
{
    current.clear();
    for (const auto& it : before)
    {
        posa = it.find("a",k);
        posb = it.find("b",k);
        posc = it.find("c",k);
        if (posb!= string::npos && posc!= string::npos) current.emplace_back(it+"a");
        if (posa!= string::npos && posc!= string::npos) current.emplace_back(it+"b");
        if (posa!= string::npos && posb!= string::npos) current.emplace_back(it+"c");
    }
    before = current;
}
for (const auto& it : current) cout<<it<<endl;
cout<<current.size()<<" valid words of length "<<n<<endl;

请注意,这样你仍然可以很快地进入指数墙......在一个更有效的实现中,我会将单词表示为整数(不是整数的向量,而是基数3表示中的整数),但是指数缩放仍然存在。如果您只是对这个数字感兴趣,@ Jeffrey的方法肯定会更好。