【问题标题】:Program Crashing due to string in structure in Trie由于 Trie 结构中的字符串导致程序崩溃
【发布时间】:2016-06-25 05:57:50
【问题描述】:

我正在实现一个 trie,一旦到达单词结尾,它也会打印定义。我使用字符串进行定义。但是当我将定义分配给字符串时,代码会崩溃。

#include <bits/stdc++.h>
#define ALPHABET_SIZE 26
#define CHAR_TO_INDEX(c) ((int)c - (int)'0')
using namespace std;
typedef struct trienode{

string definition;          //For Definition of the word
bool isLeaf; 
struct trienode *children[ALPHABET_SIZE]; 

}node;
node* getnode()
{
    int i;
    node *t=new node();
    t->isLeaf=false;
    for(i=0;i<26;i++)
    {
        t->children[i]=NULL;
    }
    return t;
}
void insert(node *root,string s)
{
    node *crawler=root;
    int level,index,length=s.length();
    for(level=0;level<length;level++)
    {
        index=  CHAR_TO_INDEX(s[level]);
        if(crawler->children[index]==NULL)
        {
            crawler->children[index]=getnode();
        }
        crawler=crawler->children[index];
    }
    crawler->definition= "Definition of" + s;  //Here is the code crashing,when I am assigning the definition
    crawler->isLeaf=true;
}

【问题讨论】:

标签: c++ data-structures trie


【解决方案1】:

你的代码有很多问题。

我看到的越大,(我想)导致崩溃的问题在下面一行

#define CHAR_TO_INDEX(c) ((int)c - (int)'0')

CHAR_TO_INDEX() 宏旨在在 c 是表示数字的字符(从 09)时返回从 0 到 9 的索引值。

问题是当c 介于az 之间或(我想)在AZ 之间时,您使用它来获取0 到25 之间的数字。

例如:当cr 时,(int)'r' - (int)'0')114 - 48 = 66。因此,您尝试访问只有 26 个插槽的 children 的插槽 66。

要纠正这个问题,你可以用这种方式重写CHAR_TO_INDEX()

#define CHAR_TO_INDEX(c) (c - (int)'a')

并以这种方式调用它

index = CHAR_TO_INDEX( std::tolower( s[level] ) );

但是我认为使用宏是一个坏主意,所以我建议你定义一个简单的函数并进行一些检查;像这样的

int charToIndec (int ch)
 {
   if ( (ch < int(`a`)) || (ch > int(`z`)) )
    ; // throw something

   return ch - int(`a`);
 }

其他建议,不分先后……

您使用的是 C++,而不是 C;所以trienode不需要那个typedef;你可以简单地写

struct trienode {
   string definition; //For Definition of the word
   bool isLeaf; 
   trienode *children[ALPHABET_SIZE]; 
};

只需将结构用作trienode

再次重申:您使用的是 C++,而不是 C;所以我不明白你为什么要编写一个函数getnode(),它应该是(恕我直言)trienode 的构造函数;像

trienode () : definition(""), isLeaf(false)
 {
   for ( int i = 0 ; i < ALPHABET_SIZE ; ++i )
      children[i] = NULL;
 }

应该这样使用

crawler->children[index]= new trienode;

无论如何,您已将ALPHABET_SIZE 定义为26;记得在任何地方都使用它而不是 26(当 26 是 children 的维度时);所以用ALPHABET_SIZE替换getnode()中的26

包括; bits/stdc++.h 是什么?不知道,我什至不知道它是否是 C++ 标准包含。建议:使用标准包括。

最后一个建议:你使用new 作为节点;记得delete分配的节点;如果您可以使用 C++11 编译器,请考虑使用 std::unique_ptr 的假设来避免这种需要。

ps:对不起,我的英语不好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多