拓展排序的偏序匹配

举报
用户已注销 发表于 2021/11/19 04:26:58 2021/11/19
【摘要】 在力扣OJ 15. 三数之和中,有这么一段代码: //给vector拓展,加上id并排序template<typename T>bool cmp(T x,T y){ return x<y;}template<typename T>vector<pair<T,int>&gt...

在力扣OJ 15. 三数之和中,有这么一段代码:


  
  1. //给vector拓展,加上id并排序
  2. template<typename T>
  3. bool cmp(T x,T y)
  4. {
  5. return x<y;
  6. }
  7. template<typename T>
  8. vector<pair<T,int>> sortWithId(vector<T>v)
  9. {
  10. vector<pair<T,int>>ans;
  11. ans.resize(v.size());
  12. for(int i=0;i<v.size();i++)ans[i].first=v[i],ans[i].second=i;
  13. sort(ans.begin(),ans.end(),[](pair<T,int>p1,pair<T,int>p2){return cmp(p1.first,p2.first);});
  14. return ans;
  15. }
  16. //2个vector中寻找和为s的对,返回结果的每一行都是[id1,id2]
  17. template<typename T>
  18. vector<vector<int>> findSum(vector<T>v1,vector<T>v2,T s)
  19. {
  20. vector<vector<int>>ans;
  21. int m=min(int(v1.size()*v2.size()),1234567);
  22. ans.reserve(m);
  23. vector<int>tmp(2);
  24. vector<pair<T,int>>v3=sortWithId(v2);
  25. sort(v2.begin(), v2.end(),cmp<T>);
  26. for(int i=0;i<v1.size();i++)
  27. {
  28. auto it1=lower_bound(v2.begin(), v2.end(), s-v1[i]);
  29. auto it2=upper_bound(v2.begin(), v2.end(), s-v1[i]);
  30. tmp[0]=i;
  31. for(auto j=it1;j<it2;j++)
  32. {
  33. tmp[1]=v3[j-v2.begin()].second;
  34. ans.push_back(tmp);
  35. }
  36. }
  37. return ans;
  38. }

其中两次用到sort函数:


  
  1. vector<pair<T,int>>v3=sortWithId(v2);
  2. sort(v2.begin(), v2.end(),cmp<T>);

一个是带ID的拓展数据域的排序,一个是原朴素数据域的排序,然后根据相同的数组下标直接对应。

这么做有没有根据?

 

换句话说,拓展排序和原排序一定偏序匹配吗

偏序匹配的条件有2个:

(1)排序算法不含随机行为,即无论调用多少次,它的行为都是完全一致的。

(2)比较函数对拓展封闭,即拓展数据域的比较逻辑和原比较逻辑完全一致。

 

总结:拓展排序有两种,一种是上面代码中所示,比较逻辑(即cmp函数)不变,拓展排序和原排序是偏序匹配的,

另外一种是利用ID实现把不稳定排序变成稳定排序,需要修改cmp函数,比较逻辑变了,这样的一个稳定排序的结果和原来的不稳定排序的结果自然也是不能确保偏序匹配的。当然,如果原排序就是稳定排序,那就和拓展排序是偏序匹配的。

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/107223702

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。