我有一个结构向量。
该结构有两个元素 X和Y ,其值如下所示。
假设:
索引0 1 2 3 4 5 6 7 8 9
值a,b c,d e,f g,h a,b a,i a,i a,i j,k l,m
我的问题:** 我需要保持**最新出现的元素(x,y)并在有效时间内删除其余部分,并且可能有辅助空间。
说,我从向量的开头开始,遇到元素(a,b),我需要删除这个元素加上所有其他(a,x)s,x可以是这里的任何东西,但不是< strong> b ,但保留最近的(a,b)。
在这里,我需要删除索引 0,5,6,7 的元素,并将其保留在 4 。
使用 vector.push_back()插入元素,因此最新元素是最后插入的元素。 (插入模仿队列的内容)
我的进步:
i)我尝试过稳定排序,但考虑到我可能遇到 O(nlogn)复杂性,我对这种方法不感兴趣。
ii)设计使我只能从头开始迭代,我无法逆转并从头开始。
iii)为了降低复杂性,我做了类似的事情:
- Iterate vector from start to end.
- For every elements, keep the search area to a smaller one by searching from the end.
- Then delete all elements between current positions of forward iterator and the reverse iterator. This does not take the above illustrated case into consideration and works only when the most recent element is towards the end, i.e.in the above case, all (a,i)s are before the last (a,b)
答案 0 :(得分:0)
我无法想到比天真的方法更快的事情:
#include <vector>
#include <algorithm>
using namespace std;
struct S {
char X;
char Y;
};
bool operator==(const S& lhs, const S& rhs ) {
return lhs.X == rhs.X && lhs.Y == rhs.Y;
}
int main(){
std::vector < S > src = { { 'a', 'b' }, { 'c', 'd' }, { 'e', 'f' }, { 'g', 'h' }, { 'a', 'b' }, { 'a', 'i' }, { 'a', 'i' }, { 'a', 'i' }, { 'j', 'k' }, { 'l', 'm' } };
auto srcIt = begin(src);
while (srcIt != end(src)) {
// find last identical element
auto le = find(rbegin(src), rend(src), *srcIt).base() - 1;
char x = srcIt->X;
// delete all elements with same X value after last element
src.erase(std::remove_if(le + 1, end(src), [=](const S& e){return x == e.X; }), end(src));
// delete all elements with same X value up to last element
src.erase(std::remove_if(srcIt, le, [=](const S& e){return x == e.X; }), le);
srcIt++;
}
for (auto& e : src) {
std::cout << e.X << "," << e.Y << " - ";
}
std::cout << std::endl;
}
我不确定,是否可以将其转换为单通道算法,但即便如此,您必须测试的值的数量会在每个步骤中增加,因此这会导致类似的渐近复杂度(可能少一些副本),但代码可能更复杂。
原则上,您可以在两个缓冲区之间用erase remove
替换copy_if
,但我不知道如何提高性能,除非您想在问题中抛出多个线程。在这种情况下,我会让每个线程将所选元素复制到一个单独的缓冲区中,然后在每次迭代结束时将它们连接起来。