我试图找到两个std :: string向量之间的常用词。我希望将它们放入按长度排序的排序列表中,然后按字母顺序对每个长度的单词进行排序。我需要使用stl函数和函子。
我的想法: 使用for_each遍历第一个向量,对于每个单词,使用仿函数将其与另一个向量进行比较(如果常见,则附加到仿函数中的列表)。然后结果列表中只有常用的单词。这是我被卡住的地方,我知道如何按字母顺序排序,但我如何按长度排序,然后按字母顺序排序相同长度的块?我环顾四周,但我找不到我需要的东西。或者,我只是想错了方法。有什么想法吗?
示例:
vec1:“和”,“因此”,“它”,“有”,“一个”,“开头”,“和”,“结束”
vec2:“和”,因此“,”星星“,”是“,”开始“,”到“,”堕落“,”到“,”他们的“,”结束“
结果:“和”,“结束”,“开始”
答案 0 :(得分:3)
如果您允许对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
按字符串长度进行比较,如果字符串具有相同的长度,则执行字符串的字典比较:
bool funny_comp(const std::string &lhs, const std::string &rhs)
{
return (lhs.size()) == rhs.size()) ? lhs < rhs
: lhs.size() < rhs.size();
}
答案 1 :(得分:1)
如果向量已排序,您可以使用std :: set_intersection()来查找每个向量的共同词。 std :: set_intersection()是项目数量的O(N)时间。当然排序是O(N log N)。
答案 2 :(得分:1)
您的解决方案是O(n ^ 2)。这意味着如果向量的长度为n,则执行n * n次操作:遍历一个向量,对于每个元素,遍历另一个向量以查找它。
如果你可以对向量进行排序(使用sort
函数。不需要像你提到的那样花哨的排序),时间是O(n)。使用set_intersection
。即使您无法对它们进行排序 - 将它们复制到新的向量中并对这些新向量进行排序。它比你提出的要快得多。
答案 3 :(得分:1)
要按长度排序,那么在词汇上,你需要定义一个比较函数(或仿函数)来做到这一点:
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());
请注意,由于您要定义排序条件,因此在进行交叉时排序和时需要指定相同的条件。
答案 4 :(得分:0)
这可能不是最佳解决方案,但可以使用以下地图:
#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;
}
);
}