检查2个字符串是否包含相同的字符?

时间:2010-10-21 07:51:21

标签: java string string-comparison

有没有办法检查两个字符串是否包含相同的字符。例如,

abc, bca -> true
aaa, aaa -> true
aab, bba -> false
abc, def -> false

10 个答案:

答案 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)
     }
}