ツリーを作成する:(トライ?)
このツリーの各ノードに、文字(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);
}