螺钉和螺母排序问题:现给定一堆螺钉和螺母(螺母和螺钉一对一唯一配对,即不存在相同大小的螺钉或螺母),现需要对螺母和螺钉按尺寸的大小排序。但是要求是不能直接根据螺钉或螺母尺寸大小进行排序,仅能通过给定的一个match函数比较大小(match()方法比较螺母和螺钉的尺寸大小,0表示两者匹配,1表示螺母尺寸大于螺钉尺寸,-1表示螺母尺寸小于螺钉尺寸)。
给定的螺钉螺母类:

class Nuts_Screws {class Nuts {private int id;//螺母标号private int size;//螺母尺寸public void setId(int id) {this.id = id;}public void setSize(int size) {this.size = size;}@Overridepublic String toString() {return "Nuts [id=" + id + ", size=" + size + "]";}}class Screws {private int id;//螺钉标号private int size;//螺钉尺寸public void setId(int id) {this.id = id;}public void setSize(int size) {this.size = size;}@Overridepublic String toString() {return "Screws [id=" + id + ", size=" + size + "]";}}public void print(Nuts[] nuts, Screws[] screws) {for (Nuts nut : nuts) {System.out.print(nut.size + " ");}System.out.println();for (Screws screw : screws) {System.out.print(screw.size + " ");}System.out.println();}public int MatchNS(Nuts nut, Screws screw) {int res = nut.size - screw.size;return res > 0 ? 1 : res < 0 ? -1 : 0;}
}

基于上述问题,很自然的想到一种暴力的方法,就是用两个指针分别遍历螺钉数组和螺母数组,用螺钉匹配螺母,match返回0就是匹配,但是这样无法排序,因为我们无法获得螺钉之间的大小关系。
我们应该如何让获取螺钉之间的大小关系呢?答案是通过match方法获得,题目给定的唯一条件表明,当我们使用螺钉请匹配螺母的时候,除了获得一个匹配的螺母外,还会获得一堆偏小的螺母,一堆偏大的螺母,这样其实就获得了当前螺母在整个数组中排完序后的位置。想到这里是不是想到一种排序?对的,就是快排,快排的核心操作就是获取当前元素在排序后数组的位置。
通过上述分析,我们用一个螺钉去匹配螺母,可以获取匹配螺母在排序后所在位置,那么接下来该如何处理大的螺母堆和小的螺母堆呢?我们可以尝试故技重施,再选择一个螺钉去匹配大的一堆,这样有可能会选择到小堆的螺母匹配的螺钉,就是说对大堆螺母没有起到效果。

那我们改如何解决这个问题呢?答案还是快排,既然螺钉匹配螺母可以获取螺母的排序后位置,那么我们也可以采用同样的方法获取螺钉的排序后位置,这样匹配的螺钉和螺母就会将两个数组分别分割成小堆和大堆,那么从小堆取螺钉自然就能对小堆螺母起作用,同理大堆亦然。说到这我们就能明白,这道题使用的是快排的思想,通过间接比较的方法实现快排,不过要注意左右哨兵快排的写法,要注意若选择起始元素作为基准,要让右哨兵先走,不然两个哨兵相遇的地方就是偏小的位置,而不是偏大的位置。
以下是笔者书写的解法:

import java.util.*;import AtLeisure.Nuts_Screws.Nuts;
import AtLeisure.Nuts_Screws.Screws;/*** 螺钉和螺母排序问题* 现给定一堆螺钉和螺母(螺母和螺钉一对一唯一配对),现需要对螺母和螺钉按尺寸的大小排序。* 基于给定一个Nuts类和Screws类,螺钉和螺母需要size一样才能匹配。* 但是只能使用提供的方法match()方法比较螺母和螺钉的尺寸大小,* 0表示两者匹配,1表示螺母尺寸大于螺钉尺寸,-1表示螺母尺寸小于螺钉尺寸* @author brooke**/
public class Nuts_Screws_Match {public static void main(String[] args) {int num = (int)(Math.random()*100);
//      int num = 10;Nuts_Screws nuts_screw = new Nuts_Screws();Nuts[] nuts = new Nuts[num];Screws[] screws = new Nuts_Screws.Screws[num];List<Integer> list_nut = new ArrayList<>();List<Integer> list_screw = new ArrayList<>();for(int i=1;i<=num;i++) {list_nut.add(i);list_screw.add(i);}Collections.shuffle(list_nut);Collections.shuffle(list_screw);for(int i=0;i<num;i++) {nuts[i] = nuts_screw.new Nuts();screws[i] = nuts_screw.new Screws();nuts[i].setId(i+1);nuts[i].setSize(list_nut.get(i));screws[i].setId(i+1);screws[i].setSize(list_screw.get(i));}System.out.println("Before sort:");
//      System.out.println(Arrays.toString(nuts));
//      System.out.println(Arrays.toString(screws));nuts_screw.print(nuts, screws);sort_order(nuts, screws, nuts_screw);System.out.println("After sort:");
//      System.out.println(Arrays.toString(nuts));
//      System.out.println(Arrays.toString(screws));nuts_screw.print(nuts, screws);}/*** 利用快排的思想,用第一个螺母去匹配螺钉,必然只有一个匹配上为0,其他都是-1或1,* 这样我们就能锁定为0 的一对螺母螺钉在整个数组中的位置,然后调整位置,-1的放左边,1的放右边* 这个时候要调整螺母和螺钉的位置,用螺钉去找螺母的位置,螺母去找螺钉的位置。* 先用螺母找螺钉,然后-1放左边,1放右边。调整好螺钉后,用0的螺钉去调整螺母,螺母也一样调整。剩下就是递归。* @param nuts_screw * */public static void sort_order(Nuts[] nuts, Screws[] screws, Nuts_Screws nuts_screw) {int n = nuts.length;sort_order(nuts, screws, nuts_screw, 0, n-1);}private static void sort_order(Nuts[] nuts, Screws[] screws, Nuts_Screws nuts_screw, int start, int end) {if(start >= end) {return ;}int i = start;int j = end;int mat = i;//记录匹配的螺钉位置while(i <= j) {while(i <= j && nuts_screw.MatchNS(nuts[start], screws[j]) <= 0) {if(nuts_screw.MatchNS(nuts[start], screws[j]) == 0) {mat = j;}j--;}while(i <= j && nuts_screw.MatchNS(nuts[start], screws[i]) > 0) i++;if(i <= j) {Screws temp = screws[i];screws[i] = screws[j];screws[j] = temp;}}if(mat != i) {Screws temp = screws[i];screws[i] = screws[mat];screws[mat] = temp;mat = i;}i = start;j = end;int mmat = i;while(i <= j) {while(i <= j && nuts_screw.MatchNS(nuts[j], screws[mat]) >= 0) {if(nuts_screw.MatchNS(nuts[j], screws[mat]) == 0) {mmat = j;}j--;}while(i <= j && nuts_screw.MatchNS(nuts[i], screws[mat]) < 0) i++;if(i <= j) {Nuts temp = nuts[i];nuts[i] = nuts[j];nuts[j] = temp;}}if(mmat != i) {Nuts temp = nuts[i];nuts[i] = nuts[mmat];nuts[mmat] = temp;mmat = i;}if(mmat != mat) {System.out.println("Error:mat = " + mat + " mmat = " + mmat);}sort_order(nuts, screws, nuts_screw, start, mat - 1);sort_order(nuts, screws, nuts_screw, mat + 1, end);}}

随机一次运行结果如下:

Before sort:
21 34 2 23 28 31 16 11 20 25 26 19 4 7 13 33 17 10 35 27 22 3 8 24 5 6 9 14 12 18 1 15 36 32 29 30
19 1 8 32 20 18 33 14 7 30 3 16 2 23 17 24 13 4 35 12 5 29 22 25 9 26 6 34 31 11 21 10 15 27 36 28
After sort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

快速排序之螺钉螺母匹配相关推荐

