我想确定列表是否使用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数组的Stream进行操作,那也将有所帮助。
答案 0 :(得分:10)
代替创建和排序char[]
或int[]
(无法内联完成并因此中断流),您可以获取{{1}中的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
快得多(这要感谢注释中的Holger)。
Arrays.toString
答案 1 :(得分:8)
我不会处理计数不同的值,因为那不是您感兴趣的。您想知道的是,根据特殊的相等性规则,所有元素是否相等。
因此,当我们创建将b
转换为规范密钥(即所有字符已排序)的方法时
select a.column1, a.column2, 'a' as column3
from a
union all
select b.column1, b.column2, 'b' as column3
from b
where not exists (select 1 from a where a.column1 = b.column1);
我们可以简单地检查所有后续元素是否等于第一个元素:
String
请注意,对于格式为private CharBuffer canonical(String s) {
char[] array = s.toCharArray();
Arrays.sort(array);
return CharBuffer.wrap(array);
}
的方法引用,该表达式只计算一次并捕获结果,因此对于整个流操作,boolean isAnagram(String[] list) {
if(list.length == 0) return false;
return Arrays.stream(list, 1, list.length)
.map(this::canonical)
.allMatch(canonical(list[0])::equals);
}
仅计算一次,并且仅调用expression::name
每个元素。
当然,您还可以使用Stream API创建规范密钥:
canonical(list[0])
(equals
方法不需要任何更改)
请注意,private IntBuffer canonical(String s) {
return IntBuffer.wrap(s.chars().sorted().toArray());
}
和isAnagram
可用作数组周围的轻量级包装器(如此答案),并根据实际数组适当地实现CharBuffer
和IntBuffer
内容。
答案 2 :(得分:4)
我不会对char数组进行排序,因为排序是EPSV
,在这里没有必要。
对于列表中的每个单词,我们所需要做的就是计算每个字符的出现次数。为此,我们将每个单词的字符收集到const config = {
...
debug: console.log,
forcePasv: true,
};
中,其中键是每个字符,值是其计数。
然后,我们检查数组参数中所有单词的字符数是否相同,即映射是否相同:
O(NlogN)
答案 3 :(得分:2)
或者可以执行的实现的更新版本是:
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;
}
答案 4 :(得分:1)
或者可以与BitSet
一起使用:
System.out.println(stream.map(String::chars)
.map(x -> {
BitSet bitSet = new BitSet();
x.forEach(bitSet::set);
return bitSet;
})
.collect(Collector.of(
BitSet::new,
BitSet::xor,
(left, right) -> {
left.xor(right);
return left;
}
))
.cardinality() == 0);