我循环遍历std :: vector和std :: string数组以查找向量中的匹配项。
示例:
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::cout << "Searching...\n";
std::vector<std::string> myVector;
myVector.push_back("Word");
myVector.push_back("Word2");
myVector.push_back("Word4");
myVector.push_back("Word6");
myVector.push_back("Word7");
std::string myStringArr[] =
{
"Word",
"Word1",
"Word2",
"Word3",
"Word4",
"Word5",
"Word6",
"Word7"
};
for (auto Vec : myVector)
{
for(auto Str : myStringArr)
{
if(Vec == Str)
{
std::cout << "Found: " << Vec << std::endl;
}
}
}
std::cin.ignore(2);
return 0;
}
这很好用。但我来自C语言(试图进入C ++ 11),并不确定这是否是最佳解决方案。
平台是windows,我不会(当前)使用像boost这样的外部库,正如你可以从代码中看到的那样。
是否有更好/更清洁的方法来达到相同的效果?
答案 0 :(得分:1)
只要矢量和字符串数组不太长,您的解决方案就可以正常工作并且很好
对代码的改进很小:不要将auto
用于简单类型,它的可读性较差(您可以使用const string&
代替)。
你可以做更高效的事情:你的算法复杂度是O(NxM),N和M是矢量和数组的大小。
将向量的值存储在hash_set中,然后检查它们是否在数组中将是O(N + M)。
答案 1 :(得分:1)
如果您的数组和向量已排序,则可以使用std::set_intersection
。
根据cplusplus.com,复杂性为Up to linear in 2*(count1+count2)-1 (where countX is the distance between firstX and lastX): Compares and assigns elements.
如果不是,您可以先对它们进行排序,只需O(nlog(n) + mlog(m))
(n
为向量中的元素数,m
为数组(反之亦然))时间,在线性范围之前(这比你的O(n*m)
解决方案更好)。
这是它的样子:
#include <iostream> // std::cout
#include <algorithm> // std::set_intersection, std::sort
#include <vector> // std::vector
std::vector<std::string> intersection(myVector.size()); //needs to be allocated
std::sort (myVector.begin(),myVector.end());
std::sort (myStringArr,myStringArr+10);
auto it = std::set_intersection (myVector.begin(), myVector.end(), //first range
myStringArr, myStringArr+10, // second range
intersection.begin()); // the result range
v.resize(it-v.begin());
std::cout << "The intersection has " << (v.size()) << " elements:\n";
答案 2 :(得分:0)
是的,您可以使用std::find_first_of
:
auto itVec = myVector.begin();
for (;;) {
itVec = std::find_first_of(itVec, myVector.end(), std::begin(myStringArr), std::end(myStringArr);
if (itVec == myVector.end())
break;
std::cout << "Found: " << *itVec << '\n';
++itVec;
}
答案 3 :(得分:0)
因为在一般情况下,矢量和数组都没有排序,所以你必须迭代每个元素。因此,这是最好的方式。
只有一件小事。 for (auto Vec : myVector)
将复制每个元素。由于std::string
制作浅层副本,因此您不会注意到。但在其他一些情况下,它可能是显而易见的。更好的方法是使用引用:
for (const auto& Vec : myVector)
答案 4 :(得分:0)
使用std::find_first_of
:
for (auto str : myStringArr)
{
if (std::find_first_of(str, std::begin(myVector). std::end(myVector))
{
std::cout << "Found: " << str << std::endl;
}
}
答案 5 :(得分:0)
您可以使用std :: set来存储字符串:
std::set<std::string> myStringSet
{
"Word",
"Word1",
"Word2",
"Word3",
"Word4",
"Word5",
"Word6",
"Word7"
};
for (auto Vec : myVector)
{
if( myStringSet.count( Vec ) )
{
std::cout << "Found: " << Vec << std::endl;
}
}
}
另一种解决方案是对矢量进行排序并使用std :: binary_search:
std::vector<std::string> myStringArr
{
"Word",
"Word1",
"Word2",
"Word3",
"Word4",
"Word5",
"Word6",
"Word7"
};
std::sort( myStringArr.begin(), myStringArr.end() );
for (auto Vec : myVector)
{
if( std::binary_search( myStringArr.begin(), myStringArr.end(), Vec ) {
std::cout << "Found: " << Vec << std::endl;
}
}
答案 6 :(得分:0)
std::set_intersection
算法可以满足您的需求。
使用std::sort
(或使用sorted data structures)对您的两个数据结构进行排序:
std::sort(myVector.begin(), myVector.end());
std::sort(myStringArr, myStringArr + 8);
然后使用std::set_intersection
:
std::set_intersection(
myVector.begin(), myVector.end(),
myStringArr, myStringArr + 8,
std::ostream_iterator<std::string>(std::cout, "\n"));
请注意使用std::ostream_iterator
在std::cout
上打印结果。