在C ++中查找数字树(trie)中最长的单词

时间:2015-02-10 23:18:14

标签: c++ search tree trie

对于作业,我必须制作两种方法,一种打印出一个存储几个单词的数字树,并在实际单词旁边标记*。另一种方法应该是找到这个数字树中最长的单词。这是定义的类(使用我完成的打印方法):

class DTN {
  public:
    DTN () :
      is_word(false), word_to_here(""), children()
    {}
    DTN (bool iw, std::string wth) :
      is_word(iw), word_to_here(wth), children()
    {}

    bool                     is_word;
    std::string              word_to_here;
    ics::ArrayMap<char,DTN>  children;
};


//Add a word correctly into a Digital Tree (of strings)
void add_a_word (DTN& dtn, std::string prefix, std::string postfix) {
  if (postfix.size() == 0) {
    dtn.is_word = true;
    return;
  } else {
    char first = postfix[0];
    if (!dtn.children.has_key(first))
      dtn.children[first] = DTN(false,prefix+first);
    return add_a_word(dtn.children[first],prefix+first,postfix.substr(1));
  }
}


//Print dtn, its n children indenter, their n children indented....
void print_DTN_tree(const DTN& dtn, std::string indent) {
  std::cout << indent << dtn.word_to_here  << (dtn.is_word? "*" : "") << std:: endl;
  for (auto n : dtn.children)
    print_DTN_tree(n.second, indent+"  ");
}


bool is_a_word (const DTN& dtn, std::string remaining_letters) {
  if (remaining_letters.empty())
    return dtn.is_word;          //all letters in tree; is it a word?
  else if (dtn.children.has_key(remaining_letters[0]) == false)
    return false;                 //some letters not in truee: it isn't a word
  else
    return is_a_word(dtn.children[remaining_letters[0]], //check the next letter
                     remaining_letters.substr(1));
  }


void add_a_word (DTN& dtn, std::string word) {
  add_a_word(dtn,"",word);
} 

std::string longest_word (const DTN& dtn) {
// add this method
}

我得到了打印方法,可以使用迭代和递归的混合,并且认为找到最长的单词是相似的,这意味着我需要做的就是迭代我的树,调用一个函数来检查是否它是一个单词,如果是,则将它与当前最长的单词进行比较,但是当它找到最长的单词时,它不会自动返回,并继续前进到下一个单词。我应该如何解决这个问题,(或者甚至是关于如何解决这个问题的一般想法,我会赞赏这个课程),以及我目前的实施情况?

1 个答案:

答案 0 :(得分:1)

有几种方法可以实现这一点,这里最简单(但效率最低):

DTN *best_match=nullptr;

find_longest(root_dtn_node, &best_match);

if (best_match != nullptr)
{
    // ... That's the longest word here
}

// ================================================================

void find_longest(DTN &node, DTN **best_match)
{
      if (
          // Check if the node is a word. If so, then if *best_match
          // is null, or if that word is shorter than the word represent
      )
      {
            *best_match= &node;
      }

      // Now, recurse to all child nodes
}

我认为你可以弄清楚如何填写标有评论的地方。当递归unwinds并且find_longest返回时,非NULL best_match将指向具有最长单词的节点。

由您决定当有两个或多个具有相同,最长篇幅的单词时会发生什么。

另一条评论。考虑采用迭代树的代码并将其放入模板函数中,由lambda类进行参数化,模板类迭代整个树,并为表示单词的每个节点调用lambda。这样就可以避免重复执行打印树的现有函数与此函数之间递归的代码。