我想确定一个列表是anagram还是不使用Java 8。
示例输入:
"cat", "cta", "act", "atc", "tac", "tca"我编写了以下函数来完成这项工作,但我想知道是否有一种更好、更优雅的方法来做到这一点。
boolean isAnagram(String[] list) {
long count = Stream.of(list)
.map(String::toCharArray)
.map(arr -> {
Arrays.sort(arr);
return arr;
})
.map(String::valueOf)
.distinct()
.count();
return count == 1;
}似乎我无法使用Stream.sorted()方法对char数组进行排序,因此我使用了第二个map运算符。如果有某种方式可以直接操作char流而不是char数组,那也会有帮助。
发布于 2018-10-29 15:10:43
您可以在字符串中获取char[]或int[]的Stream,并在将它们转换为数组之前对它们进行排序,而不是创建和排序不能内联并“中断”流的Stream或chars。但是请注意,这是一个IntSteam,String.valueOf(int[])将包含数组的内存地址,这在这里不是很有用,所以在本例中最好使用Arrays.toString。
boolean anagrams = Stream.of(words)
.map(String::chars).map(IntStream::sorted)
.map(IntStream::toArray).map(Arrays::toString)
.distinct().count() == 1;当然,您也可以使用map(s -> Arrays.toString(s.chars().sorted().toArray()))来代替四个maps的系列。不确定速度是否有显著的差异,这可能主要是因为口味的问题。
另外,您可以使用IntBuffer.wrap使数组具有可比性,这应该比Arrays.toString快得多(感谢注释中的Holger )。
boolean anagrams = Stream.of(words)
.map(s -> IntBuffer.wrap(s.chars().sorted().toArray()))
.distinct().count() == 1;发布于 2018-10-29 15:15:37
我不会对char数组排序,因为排序是O(NlogN),这在这里是不必要的。
我们所需要的是,对于列表中的每个单词,统计每个字符的出现情况。为此,我们将每个单词的字符收集到一个Map<Integer, Long>中,键是每个字符,值是它的计数。
然后,我们检查数组参数中的所有单词是否有相同的字符计数,即相同的映射:
return Arrays.stream(list)
.map(word -> word.chars()
.boxed().collect(Collectors.grouping(c -> c, Collectors.counting()))
.distinct()
.count() == 1;发布于 2018-10-30 02:18:05
或者,您的实现的更新版本可以是:
boolean isAnagram(String[] list) {
return Stream.of(list) // Stream<String>
.map(String::toCharArray) // Stream<char[]>
.peek(Arrays::sort) // sort
.map(String::valueOf) // Stream<String>
.distinct() //distinct
.count() == 1;
}https://stackoverflow.com/questions/53048056
复制相似问题