[英]how to find common words between two vectors of std::string
我試圖在std :: string的2個向量之間找到常用詞。 我想將它們放入按長度排序的排序列表中,然后將每個長度的單詞按字母順序排序。 我需要使用STL函數和函子。
我的想法:使用for_each遍歷第一個向量,並使用函子將每個單詞與另一個向量進行比較(如果常見,請附加到函子列表中)。 這樣,結果列表中將僅包含常用詞。 這是我遇到的問題,我知道如何按字母順序排序,但是如何按長度對它們進行排序,然后按字母順序對相同長度的塊進行排序呢? 我環顧了Stl,但是找不到所需的東西。 或者,我只是在想這是錯誤的方式。 有任何想法嗎?
例:
vec1: “和”,“因此”,“它”,“有”,“一個”,“開始”,“和”,“結束”
vec2: “和”,“因此”,“星星”,“是”,“開始”,“到達”,“下降”,“到達”,“其”,“結束”
結果: “和”,“結束”,“開始”
如果允許對vec1
和vec2
進行排序,則可以使用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.