我想打印出长度为n
的所有可能的单词(生成用于测试其他算法的输入),其中包含'a'
到'a' + n
的(可能是重复的)字母。
我尝试执行以下操作:
#include <iostream>
#include <string>
#include <algorithm>
using size_type = std::size_t;
using symbol_type = std::string;
using char_type = typename symbol_type::value_type;
template< size_type n >
struct test
{
static_assert(!(size_type('z' - 'a') + 1 < n));
void
print(symbol_type const & _symbol) const
{
for (size_type i = 0; i < n; ++i) {
std::cout << _symbol.substr(i * n, n) << std::endl;
}
std::cout << std::endl;
}
bool
operator () () const
{
symbol_type mishmash_;
for (size_type i = 0; i < n; ++i) {
mishmash_.append(symbol_type(n, char_type('a' + i)));
}
print(mishmash_);
while (std::next_permutation(std::begin(mishmash_), std::end(mishmash_))) {
print(mishmash_);
}
return true;
}
};
int
main()
{
test< 3 > const test_{};
if (test_()) {
std::cout << "Succes!" << std::endl;
return EXIT_SUCCESS;
} else {
std::cerr << "Failure!" << std::endl;
return EXIT_FAILURE;
}
}
但是有重复的单词。如何以最佳方式实现所需?
答案 0 :(得分:1)
它在概念上与将数字从0000000 ...(n次)迭代到999999完全相同... - 只进行基数n转换:即增加一个数字,每次你想要下一个“值”,使用% n + 'a'
提取“数字”和/= n
以准备下一个......
答案 1 :(得分:1)
您可以编写测试类,如下所示。
struct test
{
//static_assert(!(size_type('z' - 'a') + 1 < n));
void
print(symbol_type const & _symbol) const
{
std::cout << _symbol << std::endl;
}
bool
operator () () const
{
symbol_type mishmash_(n, char_type('a' - 1));
int cidx = 0;
while (cidx >= 0) {
if(cidx == n) {
print(mishmash_);
--cidx;
} else {
if(++mishmash_[cidx] == char_type('a' + n)) --cidx;
else mishmash_[++cidx] = char_type('a' - 1);
}
}
return true;
}
};
答案 2 :(得分:0)
以下可能会有所帮助:
template <typename T>
bool increase(const std::vector<T>& v, std::vector<std::size_t>& its)
{
for (std::size_t i = 0, size = its.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++its[index];
if (its[index] == v.size()) {
its[index] = 0;
} else {
return true;
}
}
return false;
}
template <typename T>
void do_job(const std::vector<T>& v, std::vector<std::size_t>& its)
{
// Print example.
for (std::size_t i = 0, size = v.size(); i != size; ++i) {
std::cout << v[its[i]] << " ";
}
std::cout << std::endl;
}
template <std::size_t N>
void test()
{
std::vector<char> v(N);
std::iota(v.begin(), v.end(), 'a');
std::vector<std::size_t> its(N, 0);
do {
do_job(v, its);
} while (increase(v, its));
}