有没有办法检查两个字符串是否包含相同的字符。例如,
abc, bca -> true
aaa, aaa -> true
aab, bba -> false
abc, def -> false
答案 0 :(得分:22)
将每个字符串转换为char [],对该数组进行排序,然后比较两者。简单。
private boolean sameChars(String firstStr, String secondStr) {
char[] first = firstStr.toCharArray();
char[] second = secondStr.toCharArray();
Arrays.sort(first);
Arrays.sort(second);
return Arrays.equals(first, second);
}
答案 1 :(得分:6)
一种非常简单但不是非常有效的方法是,将String
转换为char数组并在其上使用java.util.Arrays.sort,将String
恢复为比较平等。
如果你的字符串少于几千个字符,那应该是非常好的。
如果你有几兆字节的字符串,你可能想创建一个数字,每个字符都有一个计数(使用它的代码作为索引),在一个字符串上有一个传递,在每个字符的计数上加一个,一个传递在第二个字符串删除一个。如果您在第二次传球期间的任何时间点都低于0,则它们没有相同的字符。当您完成第二个字符串而没有错误时,如果它们具有相同的长度(您应该首先检查它),您确定它们具有相同的字符。
第二种方法比排序字符串复杂得多,如果你想使用unicode字符串,它需要一个大数组,但如果你只使用ascii集的128个字符,那就非常好了,而且速度要快得多。
如果您的字符串中没有数百万个字符,请不要理会。对字符串进行排序要容易得多,而且对于只有几十个字符的字符串来说并不会明显变慢。
答案 2 :(得分:3)
作为(挑剔;-))旁注:
请注意,此处提出的解决方案仅适用于由Unicode的Basic Multilingual Plane(BMP)字符组成的字符串。
BMP之外的字符在char
中表示为String
的对,因此您需要特别注意,因此请将这些对保持在一起。有关详细信息,请参阅java.lang.Character
的Javadocs。
幸运的是,BMP以外的大多数角色都很奇特。甚至大多数日本人和中国人都在BMP中......
答案 3 :(得分:3)
也许这不是最快的答案,但它必须是最短的答案。
boolean hasSameChar(String str1, String str2){
for(char c : str1.toCharArray()){
if(str2.indexOf(c) < 0 ) return false;
}
for(char c : str2.toCharArray()){
if(str1.indexOf(c) < 0 ) return false;
}
return true;
}
答案 4 :(得分:1)
您可以将字符串转换为char数组,对数组进行排序,然后比较数组:
String str1 = "abc";
String str2 = "acb";
char[] chars1 = str1.toCharArray();
char[] chars2 = str2.toCharArray();
Arrays.sort(chars1);
Arrays.sort(chars2);
if(Arrays.equals(chars1,chars2)) {
System.out.println(str1 + " and " + str2 + " are anagrams");
} else {
System.out.println(str1 + " and " + str2 + " are not anagrams");
}
答案 5 :(得分:1)
考虑为给定的String创建签名。使用计数和字符。
a-count:b-count:c-count:.....:z-count:
(如果需要,可以扩展为大写)。
然后比较签名。对于非常大的字符串,这应该更好地扩展。
作为捷径,检查长度。如果它们不匹配,则无论如何都要返回false。
答案 6 :(得分:0)
这里:
String str1 = "abc";
String str2 = "cba";
/* create sorted strings */
/* old buggy code
String sorted_str1 = new String( java.utils.Arrays.sort(str1.toCharArray()) );
String sorted_str2 = new String( java.utils.Arrays.sort(str2.toCharArray()) );
*/
/* the new one */
char [] arr1 = str1.toCharArray();
char [] arr2 = str2.toCharArray();
java.utils.Arrays.sort(arr1);
java.utils.Arrays.sort(arr2);
String sorted_str1 = new String(arr1);
String sorted_str2 = new String(arr2);
if (sorted_str1.equals( sorted_str2 ) ) {
/* true */
} else {
/* false */
}
答案 7 :(得分:0)
下面:
import java.util.Arrays;
public class CompareString {
String str = "Result";
String str1 = "Struel";
public void compare() {
char[] firstString = str.toLowerCase().toCharArray();
char[] secondString = str1.toLowerCase().toCharArray();
Arrays.sort(firstString);
Arrays.sort(secondString);
if (Arrays.equals(firstString, secondString) == true) {
System.out.println("Both the string contain same charecter");
} else {
System.out.println("Both the string contains different charecter");
}
}
public static void main(String[] args) {
CompareString compareString = new CompareString();
compareString.compare();
}
}
答案 8 :(得分:0)
这个问题可以在O(n)时间和O(1)空间中简单地解决。我们的想法是使用大小为26的临时数组,因为字母表中只有26个字符。
首先,如果两个字符串的长度不同,我们将立即返回false。 我们遍历给定字符串的长度并在temp数组中进行迭代,增加一个字符串中每个字符的频率,减少另一个字符串中出现的字符数。最后,如果字符串具有相等的字符,则temp数组的每个字符应为0。
答案 9 :(得分:0)
同意上述@Jean所说的使用HashMap的有效解决方案。 此问题也称为Anagram。 下面是Scala中的解决方案。
注意:cleanString是删除空格且所有字符均小写的地方
def isAnagram(cleanString1, cleanString2) = {
createHashMap(cleanString1) == createHashMap(cleanString2)
}
def createHashMap(str: String): immutable.HashMap[Char, Int] = {
str.foldLeft(immutable.HashMap.empty[Char, Int]) { (acc, next)
=> if (acc.contains(next)) acc + (next -> (acc(next) + 1))
else acc + (next -> 1)
}
}