  1. java小白探索,螺栓螺母匹配,冒泡实现和快速排序实现

    丁丁的算法作业,学大佬发博客,各位大佬教教我算法入门求求了.昨天大佬指出冒泡哪里有错误已经修改了,在源代码上加上了键入. package com.company;import java.util.Ar ...

  2. 趣味编程:函数式链表的快速排序

    前一段时间有朋友问我,以下这段Haskell快速排序的代码,是否可以转化成C#中等价的Lambda表达式实现: qsort [] = [] qsort (x:xs) = qsort (filter ( ...

  3. 【学习笔记】C#中HashTable和快速排序的用法,从单词频率统计小程序写起

    先瞎扯点别的.进入这个神圣的地方总需要些鞭策,阿西巴,我是被鞭策进来摆摊的程序猿.软件工程老师说,写程序,发博客,就来博客园.这是个号召力很强的口号.最近看网络营销 搜索引擎优化的书多一些,只能说王老 ...

  4. 【NLP】2020深度文本匹配最新进展:精度、速度我都要!

    文 | QvQ 编 | 兔子酱 在过去的几年里,信息检索(IR)领域见证了一系列神经排序模型的引入,这些模型多是基于表示或基于交互的,亦或二者的融合.然鹅,模型虽非常有效,尤其是基于 PLMs 的排序 ...

