java 判断字符串中是否包含某个字符_如何判断Java中String字符是否为Anagrams实现...

v2-31dc3fd65853f79d8290d02e02e792c4_1440w.jpg?source=172ae18b

1.概述

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

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

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

2.解决方案

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

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

v2-26c3dc05a19e0268410fbee62914ef54_b.jpg

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

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

4.计数检查

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

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

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

v2-befb56e9a73466bc8cc139f2fecca9cd_b.jpg

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

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

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

5.用MultiSet来检查

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

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

v2-464fe965b1de8d1bb0e09b7db702b928_b.jpg

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

v2-f50b8ed1953f7f2315b1da4822e913ce_b.jpg

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

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

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

6. 基于字母的Anagram

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

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

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

v2-0dfb0f5ed6c395f9665fff72ef34d618_b.jpg

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

7. 结论

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

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

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

在 C 语言判断两个字符串是否是由相同字符重新排列得到的,通常需要通过哈希表(如数组或链表)或者排序的方式来实现。以下是两种常见的方法: **方法一:利用哈希表(频率统计)** 1. 首先,对第一个字符串的每个字符计数,存储在一个数组或 map 。 2. 然后遍历第二个字符串,同样计数并更新频率。 3. 最后,比较两个字符串字符频率数组。如果它们包含相同的字符并且对应的频率相等,则说明两个字符串可以由相同的字符重新排列。 ```c #include <stdio.h> #include <stdbool.h> bool is_anagram(char* str1, char* str2) { int freq[256] = {0}; // 假设 ASCII 编码,只考虑小写字母和空格 int i; for (i = 0; str1[i]; i++) { freq[str1[i]]++; } for (i = 0; str2[i]; i++) { freq[str2[i]]--; if (freq[str2[i]] < 0) return false; // 字符在 str2 出现过多 } // 如果所有字符都检查完毕且没有剩余非零频率,表示是 anagram return !any_non_zero(freq); } // 辅助函数检查数组是否有非零元素 int any_non_zero(int arr[]) { for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (arr[i]) return true; } return false; } ``` **方法二:排序字符串** 1. 分别将两个字符串转换成字符数组,并排序。 2. 比较两个排序后的数组是否相等。 ```c #include <stdio.h> #include <string.h> bool are_anagrams(char* str1, char* str2) { // 对字符串进行排序 char sorted_str1[strlen(str1) + 1], sorted_str2[strlen(str2) + 1]; strcpy(sorted_str1, str1); strcpy(sorted_str2, str2); qsort(sorted_str1, strlen(sorted_str1), sizeof(char), compare_chars); qsort(sorted_str2, strlen(sorted_str2), sizeof(char), compare_chars); // 检查排序后的字符串是否相等 return strcmp(sorted_str1, sorted_str2) == 0; } int compare_chars(const void *a, const void *b) { return (*(char*)a - *(char*)b); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值