簡體   English   中英

如何在std :: string的兩個向量之間找到常用詞

[英]how to find common words between two vectors of std::string

我試圖在std :: string的2個向量之間找到常用詞。 我想將它們放入按長度排序的排序列表中,然后將每個長度的單詞按字母順序排序。 我需要使用STL函數和函子。

我的想法:使用for_each遍歷第一個向量,並使用函子將每個單詞與另一個向量進行比較(如果常見,請附加到函子列表中)。 這樣,結果列表中將僅包含常用詞。 這是我遇到的問題,我知道如何按字母順序排序,但是如何按長度對它們進行排序,然后按字母順序對相同長度的塊進行排序呢? 我環顧了Stl,但是找不到所需的東西。 或者,我只是在想這是錯誤的方式。 有任何想法嗎?

例:

vec1: “和”,“因此”,“它”,“有”,“一個”,“開始”,“和”,“結束”

vec2: “和”,“因此”,“星星”,“是”,“開始”,“到達”,“下降”,“到達”,“其”,“結束”

結果: “和”,“結束”,“開始”

如果允許對vec1vec2進行排序,則可以使用std::set_intersection根據指定的條件對向量進行排序,並獲得按相同條件排序的公共元素:

#include <algorithm>
#include <iterator>

std::sort(vec1.begin(), vec1.end(), funny_comp);
std::sort(vec2.begin(), vec2.end(), funny_comp);
std::list<std::string> intersection;

std::set_intersection(vec1.begin(), vec1.end(),
                      vec2.begin(), vec2.end(),
                      std::back_inserter(intersection),
                      funny_comp);

其中funny_comp按字符串長度進行比較,如果長度相同, funny_comp字典順序對字符串進行比較:

bool funny_comp(const std::string &lhs, const std::string &rhs)
{ 
   return (lhs.size()) == rhs.size()) ? lhs < rhs
                                      : lhs.size() < rhs.size();
}

在這里查看工作演示

如果對向量進行了排序,則可以使用std :: set_intersection()來找到每個詞的共同詞。 std :: set_intersection()是項目數量的O(N)時間。 當然是O(N log N)。

您的解決方案是O(n ^ 2)。 這意味着如果向量的長度為n,則您正在執行n * n運算:遍歷一個向量,對於每個元素,遍歷另一向量以尋找它。

如果可以對向量排序(使用sort功能。不需要像您提到的那樣進行奇特排序),則時間為O(n)。 使用set_intersection 即使您無法對它們進行排序-將它們復制到新的向量中並對這些新的向量進行排序。 比您所建議的要快得多。

要按長度排序,然后按詞法排序,您需要定義一個比較函數(或函子)來做到這一點:

struct by_len_lex { 
   bool operator()(std::string const &a, std::string const &b) { 
       if (a.length() < b.length())
           return true;
       if (a.length() > b.length())
           return false;
       return a < b;
    }
};

// ...
std::sort(strings1.begin(), strings1.end(), by_len_lex());
std::sort(strings2.begin(), strings2.end(), by_len_lex());

// find intersection:
std::set_intersection(strings1.begin(), strings1.end(), 
                      strings2.begin(), strings2.end(),
                      std::back_inserter(results),
                      by_len_lex());

請注意,由於要定義排序標准,因此在排序進行相交時都需要指定相同的條件。

這可能不是最佳解決方案,但可以使用如下所示的map:

#include <iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

int main()
{
vector <string> v1{"and", "thus", "it", "has", 
                  "a", "beginning", "and", "end"};

vector <string> v2{"and" ,"therefore", "stars", 
                   "are", "beginning", "to","fall","to",
                   "their", "end"};

map <string,int> m;

auto check=[&](const string& x) { return m.find(x) != m.end() ; } ;

for_each(v1.begin(),
         v1.end(),
         [&](const string& x){ 
                m[x] =1;
            } 
         );

for_each(v2.begin(),
         v2.end(),
         [&](const string& x){ 
            if(check(x)) 
                cout<<x<<endl;
            } 
         );

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM