在C ++中选择数据结构

时间:2015-12-11 05:08:19

标签: c++ algorithm c++11 dictionary tree

回答,谢谢!

请标记NAQ

2 个答案:

答案 0 :(得分:1)

也许你可以对在押韵期间匹配的语素进行分组,并且不是语素的向量,而是相关组的向量。然后,您可以对字典进行一次排序,并获得对数搜索时间。

在查看rhymingSyllables实现之后,似乎您将单词转换为声音,然后将任何元音相互匹配,并且仅在它们相同时匹配其他声音。因此,应用上面的建议,你可以引入额外的辅助声音'anyVowel',然后在字典构建过程中将每个单词转换为声音,用'anyVowel'替换所有元音并将该表示推送到字典。完成字典排序后。当你想要搜索一个单词的押韵时 - 将它转换为相同的表示并在字典上进行二进制搜索,首先是最后一个声音作为键,然后是之前的等等。这将给你m * log(n)最坏情况的复杂性,其中n是字典大小,m是字长,但通常它会更快地终止。

你也可以利用这样一个事实,即为了最好的押韵,你只考虑某些音节数字,并为每个音节数保持一个单独的字典。然后你计算你看起来押韵的单词中的音节数,并在适当的字典中搜索。渐近它并没有给你带来任何好处,但它提供的加速可能对你的应用有用。

答案 1 :(得分:1)

我一直在考虑这个问题,我可能会提出一种算法方法。

我可能会先把字典分成多个桶或批次。每个批次代表每个单词所具有的音节数。当遍历一个大的字符串向量时,遍历存储到不同桶中的向量应该是线性的。从这里开始,因为第一个桶将包​​含1个音节的所有单词,所以此刻无需做任何事情,因此您可以跳到第二个桶,每个桶后需要取每个单词并分开每个单词的音节。所以,如果你说25个桶,你知道前几个,最后几个不会持有很多单词,他们的时间不应该是重要的,应该先做,但是中间的桶说3长度为-5或3-6的音节将是最大的,如果它们的大小超过一定量并且它们并行运行,则可以在单独的线程上运行这些桶中的每一个。一旦你完成了;每个存储桶应返回std::vector<std::shared_ptr<Word>>,其结构可能如下所示:

 enum SpeechSound {
     SS_AA,
     SS_AE,
     SS_...

     SS_ZH
 };

 enum SpeechSoundType {
     ASPIRATE,
     ...
     VOWEL
 };

 struct SyllableMorpheme  {
     SpeechSound sound;
     SpeechSoundType type;         
 };

 class Word {
 public:

 private:
     std::string m_strWord;

     // These Two Containers Should Match In Size! One String For Each
     // Syllable & One Matching Struct From Above Containing Two Enums.
     std::vector<std::string> m_vSyllables
     std::vector<SyllableMorpheme> m_vMorphemes;

 public:
     explicit Word( const std::string& word );

     std::string getWord() const;

     std::string getSyllable( unsigned index ) const;
     unsigned getSyllableCount() const;

     SyllableMorpheme getMorhpeme( unsigned index ) const;

     bool operator==( const ClassObj& other ) const;
     bool operator!=( const ClassObj& other ) const;

 private:
     Word( const Word& c ); // Not Implemented
     Word& operator=( const Word& other ) const; // Not Implemented
 };

这次你将拥有这些类对象的新桶或共享指针向量。然后,您可以轻松编写一个函数来遍历每个存储桶甚至多个存储桶,因为存储桶只具有相同的签名,只有不同数量的音节。记得;每个桶应该已经按字母顺序排序,因为我们只是按音节计数添加它们,并且从未改变从字典中读入的顺序。

然后使用此功能,您可以在检查“匹配音节和语素”时轻松比较两个单词是否相等。这些都包含在std::vector<std::shared_ptr<Word>>中。因此,您也不必担心内存清理。

我们的想法是尽可能使用线性搜索,分离和比较;但是如果你的容器太大,那么创建存储桶并在多个线程中并行运行,或者如果它能满足你的需要,可以使用哈希表。

此类结构的另一种可能性是,如果您想要或需要更多,例如另一个std :: vector用于其定义,您甚至可以添加更多内容,而另一个std::vector<string>用于其部分语句{名词,动词等。}你甚至可以在其他vector<string>中添加同音词,同音词甚至vector<string>之类的内容,以获得与之押韵的所有单词的列表。

现在,为了您找到最佳匹配押韵的具体任务,您可能会发现某些单词最终可能会被列为单词列表,这些单词将被视为最佳匹配或合适!因此,你不想存储或返回一个字符串,而是一个字符串向量!

案例:

To Too Two Blue Blew Hue Hew Knew New,  
Bare Bear Care Air Ayre Heir Fair Fare There Their They're
Plain, Plane, Rain, Reign, Main, Mane, Maine

是的,这些都是单音节押韵的单词,但正如你所看到的,有很多情况下有多个有效的答案,而不仅仅是一个单一的最佳案例匹配。这是需要考虑的事情。