关于一个如何使用泛型算法的问题

zhcosin 2013-08-09 09:52:10
问题是这样的,有两个容器A、B,需要从容器A中删除与容器B重复的元素,用泛型算法 std::remove_if 和 std::find_if 如何实现,求指点,可以以 std::vector<int> 为例。
...全文
143 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
mujiok2003 2013-08-10
  • 打赏
  • 举报
回复
用现成的std::set_difference
// set_difference example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_difference, std::sort
#include <vector>       // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
  std::vector<int>::iterator it;

  std::sort (first,first+5);     //  5 10 15 20 25
  std::sort (second,second+5);   // 10 20 30 40 50

  it=std::set_difference (first, first+5, second, second+5, v.begin());
                                               //  5 15 25  0  0  0  0  0  0  0
  v.resize(it-v.begin());                      //  5 15 25

  std::cout << "The difference has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
//The difference has 3 elements:
//5 15 25
FancyMouse 2013-08-10
  • 打赏
  • 举报
回复
你们要讲复杂度干啥不给B建unordered_map再让每个A去查B的hashtable……
ri_aje 2013-08-09
  • 打赏
  • 举报
回复
引用 7 楼 zhcosin 的回复:
[quote=引用 5 楼 ri_aje 的回复:] [quote=引用 4 楼 zhcosin 的回复:] [quote=引用 3 楼 ri_aje 的回复:] 今天我为啥竟犯错误,,再帖一遍试试。

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int> B{3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 std::sort(A.begin(),A.end());
 std::sort(B.begin(),B.end());

 std::vector<int> C;
 std::set_difference(A.begin(),A.end(),
                     B.begin(),B.end(),
                     std::back_inserter(C));
 A = std::move(C);

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
这个方法可以倒是可以,不过泛型算法 std::set_difference 要求两个容器必须事先排好序,这个不太现实哦。[/quote] 那就用 #1 第一种方法呗。 话说如果规模大到排序(std::sort O(nlogn)+O(mlogm))都不现实,那主楼的那种算法 O(n*m) 更不现实,n,m 分别是 A,B 的元素个数。[/quote] 说的也是,不过,我这编译器不支持 C++ 11,一楼的那个。。。。编不过。。。。[/quote] 那就改造改造,你都玩 boost::lambda 了,自己动手丰衣足食撒。

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int>const B {3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 struct not_in
 {
  std::vector<int>const& B;
  not_in (std::vector<int>const& B) : B(B) { }
  bool operator () (int const a) const
  {
   return B.end() != std::find(B.begin(),B.end(),a);
  }
 };

 A.erase(std::remove_if(A.begin(),A.end(),not_in(B)),A.end());

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
大尾巴猫 2013-08-09
  • 打赏
  • 举报
回复
我用的vs2010, 来个2010版本的
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

int main()
{
	int data1[] = {1,2,11,12,3,12,11,4,5,11,6,7,8,9};
	int data2[] = {11,12};
	//根据数组初始化2个容器
	vector<int> v1(sizeof(data1) / sizeof(int));
	vector<int> v2(sizeof(data2) / sizeof(int));
	for (int i = 0; i < sizeof(data1) / sizeof(int); i++)
		v1[i] = data1[i];
	for (int i = 0; i < sizeof(data2) / sizeof(int); i++)
		v2[i] = data2[i];
	
	typedef vector<int>::iterator vit;  //定义迭代器
	vit it1 = v1.end();  //设置在v1搜索的区间,从 begin 到 it1
	for (vit it = v2.begin(); it < v2.end(); ++it)
	{
		vit it2 = find(v1.begin(),it1, *it);  //对v2中的每个值在v1中进行查找
		if (it2 != it1)
		{
			it1 = remove(v1.begin(), it1, *it);   //找到执行remove
		}
	}
	v1.erase(it1, v1.end());   //remove并不会删除元素,最后erase删除
	copy(v1.begin(), v1.end(), ostream_iterator<int, char>(cout, " "));
	cout << endl;
	return 0;
}
zhcosin 2013-08-09
  • 打赏
  • 举报
回复
引用 5 楼 ri_aje 的回复:
[quote=引用 4 楼 zhcosin 的回复:] [quote=引用 3 楼 ri_aje 的回复:] 今天我为啥竟犯错误,,再帖一遍试试。

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int> B{3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 std::sort(A.begin(),A.end());
 std::sort(B.begin(),B.end());

 std::vector<int> C;
 std::set_difference(A.begin(),A.end(),
                     B.begin(),B.end(),
                     std::back_inserter(C));
 A = std::move(C);

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
这个方法可以倒是可以,不过泛型算法 std::set_difference 要求两个容器必须事先排好序,这个不太现实哦。[/quote] 那就用 #1 第一种方法呗。 话说如果规模大到排序(std::sort O(nlogn)+O(mlogm))都不现实,那主楼的那种算法 O(n*m) 更不现实,n,m 分别是 A,B 的元素个数。[/quote] 说的也是,不过,我这编译器不支持 C++ 11,一楼的那个。。。。编不过。。。。
ri_aje 2013-08-09
  • 打赏
  • 举报
回复
又想了一下,如果 B 不是很大,可以遍历 A,然后 binary_search B,不要用 find_if,这样的话是 O(nlogm).
ri_aje 2013-08-09
  • 打赏
  • 举报
回复
引用 4 楼 zhcosin 的回复:
[quote=引用 3 楼 ri_aje 的回复:] 今天我为啥竟犯错误,,再帖一遍试试。

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int> B{3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 std::sort(A.begin(),A.end());
 std::sort(B.begin(),B.end());

 std::vector<int> C;
 std::set_difference(A.begin(),A.end(),
                     B.begin(),B.end(),
                     std::back_inserter(C));
 A = std::move(C);

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
这个方法可以倒是可以,不过泛型算法 std::set_difference 要求两个容器必须事先排好序,这个不太现实哦。[/quote] 那就用 #1 第一种方法呗。 话说如果规模大到排序(std::sort O(nlogn)+O(mlogm))都不现实,那主楼的那种算法 O(n*m) 更不现实,n,m 分别是 A,B 的元素个数。
zhcosin 2013-08-09
  • 打赏
  • 举报
回复
引用 3 楼 ri_aje 的回复:
今天我为啥竟犯错误,,再帖一遍试试。

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int> B{3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 std::sort(A.begin(),A.end());
 std::sort(B.begin(),B.end());

 std::vector<int> C;
 std::set_difference(A.begin(),A.end(),
                     B.begin(),B.end(),
                     std::back_inserter(C));
 A = std::move(C);

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
这个方法可以倒是可以,不过泛型算法 std::set_difference 要求两个容器必须事先排好序,这个不太现实哦。
ri_aje 2013-08-09
  • 打赏
  • 举报
回复
今天我为啥竟犯错误,,再帖一遍试试。

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int> B{3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 std::sort(A.begin(),A.end());
 std::sort(B.begin(),B.end());

 std::vector<int> C;
 std::set_difference(A.begin(),A.end(),
                     B.begin(),B.end(),
                     std::back_inserter(C));
 A = std::move(C);

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
ri_aje 2013-08-09
  • 打赏
  • 举报
回复

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

int main ()
{
 std::vector<int> a {0,1,2,3,4,5,6,7,8,9};
 std::vector<int> b {3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : a) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : b) { std::cout << b << " "; } std::cout << std::endl;

 std::sort(a.begin(),a.end());
 std::sort(b.begin(),b.end());

 std::vector<int> c;
 std::set_difference(a.begin(),a.end(),
                     b.begin(),b.end(),
                     std::back_inserter(c));
 a = std::move(c);

 std::cout << "after removal" << std::endl;
 for (auto const a : a) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : b) { std::cout << b << " "; } std::cout << std::endl;
}
ri_aje 2013-08-09
  • 打赏
  • 举报
回复
this literally does what you have asked for.

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

int main ()
{
 std::vector<int> A {0,1,2,3,4,5,6,7,8,9};
 std::vector<int>const B{3,5,8};

 std::cout << "before removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;

 A.erase(std::remove_if(A.begin(),A.end(),[&](int const a)
         {
         return B.end() != std::find(B.begin(),B.end(),a);
         }),A.end());

 std::cout << "after removal" << std::endl;
 for (auto const a : A) { std::cout << a << " "; } std::cout << std::endl;
 for (auto const b : B) { std::cout << b << " "; } std::cout << std::endl;
}
but a faster solution would be #include <algorithm> #include <iostream> #include <iterator> #include <vector> int main () { std::vector<int> a {0,1,2,3,4,5,6,7,8,9}; std::vector<int> b{3,5,8}; std::cout << "before removal" << std::endl; for (auto const a : a) { std::cout << a << " "; } std::cout << std::endl; for (auto const b : b) { std::cout << b << " "; } std::cout << std::endl; std::sort(a.begin(),a.end()); std::sort(b.begin(),b.end()); std::vector<int> c; std::set_difference(a.begin(),a.end(), b.begin(),b.end(), std::back_inserter(c)); a = std::move(c); std::cout << "after removal" << std::endl; for (auto const a : a) { std::cout << a << " "; } std::cout << std::endl; for (auto const b : b) { std::cout << b << " "; } std::cout << std::endl; }

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