14 typedef std::pair<const std::string, Node> WordNode;
16 WordNode *down, *right, *up;
21 # error "`TREE' not defined or bungled constant setting"
24 typedef std::map<std::string, Node> Map;
25 #elif TREE == CXX_UOMAP
26 # include <unordered_map>
27 typedef std::unordered_map<std::string, Node> Map;
29 # error "unknown `TREE' value"
34 static void bail(const char *msg, ...)
39 va_start(ap, msg); std::vfprintf(stderr, msg, ap); va_end(ap);
40 pos = std::ftell(stdin);
41 if (pos >= 0) std::fprintf(stderr, " (input pos = %ld)", pos);
42 std::fputc('\n', stderr);
46 static void print_chain(WordNode *wnode)
48 const std::string *word = &wnode->first;
49 Node *node = &wnode->second;
52 std::fputs(word->c_str(), stdout);
54 { std::putchar(' '); print_chain(node->down); }
56 std::fputs("{ ", stdout);
58 std::fputs(word->c_str(), stdout);
60 { std::putchar(' '); print_chain(node->down); }
61 wnode = node->right; if (!wnode) break;
62 std::fputs(" | ", stdout);
63 word = &wnode->first; node = &wnode->second;
65 std::fputs(" }", stdout);
72 char buf[WORDMAX]; size_t n;
75 if (!std::fgets(buf, WORDMAX, stdin)) break;
76 n = std::strlen(buf); assert(n);
77 if (buf[n - 1] == '\n') buf[--n] = 0;
78 else if (n == WORDMAX - 1) bail("word too long");
81 if (ch = std::getchar(), ch != EOF)
82 bail("short read, found `%c'", ch);
85 auto r = map.insert(WordNode(std::string(buf, n), Node{}));
86 if (!r.second) printf(";; duplicate `%s'\n", buf);
88 Node *node = &r.first->second;
89 node->len = 1; node->up = node->down = node->right = 0;
93 WordNode *winners, **winners_tail = &winners;
96 for (auto p = map.begin(); p != map.end(); ++p) {
97 /* std::fprintf(stderr, ";; ponder `%.*s'\n",
98 p->first.length(), p->first.c_str()); */
99 WordNode *wnode = &*p, *pwnode;
100 const std::string *word = &wnode->first;
101 Node *node = &wnode->second;
102 if (word->length() <= 1)
105 /* std::fprintf(stderr, ";; search `%.*s'\n",
106 w->first.length(), w->first.c_str()); */
107 std::string prefix{*word, 0, word->length() - 1};
108 auto p = map.find(prefix); if (p == map.end()) continue;
111 int nlen = node->len;
117 { max = nlen; *winners_tail = 0; winners_tail = &winners; }
118 *winners_tail = wnode; winners_tail = &node->right;
122 Node *parent = &pwnode->second;
123 nlen++; int plen = parent->len;
126 else if (plen == nlen) {
127 node->right = parent->down; parent->down = wnode;
130 parent->down = wnode; node->right = 0;
132 wnode = pwnode; node = &wnode->second; pwnode = node->up;
138 for (WordNode *next, *wnode = winners; wnode; wnode = next) {
139 next = wnode->second.right; wnode->second.right = 0;
140 print_chain(wnode); std::putchar('\n');