| // build |
| |
| // Copyright 2025 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "iter" |
| ) |
| |
| type leafSet map[rune]struct{} |
| |
| type branchMap map[rune]*node |
| |
| func (bm branchMap) findOrCreateBranch(r rune) *node { |
| if _, ok := bm[r]; !ok { |
| bm[r] = newNode() |
| } |
| return bm[r] |
| } |
| |
| func (bm branchMap) allSuffixes() iter.Seq[string] { |
| return func(yield func(string) bool) { |
| for r, n := range bm { |
| for s := range n.allStrings() { |
| if !yield(string(r) + s) { |
| return |
| } |
| } |
| } |
| } |
| } |
| |
| type node struct { |
| leafSet |
| branchMap |
| } |
| |
| func newNode() *node { |
| return &node{make(leafSet), make(branchMap)} |
| } |
| |
| func (n *node) add(s []rune) { |
| switch len(s) { |
| case 0: |
| return |
| case 1: |
| n.leafSet[s[0]] = struct{}{} |
| default: |
| n.branchMap.findOrCreateBranch(s[0]).add(s[1:]) |
| } |
| } |
| |
| func (n *node) addString(s string) { |
| n.add([]rune(s)) |
| } |
| |
| func (n *node) allStrings() iter.Seq[string] { |
| return func(yield func(string) bool) { |
| for s := range n.leafSet { |
| if !yield(string(s)) { |
| return |
| } |
| } |
| for r, n := range n.branchMap { |
| for s := range n.allSuffixes() { |
| if !yield(string(r) + s) { |
| return |
| } |
| } |
| } |
| } |
| } |
| |
| func main() { |
| root := newNode() |
| for _, s := range []string{"foo", "bar", "baz", "a", "b", "c", "hello", "world"} { |
| root.addString(s) |
| } |
| for s := range root.allStrings() { |
| println(s) |
| } |
| } |