【发布时间】:2018-05-17 18:14:02
【问题描述】:
我想用 C++ 过滤一个列表。为此,我获得了一个外部函数 f,用于比较元素。基于该比较,我决定保留哪些元素。
我的实现好像有问题,你能帮我找出错误吗?
f 示例:
bool function f(a, b){
if (a + b % 3 != 0){
return true; // keep element
}
return false; }
我想强调的是,这只是一个示例,以保持简单。
我的实现应该像这样工作(元素由___分隔):
1____2____3____4____5____6____7____8
^ ^
f(1, 2) == false. Discard 2.
1____3____4____5____6____7____8
^ ^
now compare the next element with 1
f(1, 3) == true. Keep 3. Move first pointer to 3
1____3____4____5____6____7____8
^ ^
Compare 3 with 4 ...
1____3____4____5____6____7____8
^ ^
remove 5, since f(4, 5) == false
1____3____4____6____7____8
^ ^
keep 6, move pointer
1____3____4____6____7____8
^ ^
1____3____4____6____7____8
^ ^
remove 8.
1____3____4____6____7
^
Nothing more to compare. Terminate.
我通过将有效元素移动到另一个列表并将迭代器移动到原始列表中的下一个元素来实现“删除”,但实际上删除它们也可以。
list<node> result;
list<node>::iterator i = path.begin();
element firstElement = *i;
result.push_back(firstElement);
for (; i != path.end();)
{
if (++i == path.end())
{
break;
}
// compare with next node
int d = distance(firstElement.id, (*i).id);
if (d <= (*i).valFrom)
{
// add edge to result
result.push_back(*i);
firstElement = *i;
}
}
工作示例
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
#include <list>
using namespace std;
int f(int a, int b)
{
if (a + b % 3 == 0)
{
return false;
}
return true;
}
int main()
{
list<int> path = {1, 2, 3, 4, 5, 6, 7, 8};
list<int> result;
bool skip = false;
list<int>::iterator i = path.begin();
int firstint = *i;
result.push_back(firstint);
for (; i != path.end();)
{
if (++i == path.end())
{
break;
}
// compare with next int
if (f(firstint, *i))
{
// add edge to result
result.push_back(*i);
firstint = *i;
}
}
// output path
for (list<int>::iterator i = result.begin(); i != result.end(); ++i)
{
cout << *i << ' ';
}
}
【问题讨论】:
-
这是一个非常好的使用调试器的案例,一步一步执行。
-
这也是使用单元测试的好案例。无论如何,我不确定您是否已经这样做了,但是就地过滤类似的东西通常比复制甚至移动到第二个列表更麻烦。在任何情况下,请用简单的散文为自己编写一个您想要实现的算法的逐步定义。它有助于作为稍后将其转换为 C++ 的中间步骤。
-
@UlrichEckhardt ,这就是为什么我没有这样做,而是将其编译为结果
-
f 由库提供。您可以假设它是正确的,因为它经过了彻底的测试。我不想让这篇文章过于复杂,这就是为什么我编了一个新的f
-
@n.m.我包括了一个工作示例。它做了它应该做的事,但显然并非总是如此