个人整理学习用,非教材,有错误欢迎指正
今天c++刷leetcode的每日一题:937. 重新排列日志文件。其中涉及到string类型的比较问题以及手写mycompare()
函数
题目中涉及到排序,首先想到的是sort()
函数,sort()函数也确实可以给string类型排序,但是题目要求根据标签、内容并按照一定优先级排序。因此,默认的cmpare()
函数不足以完成次功能,需要自己手写mycompare()
。其中,题目要求:内容为数字时不改变原相对位置,也就是不发生位置交换。
查询compare函数定义:bool compare(a,b)
,当a的正确位置排在b之前时,返回true,若a的正确位置应在b之后,则应返回false。我通常理解为,返回值为true时,不发生交换;返回值为false时,发生交换。因此自然而然地,mycompare()
中,如果检测到两个输入地字符串其对应content为数字时,返回false,即不交换顺序。在运行时,发现所有的数字字符串顺序反过来了。
查证无果,在自己调试时发现了端倪在两个参数的传参调用上。sort()
函数调用mycompare()
时,是从右向左传递参数的,也就是下标靠前的元素先传入b,下标靠后的元素传入a,因此正确的理解是返回值为true时发生交换;返回值为false时不发生交换。因此第一条定义对于a=b的情况并不适用。当a=b时,直觉上a应该在b之前,返回true,但是实际上先传入的是b,若不发生交换,则默认此时的位置是对的,也就是b应该排在a之前。虽然从排序算法本身来说没有交换,但是这次交换已经在传参的顺序中隐含了。
因此,每次compare()前,先默认交换了一次,然后看交换后的顺序是否正确。若交换后的顺序正确,则返回false,sort()不再进行交换,也就是a应该排在b之后;若交换后的顺序不正确,则返回true,由sort()再进行一次交换,也就是a应该排在b之前。
以上仅是个人猜测,但如果了解数据结构就能发现还是有错误的。sort()是类似于快排算法,因此sort()与快排一样,为了保证高效是不稳定的。而上面的情况仅仅是第一次交换时的情况,但排序本身会多次交换元素,也就是多次传参。之后再传参时就不能保证谁先传入,谁后传入的问题了。因此两个相同的元素,其最终相对位置并不一定等于初始相对位置。我们要使用stable_sort()
函数,来代替sort()。stable_sort()放弃了一些性能来保证排序是稳定的,同时,stable_sort()
的传参应该是可以始终保证是右往左(也可能有其他实现方法,不妨先这样理解),因此也与前文一样,在mycompare()
中,元素值一样时不发生交换,即返回false
综上:
- 在
sort()
中只需要记住定义一就够了,因为讨论元素值相同的情况是无意义的 - 在
stable_sort()
中,应该定义二于定义一相结合,因为值相同时,定义一会失效