面试题目:给定两个数N,K和N个字符串,输出2*K行,每行为字符串和该字符串出现的次数,对于前K行,按字符串出现次数降序排列,如果出现次数相同,则按字符串的字典序升序输出,后K行,按字符串出现次数升序排列,如果出现次数相同,则按字符串的字典序升序输出。
题解,其实就是对字符串S
的一个计数+排序,排序的对象为:(出现次数,字符串),当使用出现次数Count
无法判定大小的时候,使用额外的字符串本身的序列作为比较依据。
使用Java还是比较好写的,直接传给list.sort()
一个比较器(Comparator
)就行了:
class Row {
String string;
Integer count;
// getter and setter
@Override
public String toString() {
return string + " " + count;
}
}
......
list.sort((Row o1, Row o2) -> {
if (o1.getCount() > o2.getCount()) {
return -1;
} else if (o1.getCount().equals(o2.getCount())) {
return o1.getString().compareTo(o2.getString());
} else {
return 1;
}
});
list.stream().limit(k).forEach(System.out::println);
......
但是之前没有太使用过Python里面的这个比较器,之前的有限经验里面使用的比较多的就是字典的排序了:
# 按照键排
t = sorted(d.items(), key=lambda d: d[0])
# 按照值排
t = sorted(d.items(), key=lambda d: d[1])
没有使用到两个以上的排序属性的排序,查阅之后,发现还是同样使用sorted()
,有如下代码:
import random
from functools import cmp_to_key
def comparator01(o1, o2):
if o1[1] > o2[1]:
return -1
elif o1[1] == o2[1]:
if o1[0] > o2[0]:
return 1
elif o1[0] == o2[0]:
return 0
else:
return -1
else:
return 1
def comparator02(o1, o2):
if o1[1] > o2[1]:
return 1
elif o1[1] == o2[1]:
if o1[0] > o2[0]:
return 1
elif o1[0] == o2[0]:
return 0
else:
return -1
else:
return -1
# n = int(input())
# a = list(map(int, input().split()))
n = 10
a = [random.randint(0, n) for i in range(n)]
d = {}
for i in a:
if i in d.keys():
d[i] += 1
else:
d[i] = 1
t = sorted(d.items(), key=cmp_to_key(comparator01))
limit = n // 3
for i in range(limit):
print('{} {}'.format(*t[i]))
t = sorted(d.items(), key=cmp_to_key(comparator02))
for i in range(limit):
print('{} {}'.format(*t[i]))
需要自定义比较器的逻辑,之后使用functools
里面的cmp_to_key()
将比较逻辑进行包装,传递给key
参数。
网友评论