问题
现在有两个字符串,我们要想办法表现出他们的不同。我们只考虑字符串中的小写字符a-z。首先计算每个小写字母在两个字符串中出现的频率
s1 = “A aaaa bb c”
s2 = “& aaa bbb c d”
s1 has 4 ‘a’, 2 ‘b’, 1 ‘c’
s2 has 3 ‘a’, 3 ‘b’, 1 ‘c’, 1 ‘d’
经过比较a这个字母出现频率最高是在s1中出现4次,b是在s2中出现3次。对于那种最多的频率小于2的不考虑。
对两个字符串的不同可以表示为”1:aaaa/2:bbb”
现在给两个字符串,用以上方法表示它们的不同。
例子
s1 = “my&friend&Paul has heavy hats! &”
s2 = “my friend John has many many friends &”
mix(s1, s2) –> “2:nnnnn/1:aaaa/1:hhh/2:mmm/2:yyy/2:dd/2:ff/2:ii/2:rr/=:ee/=:ss”
s1 = “mmmmm m nnnnn y&friend&Paul has heavy hats! &”
s2 = “my frie n d Joh n has ma n y ma n y frie n ds n&”
mix(s1, s2) –> “1:mmmmmm/=:nnnnnn/1:aaaa/1:hhh/2:yyy/2:dd/2:ff/2:ii/2:rr/=:ee/=:ss”
s1=”Are the kids at home? aaaaa fffff”
s2=”Yes they are here! aaaaa fffff”
mix(s1, s2) –> “=:aaaaaa/2:eeeee/=:fffff/1:tt/2:rr/=:hh”
我的代码
package codewars;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Mixing {
public static String mix(String s1, String s2) {
//统计字符串m1的各个字母频率
Map<String, Long> m1 = Stream.of(s1.replaceAll("[^a-z]","").split("")).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
//统计字符串m2的各个字母频率
Map<String, Long> m2 = Stream.of(s2.replaceAll("[^a-z]","").split("")).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Set<String> set1 = m1.keySet();
Set<String> set2 = m2.keySet();
Set<String> set3 = new HashSet<>();
set3.addAll(set1);
set3.addAll(set2);
List<String> result = set3.stream().map(e -> {
StringBuilder sb = new StringBuilder();
if (m1.get(e) != null && m2.get(e) != null && m1.get(e) > 1 && m1.get(e) > m2.get(e)) {
for (int i = 0; i < m1.get(e); i++) {
sb.append(e);
}
return "1:"+sb.toString();
} else if (m1.get(e) != null && m2.get(e) != null && m1.get(e) > 1 && m1.get(e) == m2.get(e)) {
for (int i = 0; i < m1.get(e); i++) {
sb.append(e);
}
return "=:"+sb.toString();
} else if (m1.get(e) != null && m2.get(e) != null && m2.get(e) > 1 && m2.get(e) > m1.get(e)) {
for (int i = 0; i < m2.get(e); i++) {
sb.append(e);
}
return "2:"+sb.toString();
} else if (m1.get(e) != null && m2.get(e) == null && m1.get(e) > 1) {
for (int i = 0; i < m1.get(e); i++) {
sb.append(e);
}
return "1:"+sb.toString();
} else if (m2.get(e) != null && m1.get(e) == null && m2.get(e) > 1) {
for (int i = 0; i < m2.get(e); i++) {
sb.append(e);
}
return "2:"+sb.toString();
} else {
return "";
}
}).filter(e -> e.length()>0).sorted(Comparator.comparing(String::length).reversed().thenComparing(Function.identity())).collect(Collectors.toList());
return String.join("/", result);
}
public static void main(String[] args) {
System.out.println(Mixing.mix(" In many languages", " there's a pair of functions"));
}
}
分析
这道题有点难度,思路是:
- 将两个字符串中各个小写字母的频率统计出来,结果是Map,key为字母,value为出现次数
- 出去两个字符串中出现的所有小写字母集合set
- 遍历set按照问题给出的逻辑拼接出字符串列表list
- list按照长度的降序,字符串的字典序排列
- 用”/”join出结果