anagrams java_如何判断Java中String字符是否为Anagrams实现

1.概述

根据维基百科,一个Anagram是通过重新排列不同单词或短语的字母而形成的单词或短语。

我们可以在字符串处理中推广这一点,即字符串的一个anagram是另一个字符串,它中每个字符的数量完全相同,以任何顺序排列。

在本教程中,我们将研究如何检测整个字符串的anagram,其中每个字符的数量必须相等,包括空格和数字等非字母字符。给定两个字符串,每个字符包含中英文,空格,大小写等等,如果这两个字符串在忽略大小写和空格的情况下,如果相同字符出现的次数相同,则互为anagram。

2.解决方案

让我们比较几个可以确定两个字符串是否为anagram的解决方案。每个解决方案将在开始时检查两个字符串是否具有相同数量的字符。这是一种快速退出的方法,因为不同长度的输入不能被取消。

对于每个可能的解决方案,让我们来看看我们作为开发人员的实现复杂性。我们还将使用大O表示法来查看CPU的时间复杂度。

此解决方案易于理解和实现。但是,该算法的总体运行时间是O(n logn),因为对n个字符的数组排序需要O(n logn)时间。

要使算法正常工作,它必须使用一点额外的内存,将两个输入字符串复制为字符数组。

4.计数检查

另一种策略是计算输入中每个字符的出现次数。如果这些柱状图在输入之间相等,那么字符串就是anagrams。

为了节省一点内存,我们只构建一个直方图。我们将增加第一个字符串中每个字符的计数,并减少第二个字符串中每个字符的计数。如果这两个字符串是anagrams,那么结果就是所有的值都平衡到0。

直方图需要一个固定大小的计数表,其大小由字符集大小定义。例如,如果我们只使用一个字节来存储每个字符,那么我们可以使用256的计数数组来计数每个字符的出现次数:

随着O(n)时间复杂度的增加,该方法的求解速度更快。但是,它需要额外的空间用于计数数组。256个整数,对于ASCII来说还不错。

但是,如果我们需要增加CHARACTER_RANGE来支持多字节字符集,比如UTF-8,这将非常占用内存。因此,只有当可能的字符数在一个小范围内时,它才是真正实用的。

从开发的角度来看,这个解决方案包含了更多的代码需要维护,并且很少使用Java库函数。

5.用MultiSet来检查

利用MultiSet可以简化计算和比较过程。MultiSet是一个集合,它支持与重复元素无关的顺序相等。例如,多集{a,a,b}和{a,b,a}是相等的。

要使用Multiset,首先需要将番石榴依赖项添加到project pom.xml文件中:

我们将把每个输入字符串转换成多个字符集。然后我们会检查它们是否相等:

该算法在O(n)时间内解决了该问题,无需声明一个大的计数数组。

这与之前的计数方法类似。但是,我们没有使用固定大小的表来计数,而是利用MutlitSet类来模拟可变大小的表,每个字符都有一个计数。

此解决方案的代码比我们的计数解决方案更多地使用高级库功能。

6. 基于字母的Anagram

到目前为止,这些例子并没有严格遵循一个字谜的语言定义。这是因为他们认为标点符号是anagram的一部分,并且是区分大小写的。

让我们调整算法以启用基于字母的anagram。我们只考虑不区分大小写的字母的重新排列,而不考虑其他字符,如空格和标点符号。例如,“一个小数点”和“我是一个适当的点”是彼此之间的一个字谜。

为了解决这个问题,我们可以先对两个输入字符串进行预处理,过滤掉不需要的字符,然后将字母转换成小写字母。然后我们可以使用上面的一个解决方案(例如,MultiSet解决方案)来检查处理过的字符串上的anagram:

这种方法可以是一种通用的方法来解决所有的变型问题。例如,如果我们还想包含数字,我们只需要调整预处理过滤器。

7. 结论

在本文中,我们研究了三种算法来检查给定的字符串是否是另一个字符串的anagram,字符对字符。对于每个解决方案,我们讨论了速度、可读性和所需内存大小之间的权衡。

我们还研究了如何使算法适应更传统的语言意义上的语法检查。我们通过将输入预处理为小写字母来实现这一点。

与往常一样,本文的源代码可以在GitHub上找到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值