SymSpellPlusPlus 中的分词
WordSegmentation in SymSpellPlusPlus
我想使用 SymSpell, which is called SymSpellPlusPlus 的 C++ 版本。在 C# 版本中使用 WordSegmentation 看起来像这样(从第一个 link 开始):
//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++版本方法WordSegmentationreturns共享指针(来自第二个link):
...
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)
跟内存错误有关,不知道怎么解决
Class WordSegmentationItem 看起来如下(第 292-325 行在第二个 link):
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 中获取 correctedString?
该库有问题,作者需要进行一些修复。
首先,编译给我们一个关于 SuggestItem::ShallowCopy
的警告,其中 return 是一个引用局部变量。很坏!我们可以按值将其更改为 return。
但这并不能解决崩溃问题。
如果我们克隆库的 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
函数中的 returning compositions[circularIndex]
导致 shared_ptr
构造函数中的无效访问。这表明 circularIndex
是 out-of-bounds 并给我们一个 non-existent shared_ptr
。事实上,circularIndex
是 95
但 compositions.size()
是 0
!
该函数缺少一些严重的错误检查。
现在,只有作者(或者至少知道库应该做什么的人;那不是我!)才能正确解决这个问题。但作为一个快速补丁,我在第 1055 行之后添加了以下内容:
if (compositions.empty())
return nullptr;
…现在至少 运行s.
似乎该函数假定字典是 non-empty。我不知道这是否是预期的行为(除了上面详述的缺失错误检查)。
该项目非常需要一些文档,因为没有提到这些函数的先决条件或后置条件,也没有说明应该如何使用该库。同样,作者应该修复这些问题。
我想使用 SymSpell, which is called SymSpellPlusPlus 的 C++ 版本。在 C# 版本中使用 WordSegmentation 看起来像这样(从第一个 link 开始):
//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++版本方法WordSegmentationreturns共享指针(来自第二个link):
...
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)
跟内存错误有关,不知道怎么解决
Class WordSegmentationItem 看起来如下(第 292-325 行在第二个 link):
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 中获取 correctedString?
该库有问题,作者需要进行一些修复。
首先,编译给我们一个关于 SuggestItem::ShallowCopy
的警告,其中 return 是一个引用局部变量。很坏!我们可以按值将其更改为 return。
但这并不能解决崩溃问题。
如果我们克隆库的 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
函数中的 returning compositions[circularIndex]
导致 shared_ptr
构造函数中的无效访问。这表明 circularIndex
是 out-of-bounds 并给我们一个 non-existent shared_ptr
。事实上,circularIndex
是 95
但 compositions.size()
是 0
!
该函数缺少一些严重的错误检查。
现在,只有作者(或者至少知道库应该做什么的人;那不是我!)才能正确解决这个问题。但作为一个快速补丁,我在第 1055 行之后添加了以下内容:
if (compositions.empty())
return nullptr;
…现在至少 运行s.
似乎该函数假定字典是 non-empty。我不知道这是否是预期的行为(除了上面详述的缺失错误检查)。
该项目非常需要一些文档,因为没有提到这些函数的先决条件或后置条件,也没有说明应该如何使用该库。同样,作者应该修复这些问题。