简体   繁体   English

在c中按字典顺序打印trie

[英]Printing a trie lexicographically in c

So I'm implementing a trie to store words in a dictionary file. 所以我正在实现一个特里将单词存储在字典文件中。 I've implemented the insert operation; 我已经实现了插入操作; now I'm trying to print lexicograpically. 现在,我正在尝试印刷。 I'm close to getting it, but I have a small problem that I'm not sure how to fix. 我快要解决了,但是我有一个小问题,我不确定如何解决。 I'm also trying to keep in mind the speed of my program, which is why I've opted for a trie over an array or a linked list. 我还试图牢记程序的速度,这就是为什么我选择重选数组或链接列表的原因。 Here is what a single node looks like: 这是单个节点的外观:

struct node {
  int end;
  int occurrences;
  int superwords;
  struct node* child[26];
};

"end" indicates the completion of a word (for example, end == 1 at letter 'k' in the word book; this prevents confusion in checking whether or not a word has actually been inserted in the tree). “ end”表示单词的完成(例如,单词本中字母“ k”的end == 1;这可防止在检查树中是否已实际插入单词时产生混淆)。

Here's the method: 方法如下:

void preorder(struct node *follow, char hold[200], int s){
  int i = 0;
  if(follow == NULL){
    return;
  }

  for(i = 0; i < 26; i++){
    if(follow->child[i] == NULL){
      continue;
    }
    else{
      printf("%c",'a'+i);
      hold[s] = 'a'+i;
      s++;
      if(follow->child[i]->end == 1){
        printf("\n");
        hold[s] = '\0';
        printf("%s", hold);
      }
      preorder(follow->child[i], hold, s);
    }
  }
  return;
}

The words I've inserted are: boo, book, booking, john, tex, text. 我插入的词是:嘘,书,预订,约翰,特克斯,文本。 They should be printed in that order and line separated. 它们应按该顺序打印并分隔行。 My output looks like: 我的输出看起来像:

boo
book
booking
bookingjohn
bjohntex
bjtext
bjtext

I know this probably has something to do with my "hold" array, which stores the prefixes of words so they don't get lost. 我知道这可能与我的“ hold”数组有关,该数组存储单词的前缀,这样它们就不会丢失。 I need to set the index back to zero somewhere to indicate the completion of a prefix and all its associated words (boo, book, booking being a good example) but haven't been successful. 我需要在某处将索引设置回零以指示前缀及其所有相关单词(例如boo,book,booking是一个很好的例子)的完成,但是还没有成功。 Any help would be much appreciated and I would be glad to further clarify my thought process. 任何帮助将不胜感激,我将很高兴进一步阐明我的思考过程。

You're very close. 你很亲密

There are two problems, both in the for loop which runs through the trie branches: 有两个问题,都存在于遍历trie分支的for循环中:

else{
  printf("%c",'a'+i);
  hold[s] = 'a'+i;
  s++;

First problem is that you are printing (almost) everything twice. 第一个问题是(几乎)所有内容都要打印两次。 In the above snippet, you print the prefix as you trace the tree. 在上面的代码段中,您在跟踪树时打印前缀。 Then later when you reach the end of the word, you print the entire word: 然后,当您到达单词的结尾时,您将打印整个单词:

  if(follow->child[i]->end == 1){
    printf("\n");
    hold[s] = '\0';
    printf("%s", hold);
  }

So there was no need to print the prefix at all, and the double printing is confusing. 因此根本不需要打印前缀,并且双重打印令人困惑。

Second, the s argument represents the depth in the tree, which is the length of the current prefix. 其次, s参数表示树中的深度,即当前前缀的长度。 So it should be constant during the exploration of a trie node. 因此在探索特里节点时它应该是恒定的。 But everytime you find a new branch, you increment it ( s++ in the first snippet above). 但是,每次找到新分支时,都将其递增(上面第一个代码段中的s++ )。 Instead of doing that, you need the recursive call to use s + 1 as its argument, so that it will be called with the correct prefix-length. 而不是这样做,您需要递归调用以使用s + 1作为其参数,以便将使用正确的前缀长度来调用它。

You can also simplify your control structures quite a bit. 您还可以相当简单地简化控制结构。

Here's an example: 这是一个例子:

void preorder(struct node *follow, char hold[200], int s){
  int i = 0;
  if(follow == NULL){
    return;
  }
  /* Print the word at the beginning instead of the end */
  if (follow->end) {
    hold[s] = 0;
    printf("%s\n", hold);
  }

  for(i = 0; i < 26; i++){
    /* preorder returns immediately if its argument is NULL, so
     * there's no need to check twice. Perhaps even better would be
     * to do the check here, and not do it at the beginning.
     */
    hold[s] = 'a'+i;
    preorder(follow->child[i], hold, s + 1);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM