【问题标题】:WordSegmentation in SymSpellPlusPlusSymSpellPlusPlus 中的分词
【发布时间】:2019-10-17 02:18:34
【问题描述】:

我想使用SymSpell 的C++ 版本,称为SymSpellPlusPlus。在使用 WordSegmentation 的 C# 版本中(来自第一个链接):

//word segmentation and correction for multi-word input strings with/without spaces
inputTerm="thequickbrownfoxjumpsoverthelazydog";
maxEditDistance = 0;
suggestion = symSpell.WordSegmentation(input);

//display term and edit distance
Console.WriteLine(suggestion.correctedString + " " + suggestion.distanceSum.ToString("N0"));

在 C++ 版本方法中 WordSegmentation 返回共享指针(来自第二个链接):

     ...
     shared_ptr<WordSegmentationItem> WordSegmentation(const char* input)
        {
            return WordSegmentation(input, this->maxDictionaryEditDistance, this->maxDictionaryWordLength);
        }

     shared_ptr<WordSegmentationItem> WordSegmentation(const char* input, size_t maxEditDistance)
        {
            return WordSegmentation(input, maxEditDistance, this->maxDictionaryWordLength);
        }

     shared_ptr<WordSegmentationItem> WordSegmentation(const char* input, size_t maxEditDistance, size_t maxSegmentationWordLength)
        {
          // lines 1039 - 1179 under second link
          std::vector<shared_ptr<WordSegmentationItem>> compositions;
          ...
          return compositions[circularIndex];
        }

在我的代码中,我尝试了以下代码:

const char* inputTerm = "whereis th elove hehad dated forImuch of thepast who couqdn'tread in sixtgrade and ins pired him";
auto suggestions = symSpell.WordSegmentation(inputTerm);

但它给出了一个错误:

free() invalid next size (fast)

这与内存错误有关,但我不知道如何克服这个问题。
WordSegmentationItem 类如下所示(第二个链接中的第 292-325 行):

class WordSegmentationItem
    {
    public:
        const char* segmentedString{ nullptr };
        const char* correctedString{ nullptr };
        u_int8_t distanceSum = 0;
        double probabilityLogSum = 0;

        WordSegmentationItem() { }
        WordSegmentationItem(const symspell::WordSegmentationItem & p)
        {
            this->segmentedString = p.segmentedString;
            this->correctedString = p.correctedString;
            this->distanceSum = p.distanceSum;
            this->probabilityLogSum = p.probabilityLogSum;
        }

        WordSegmentationItem& operator=(const WordSegmentationItem&) { return *this; }
        WordSegmentationItem& operator=(WordSegmentationItem&&) { return *this; }

        void set(const char* pSegmentedString, const char* pCorrectedString, u_int8_t pDistanceSum, double pProbabilityLogSum)
        {
            this->segmentedString = pSegmentedString;
            this->correctedString = pCorrectedString;
            this->distanceSum = pDistanceSum;
            this->probabilityLogSum = pProbabilityLogSum;
        }

        ~WordSegmentationItem()
        {
            delete[] segmentedString;
            delete[] correctedString;
        }
};

我应该如何从 WordSegmentationItem 中获取正确的字符串?

【问题讨论】:

  • 似乎这是给图书馆作者的问题/错误报告。
  • ((猜this是你!))
  • 不是我 :)
  • 同样的输入字符串,同样的问题,同样的问题,同样的一天!嗯

标签: c++ pointers spell-checking


【解决方案1】:

库有问题,作者需要做一些修复。

首先,编译给我们一个关于SuggestItem::ShallowCopy 的警告,它通过引用返回一个局部变量。很坏!我们可以将其更改为按值返回。

不过,这并不能解决崩溃问题。

如果我们克隆库的 repo,然后在调试器中运行以下测试用例:

#include "symspell6.h"

int main()
{
    const char* inputTerm = "whereis th elove hehad dated forlmuch of thepast who couqdn'tread in sixtgrade and ins pired him";

    symspell::SymSpell symSpell;
    auto suggestions = symSpell.WordSegmentation(inputTerm);
}

...我们看到从WordSegmentation 函数返回compositions[circularIndex] 导致shared_ptr 构造函数中的访问无效。这表明circularIndex 越界并且给我们一个不存在的shared_ptr。事实上,circularIndex 是 95 但 compositions.size() 是 0!

该函数缺少一些严重的错误检查。

现在,只有作者(或至少知道图书馆应该做什么的人;那不是我!)才能正确解决这个问题。但作为一个快速补丁,我在第 1055 行之后添加了以下内容:

if (compositions.empty())
   return nullptr;

……它现在至少可以运行了。

该函数似乎假定字典是非空的。我不知道这是否是预期的行为(除了上面详述的缺失错误检查)。

该项目非常需要一些文档,因为没有提到这些函数的前置条件或后置条件,也没有说明应该如何使用该库。同样,作者应该解决这些问题。

【讨论】:

  • 我在 github 上提出了一个问题,用于悬空参考。
猜你喜欢
  • 1970-01-01
  • 2017-01-19
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多