给出一个字符串向量:
std::vector<std::string> contents {"right", "sun is shining", "high hopes", "I wish you were here", "shining", "do it right"};
我想删除所有属于其他子字符串的元素。在此示例中,“ right”和“ shining”是要删除的。
我正在遍历向量和每个元素,进行另一个循环以检查是否有包含它的其他元素。 请参阅下面的实际代码。
我想知道是否有更好的方法。 (使用stl算法?)
std::vector<std::string> contents{"right", "sun is shining",
"high hopes", "I wish you were here", "shining", "do it right"};
std::vector<std::string> result;
for (size_t i = 0, j = 0; i < contents.size(); ++i)
{
for (j = 0; j < contents.size(); ++j)
{
if (i != j && boost::algorithm::contains(contents[j], contents[i]))
{
std::cout << "[" << contents[i] << "] contained in [" << contents[j] << "]" <<std::endl;
break;
}
}
if (j == contents.size())
{
std::cout << "[" << contents[i] << "] not contained in any element" << std::endl;
result.push_back(contents[i]);
}
}
预期结果将是: {“阳光明媚”,“充满希望”,“我希望你在这里”,“做对了”};
答案 0 :(得分:0)
嗯。好还是不好。
我认为您的解决方案可以。为什么您使用升压,我不明白。这里不需要。这项任务很简单。
共性始终为n * n(不完全。我们不将字符串与istself进行比较)
我准备了3种选择。
版本1正在使用std::algorithm
。
没人会理解它,它看起来像是混淆的代码。
版本2与版本1完全相同。我刚刚添加了许多换行符和注释。人们可以从中学到东西,并且可能会理解。但实际上,这里也有很多声明。
我认为第3版是最合理的方法。与您相似。仅使用基于的范围。而且没有助力。简单的C ++语句。
请参阅:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
void version1()
{
// Source data
std::vector<std::string> contents{ "right", "sun is shining", "high hopes", "I wish you were here", "shining", "do it right" };
// print filtered data to std::out
std::copy_if(contents.begin(), contents.end(), std::ostream_iterator<std::string>(std::cout, "\n"),
[&contents](std::string & s1) { return std::find_if(contents.begin(), contents.end(), [&s1](std::string & s2) {
return (s1 != s2) && (s2.find(s1) != std::string::npos); }) == contents.end(); });
}
void version2()
{
// Source data
std::vector<std::string> contents{ "right", "sun is shining", "high hopes", "I wish you were here", "shining", "do it right" };
// Copy data to standard out only if
std::copy_if
(
contents.begin(), // Evaluate from the begin of the source string
contents.end(), // To the end of the source string
std::ostream_iterator<std::string>(std::cout, "\n"), // Display found results on console
[&contents](std::string & s1) // The lambda to decide, if we will copy or not
{
return std::find_if // We will copy only, if we do not find a substring
(
contents.begin(), // We compare verything with everything
contents.end(), // Every word, from the source string with every other word
[&s1](std::string & s2)
{
return (s1 != s2) && // But not the same string with itself
(s2.find(s1) != std::string::npos); // Check, if it is a substring
}
) == contents.end(); // If we cannot find a substring, then we copy the data to the output
}
);
}
void version3()
{
// Source data
std::vector<std::string> contents{ "right", "sun is shining", "high hopes", "I wish you were here", "shining", "do it right" };
// Iterate over all strings in source vector
for (const std::string& s1 : contents) {
// Initially we have not found a substring
bool subStringFound{ false };
// Now compare every string in vector with every other string
for (const std::string& s2 : contents) {
// If one is a real substring of the other
if ((s1 != s2) && (s2.find(s1) != std::string::npos)) {
// Then we found something
subStringFound = true;
}
}
// If we did not find a substring
if (!subStringFound)
// Then show it
std::cout << s1 << '\n';
}
}
int main()
{
std::cout << "\n\nVersion 1\n\n";
version1();
std::cout << "\n\nVersion 2\n\n";
version2();
std::cout << "\n\nVersion 3\n\n";
version3();
return 0;
}