这是我被问到的一个面试问题。我的答案如下,但我想知道是否有更有效的方法。可能是组合类型函数,还是穷举生成+计数的唯一方法?
规则: 给定一个字符,下一个字符可以是任何一个字符 你可以制作多少个N个字符组合? 例如
a - > I,E
e - > I,O
i - > A,E,邻
u - > A,E,I,O
o - > I,U,邻
对于N = 1个可能的字符串组合 a,e,i,o,u
对于N = 2个可能的字符串组合 [ai,ae],[ei,eo],[ia,ie,io],[ua,ue,ui,uo],[oi,ou,oo]
等等。
我通过构建树然后计算叶子来解决它
struct Node {
Node(char v) : v_(v) {}
void add_child(shared_ptr<Node> n) { children.emplace_back(n); }
char v_ = 0;
vector<shared_ptr<Node>> children;
};
void add_child(shared_ptr<Node> root, int n, int depth, const map<char, vector<char>> &combo) {
if (depth == n) return;
auto ch = root->v_;
auto it = combo.find(ch);
for (auto ch : it->second) {
//printf("Adding to %c to %c\n", ch, root->v_);
root->add_child(make_shared<Node>(ch));
}
++depth;
for (auto &child : root->children) { add_child(child, n, depth, combo); }
}
int count_leaf(shared_ptr<Node> root) {
if (root->children.size() == 0) return 0;
int sum = 0;
for (auto &child : root->children) sum += count_leaf(child);
return sum > 0 ? sum : root->children.size();
}
void password_combination() {
// Find combos until this depth
int n = 3;
map<char, vector<char>> combo;
combo.insert(make_pair('a', vector<char>{'i', 'e'}));
combo.insert(make_pair('e', vector<char>{'i', 'o'}));
combo.insert(make_pair('i', vector<char>{'a', 'e', 'o'}));
combo.insert(make_pair('u', vector<char>{'a', 'e', 'i', 'o'}));
combo.insert(make_pair('o', vector<char>{'i', 'u', 'o'}));
// Create a N depth tree and count leaves
// Count all children until n = 3;
auto root = make_shared<Node>(0);
int depth = 0;
for (auto &c : combo) { root->add_child(make_shared<Node>(c.first)); }
for (auto child : root->children) { add_child(child, n, depth, combo); }
printf("%d\n", count_leaf(root));
}
有没有更好的方法。对代码/错误的批判,以及如果有一个c ++ 14惯用的方法,甚至更好。