ツリーを作成する:(トライ?)
このツリーの各ノードに、文字(az)ごとに1つずつ、最大26の子があるとします。
ルートからリーフへのパスは文字列を示します。
root
\
s
|
t
|
a
/\
c n
/ |
k d
| |
o u
...
このツリーにすべてのアイテムを追加するだけです。
次に、深さ優先探索でツリーを処理します。サブツリーにリーフが1つしかないノードを取得するたびに(これらのカウントを追跡できます)、その文字列をこれまでに印刷して繰り返します。つまり、c
とn
は葉が1つしかないので、それぞれとを印刷stac
しstan
ます。
上記のアプローチが大規模なC++プログラマーに特に適しているとは言えませんが、機能するコードを次に示します(CとC ++の悲惨な組み合わせと、以下のさまざまな残虐行為を許してください。これは非常に高速です。 -そして汚いアプローチ)
(リンク)
#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);
}