【问题标题】:Find similar string using similarity() function使用similarity() 函数查找相似的字符串
【发布时间】:2021-07-17 16:21:57
【问题描述】:

假设一个函数similarity() 接受两个字符串作为参数。如果两个字符串相似,则返回接近 1 的数字,否则返回接近 0 的数字。

到目前为止,我有一个二叉树,其中每个节点都包含一个字符串作为数据。我想创建一个函数,该函数将逐个节点浏览该树并返回相似度最高的单词。

尝试:

使用@AshutoshRaghuwanshi 的答案,我得到了

void Tree::traverse(Node* rootNode, float& score, std::string& bestMatch, std::string& word)
{
    if(rootNode == nullptr) return;
    if(similarity(rootNode->data, word)>score){
        score = similarity(rootNode->data, word);
        bestMatch = rootNode->data;
    }
    traverse(rootNode->left, score, bestMatch, word);
    traverse(rootNode->right, score, bestMatch, word);
}

std::string Tree::browseTree(const std::string& word) const{
    if(isEmpty()){
        throw std::invalid_argument("The tree is empty!");
    }

    Node * currentNode = root;
    float score=0;
    std::string bestMatch;

    traverse(currentNode->left, score, bestMatch, word);
    traverse(currentNode->right, score, bestMatch, word);

    if(score>.90){
        return bestMatch;
    }else{
        throw std::invalid_argument("Word not found");
    }
}

似乎效果不太好?我哪里错了?

【问题讨论】:

  • 提示,如果你的函数返回“banana”这个词的 0.4 和“bandana”这个词的 0.45,你如何决定哪一个是更好的匹配?写一行代码就可以做到这一点。
  • 现在是有趣的部分。假设banana 是左子树上的最佳选择,bandana 是右子树上的最佳选择,程序应该怎么做才能找到整体上的最佳选择?不用等,有人已经在答案中泄露了所有秘密......
  • 有一些错误,但没有什么是无法修复的。
  • 请详细说明“似乎效果不佳?”因为这是唯一决定正确解决方案的部分。

标签: c++ recursion binary-tree traversal


【解决方案1】:

树遍历永远不是线性的。你需要一个递归逻辑。一个简单的例子如下所示:

void Traverse(const std::string& word, Node* rootNode, float& score, std::string& bestMatch)
{
    if(rootNode == nullptr) return;
    if(similarity(rootNode->data, word)>score){
        score = similarity(rootNode->data, word);
        bestMatch = rootNode->data;
    }
    Traverse(word, rootNode->left, score, bestMatch);
    Traverse(word, rootNode->right, score, bestMatch);
}

然后在您的主代码中,将整个 while 循环替换为以下代码:

Traverse(word, root->left, score, bestMatch);
Traverse(word, root->right, score, bestMatch);

这应该可以解决您的问题。

【讨论】:

  • 你的函数什么也不返回。谢谢顺便说一句,我已经明白了一点。是void类型吗?
  • @notaprogrammertoday 是的,它是无效的,我更新了代码。
  • 我已经修改了我在问题中的尝试。你能告诉它是否很好。它似乎对我不起作用。顺便说一句,我认为这个词必须在 traversal() 的参数中
  • @notaprogrammertoday 是的,由于缺少 word 参数,它可能无法正常工作。正如我之前所说,我的目的是展示这个想法,而不是经过良好测试的实现。
【解决方案2】:
void Tree::traverse(Node* rootNode, float& score, std::string& bestMatch, std::string& word)
{
    if(rootNode == nullptr) return;
    float s = similarity(rootNode->data, word);
    if(s>score){
        score = s;
        bestMatch = rootNode->data;
    }   
    traverse(rootNode->left, score, bestMatch, word);
    traverse(rootNode->right, score, bestMatch, word);
}

std::string Tree::browseTree(const std::string& word) const{
    if(isEmpty()){
        throw std::invalid_argument("The tree is empty!");
    }

    Node * currentNode = root; //replace this line
    float score=0;
    std::string bestMatch;

    traverse(root, score, bestMatch, word);

    if(score>.90){
        return bestMatch;
    }else{
        throw std::invalid_argument("Word not found");
    }
}

这个 sn-p 代码很可能会起作用。请将注释中的行替换为二叉树的实际根节点。

【讨论】:

    猜你喜欢
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2016-11-02
    相关资源
    最近更新 更多