我正在学习C ++并做一些在线挑战。然而,似乎大多数“正常”的挑战我总是被困住。我不确定我是缺乏知识,还是只是过度思考。无论如何,如果有人能帮助我,我将不胜感激。
我正在尝试做这个挑战: 我的输入是一个数字“N”,然后我将不得不输入“N”字符串。
然后我必须找到每个字符串typen的最小数量的前缀,并确保它们不会重复。
例如,字符串“stackoverflow”有许多前缀:s,st,sta,stac,stack,stacko,stackov,stackove,stackover,stackoverf,stackoverfl,stackoverflo,stackoverflow。
所有这些都是stackoverflow的前缀。所以,如果我们有另一个字符串“standup”,我们必须键入stackoverflow - stac,因为已经有sta in standup,所以它将是stan for standup。
提前致谢。
答案 0 :(得分:1)
我能想到的最简单的版本;
按字母顺序对单词列表进行排序。将第二个到最后一个单词的副本附加到列表中。
对于列表中的每个单词,其唯一前缀是与列表中的下一个单词相比使其唯一的字母数。
示例,stackoverflow
,standup
,seer
。
列表变为;
seer
stackoverflow
standup
stackoverflow
seer only requires `se` to be unique as compared to `stackoverflow`.
stackoverflow requires `stac` to be unique as compared to `standup`.
standup requires `stan` to be unique as compared to `stackoverflow`.
完成。
答案 1 :(得分:0)
创建一个树:(trie?)
让此树中的每个节点最多包含26个子节点,每个字母对应一个字母(a-z)。
从root到leaf的路径表示字符串。
root
\
s
|
t
|
a
/\
c n
/ |
k d
| |
o u
...
只需将所有项目添加到此树中即可。
然后,只要您获得一个在其子树中只有1个叶子的节点(您可以跟踪这些计数),就可以使用深度优先搜索来处理树,到目前为止打印该字符串并递归。因此,在c
和n
,只有一个叶子,因此您分别打印stac
和stan
。
我不会说上面的方法特别适合更大的C ++程序员,但是这里有一些代码可以工作:(原谅C和C ++的灾难性混合以及下面的各种其他暴行,这只是一种超级快速的方法)
(link)
#include <string>
#include <iostream>
using namespace std;
class Node
{
public:
int count;
Node *(children[26]); // array of pointers
Node() { count = 0; for (int i = 0; i < 26; i++) children[i] = NULL; };
};
void add(char *s, Node &n)
{
if (*s == 0) // null-terminator
return;
if (n.children[*s-'a'] == NULL)
n.children[*s-'a'] = new Node();
n.count++;
add(s+1, *n.children[*s-'a']);
}
void print(char *start, char *end, Node &n)
{
if (n.count == 1)
{
*end = 0; // null-terminator
cout << start << endl;
return;
}
for (int i = 0; i < 26; i++)
{
if (n.children[i] != NULL)
{
*end = (char)(i+'a');
print(start, end+1, *n.children[i]);
}
}
}
int main()
{
char *s = "stackoverflow";
Node root;
add(s, root);
s = "standup";
add(s, root);
char output[1000]; // big buffer
print(output, output, root);
}