从排序的std :: vector中删除具有相同键的最后一个元素的最简洁方法是什么?

时间:2013-06-28 06:12:56

标签: c++ vector stl

我有一个结构向量{key; value},按键排序:

{ {0, 1}, {0, 2}, {1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2} }

我需要使用相同的键擦除除最后一个元素以外的所有元素。结果应该是:

{ {0, 2}, {1, 3}, {2, 2} }

最简洁的方法是什么?我可以使用哪种STL算法?显然,这个任务不适合删除 - 擦除习惯用法。

3 个答案:

答案 0 :(得分:8)

一个天真但有效的解决方案是迭代向量,将相关元素复制到一个新向量中。

另一种方法是使用std::unique(使用适当的谓词)。由于您希望保留每个组中的 last 元素,因此您需要使用反向迭代器。

答案 1 :(得分:3)

我说的话,所需的算法是:

  • 向后迭代容器
  • 如果你使用新密钥,请保留元素
  • 如果您使用了已经拥有的密钥,请删除该元素。

代码:

#include <vector>
#include <iostream>
#include <algorithm>

struct S { int key; int value; };

int main() {
  std::vector<S> vec{ {0, 1}, {0, 2}, {1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2} };

  auto lastKey = std::numeric_limits<int>::max();
  auto rLast = std::remove_if(vec.rbegin(), vec.rend(), [&lastKey](S const& s) -> bool {
    if (s.key == lastKey) return true;
    lastKey = s.key;
    return false;
  });
  vec.erase(begin(vec),rLast.base());

  for (auto& s : vec) {
    std::cout << '{' << s.key << ',' << s.value << '}';
  }
}

或使用其他答案中建议的std::unique

auto rLast = std::unique(vec.rbegin(), vec.rend() [](S const& s1, S const& s2) {
  return s1.key == s2.key;
});
vec.erase(vec.begin(), rLast.base());

答案 2 :(得分:1)

如果使用std::map问题就会消失:

std::map<int, int> theMap;
// insert the elements of { {0, 1}, {0, 2}, {1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2} }
theMap[0] = 1;
theMap[0] = 2;
theMap[1] = 1;
theMap[1] = 2;
theMap[1] = 3;
theMap[2] = 1;
theMap[2] = 2;
// result: { {0, 2}, {1, 3}, {2, 2} }