C++ 如何在std::string的两个向量之间查找公共词
我试图在std::string的两个向量之间找到常用词。我想把它们放到一个按长度排序的列表中,然后每个长度的单词按字母顺序排序。我需要使用stl函数和函子 我的想法: 使用for_遍历第一个向量,对于每个单词,使用functor将其与另一个向量进行比较(如果通用,则附加到functor中的列表)。然后,生成的列表中只有常用词。这就是我被卡住的地方,我知道如何按字母顺序排序,但我如何按长度排序,然后按字母顺序排序相同长度的块?我已经环顾了stl,但我没有找到我需要的。或者,我只是想错了。有什么想法吗 例如: 因此,它有,开始,和结束 vec2:因此,星星是,开始、结束、坠落、结束C++ 如何在std::string的两个向量之间查找公共词,c++,stl,functor,C++,Stl,Functor,我试图在std::string的两个向量之间找到常用词。我想把它们放到一个按长度排序的列表中,然后每个长度的单词按字母顺序排序。我需要使用stl函数和函子 我的想法: 使用for_遍历第一个向量,对于每个单词,使用functor将其与另一个向量进行比较(如果通用,则附加到functor中的列表)。然后,生成的列表中只有常用词。这就是我被卡住的地方,我知道如何按字母顺序排序,但我如何按长度排序,然后按字母顺序排序相同长度的块?我已经环顾了stl,但我没有找到我需要的。或者,我只是想错了。有什么想法
结果:和、结束、开始如果向量已排序,则可以使用std::set_intersection查找每个向量的公用词。std::设置交叉点的项目数是否准时。当然,排序在日志N上。如果向量已排序,则可以使用std::set_intersection查找每个向量共有的单词。std::设置交叉点的项目数是否准时。当然,排序在日志N上。如果允许您对vec1和vec2进行排序,您可以使用来根据指定的标准对向量进行排序,并获得公共元素,按相同的标准排序:
#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);
请参阅。如果允许对vec1和vec2进行排序,则可以使用来根据指定的标准对向量进行排序,并获得按相同标准排序的公共元素:
#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);
请参阅。您的解决方案位于^2上。这意味着,如果向量的长度为n,那么您将执行n*n操作:遍历一个向量,对于每个元素,遍历另一个向量以查找它
如果可以使用sort函数对向量进行排序。不需要像你提到的那样花哨,时间到了。使用集合交叉。即使你不能对它们进行排序,也要将它们复制到新的向量中,并对这些新向量进行排序。它比您的建议快得多。您的解决方案在^2上。这意味着,如果向量的长度为n,那么您将执行n*n操作:遍历一个向量,对于每个元素,遍历另一个向量以查找它
如果可以使用sort函数对向量进行排序。不需要像你提到的那样花哨,时间到了。使用集合交叉。即使你不能对它们进行排序,也要将它们复制到新的向量中,并对这些新向量进行排序。它比您建议的要快得多。要按长度排序,然后按词汇进行排序,您需要定义一个比较函数或函子:
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());
请注意,由于您正在定义排序标准,因此在排序和进行交叉时都需要指定相同的标准。要按长度排序,然后按词汇进行排序,需要定义一个比较函数或函子:
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());
请注意,由于您正在定义排序标准,因此在排序和进行交叉时都需要指定相同的标准。这可能不是最佳解决方案,但可以使用如下映射:
#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;
}
);
}
这可能不是最好的解决方案,但可以使用如下映射:
#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;
}
);
}
你能先排序向量吗?是的,如果我创建一个eachI道歉的副本,我忘了提到我不能在结果向量中有重复的单词。你能先排序向量吗?是的,如果我创建一个eachI道歉的副本,我忘了提到我不能在结果向量中有重复的单词。是的,但是它创建了一堆重复项,所以我在你的算法中添加了std::unique,这样会不会更复杂?@MarinaGolubtsova:如果原始输入中有重复项,这将在输出中保留它们。如果你想消除它们,你可以使用std::unique来消除它们。这样做了,但它会创建一堆重复的sok,所以我在你的算法中添加了std::unique,这样会不会更复杂?@MarinaGolubtsova:如果你在原始输入中有重复的,这将在输出中保留它们。如果你想消除它们,你可以使用std::unique来消除它们。没有向量没有排序,但是ONlogN的复杂度仍然比我没有排序的好。没有向量没有排序,但是ONlogN的复杂度仍然比我的好。有没有避免重复的方法?@maringolubtsova除非我误解了你,这个解决方案会删除重复的。请看演示。有没有避免重复的方法?@MarinaGolubtsova除非我误解了你的意思,否则此解决方案会删除重复的内容。看演示。你说如果你能排序,时间是开着的,不是在日志n上排序吗?你说如果你能排序,时间是开着的,不是在日志n上排序吗?