  5. 《剑指offer》-- 数组中的逆序对、最小的K个数、从1到n整数中1出现的次数、正则表达式匹配、数值的整数次方

    一.数组中的逆序对: 1.题目: 数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出 ...

  6. 写一个排序算法,可以是冒泡排序或者是快速排序,假设待排序对象是一个维数组。(提示:不能使用系统已有函数,另外请仔细回忆以前学习过的 基础知识)...

    //冒泡排序(数组排序) function bubble_sort($array) {$count = count($array);if ($count <= 0) return false;f ...

  7. MTK优美代码赏析6:电话本里的快速排序和插入排序算法

    MTK优美代码赏析6:电话本里的快速排序和插入排序算法 记得读书的时候学数据结构和一些程序基础的课程,学了很多的排序算法,当时感觉蛮有趣,也很简单,当大学的教育是以理论为主的,哪些教授们又没给咱举个实 ...

  8. 2020深度文本匹配最新进展:精度、速度我都要!

    文 | QvQ 编 | 兔子酱 在过去的几年里,信息检索(IR)领域见证了一系列神经排序模型的引入,这些模型多是基于表示或基于交互的,亦或二者的融合.然鹅,模型虽非常有效,尤其是基于 PLMs 的排序 ...

  9. 设置线程堆栈大小_哇擦,传说中的堆栈溢出和快速排序

    stack overflow 堆栈溢出和快速排序这两个概念对开发人员来说并不陌生,但是通知都只是听说过,真正开发过程中却很少会遇到.我也是敲代码好些行后非常有幸撞上了,而且还是两个一起出现的,这其中过 ...

  10. python数据结构和算法 时间复杂度分析 乱序单词检测 线性数据结构 栈stack 字符匹配 表达式求值 queue队列 链表 递归 动态规划 排序和搜索 树 图

    python数据结构和算法 参考 本文github 计算机科学是解决问题的研究.计算机科学使用抽象作为表示过程和数据的工具.抽象的数据类型允许程序员通过隐藏数据的细节来管理问题领域的复杂性.Pytho ...

最新文章

  1. 揭开雷达的面纱(科普)接收机
  2. 学习java的步骤_java学习的基本步骤
  3. 用XInput库使用xbox360手柄
  4. setModel 的核心逻辑
  5. 英语一段落排序题技巧
  6. 作者:熊贇(1980-),女,博士,复旦大学计算机科学技术学院教授
  7. 中国人寿构建国内首个Silverlight企业级应用
  8. 深圳 | 腾讯 Robotics X 招聘语义视觉方向实习生和正式员工
  9. android java代码重启,如何在Android中重启服务?
  10. 别让for循环毁了你的程序(二)
  11. pandas 如何删掉第一行_Pandas-数据筛选
  12. Python Day 10 函数(名称空间,作用域,作用域链,加载顺序等; 函数的嵌套 global,nonlocal)...
  13. 机器学习、深度学习概念术语的理解
  14. k8s组件通信或者创建pod生命周期
  15. Python学习教程(Python学习路线):Python3你还未get到的隐藏技能
  16. 页面滚动可视区域的获取
  17. Linux ldd时某个依赖库so not found的一种特殊情形
  18. 最新HTML5财经直播聊天室喊单直播间系统源码 Redis缓存技术
  19. QQ音乐JS逆向爬虫,获取调皮的sign参数,我用python全都爬!
  20. H3CSE认证网络工程师视频课程-广域网-宋文峰-专题视频课程

热门文章

  1. 保险污名化?区块链赋予保险的「四个机会」
  2. Unity Demo ——3D时钟
  3. 74HC595在【8x8LED点阵】中的运用
  4. 车载激光扫描系统检校
  5. 计算机 大管家 说课稿,精选信息技术说课稿模板集锦九篇
  6. 通用技术标模板,技术方案书
  7. Android LinearLayout实现下拉刷新
  8. Matlab线型、标记符号、颜色
  9. 迅捷pdf怎么转换成html,PDF怎么转HTML?迅捷PDF转换器还能这么用!
  10. 小程序阿里云oss前端直传