13

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

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

12 回答 12

27

将每个字符串转换为 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);
}
于 2010-10-21T07:54:09.587 回答
8

一种非常简单(但不是很有效)的方法是将Strings 转换为 char 数组并在它们上使用 java.util.Arrays.sort ,获取Strings 并比较是否相等。如果您的字符串少于几千个字符,那应该没问题。

如果您有几兆字节的字符串,您可能希望创建一个数组,每个字符都有一个计数(使用其代码作为索引),对一个字符串进行一次传递,在每个字符的计数上加一个,然后在第二个传递字符串删除一个。如果您在第二遍中的任何时候都低于 0,则它们没有相同的字符。当您没有错误地完成第二个字符串时,如果它们具有相同的长度(无论如何您应该首先检查),您可以确定它们具有相同的字符。
第二种方法比对字符串进行排序要复杂得多,如果你想使用 unicode 字符串,它需要一个大数组,但如果你只使用 ascii 集的 128 个字符就可以了,而且速度更快。
如果您的字符串中没有几百万个字符,请不要为此烦恼。对字符串进行排序要容易得多,并且在只有几十个字符的字符串上不会明显变慢。

于 2010-10-21T08:01:46.073 回答
3

作为(挑剔;-))旁注:

请注意,此处提出的解决方案仅适用于由 Unicode基本多语言平面(BMP) 中的字符组成的字符串。

BMP 之外的字符表示为 a中的一,因此您需要特别注意,因此将这些对放在一起。有关血腥细节,请参阅的 Javadocs 。charStringjava.lang.Character

幸运的是,BMP 之外的大多数字符都相当奇特。甚至大部分日文和中文都在BMP中......

于 2010-10-21T08:03:37.490 回答
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;
}
于 2010-10-21T08:58:10.463 回答
2

考虑为给定的字符串创建签名。使用计数和字符。

a-count:b-count:c-count:.....:z-count:(如果需要,可以扩展为大写)。

然后比较签名。对于非常大的字符串,这应该可以更好地扩展。

作为快捷方式,请检查长度。如果它们不匹配,则无论如何都返回 false。

于 2010-10-21T08:49:53.383 回答
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");
}
于 2010-10-21T07:54:45.013 回答
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 */
    }
于 2010-10-21T07:59:06.953 回答
0

这里:

import java.util.Arrays;

公共类比较字符串 {

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();
}

}

于 2013-08-13T20:45:23.080 回答
0
public static boolean isSameLetters(String word1, String word2){
    String s1 = Arrays.stream(word1.trim().strip().replaceAll("\\s","").split("")).sorted().collect(Collectors.joining());
    String s2 = Arrays.stream(word2.trim().strip().replaceAll("\\s","").split("")).sorted().collect(Collectors.joining());
    System.out.printf("word 1: %s\nword 2: %s\n",s1,s2);
    return s1.equals(s2);
}
于 2022-01-09T15:24:14.677 回答
0

这个问题可以在 O(n) 时间和 O(1) 空间内简单地解决。我们的想法是使用大小为 26 的临时数组,因为我们在字母表中只有 26 个字符。

首先,如果两个字符串的长度不同,我们立即返回 false。我们迭代给定字符串的长度和临时数组,增加字符串 1 中每个字符的频率并减少其他字符串中出现的字符数。如果字符串具有相同的字符,则最后临时数组的每个字符的计数应为 0。

于 2020-08-22T16:30:42.323 回答
0

同意@Jean 上面所说的使用 HashMap 的有效解决方案。这个问题也称为字谜。以下是 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)
     }
}
于 2020-09-21T19:27:24.217 回答
0

//C++

#include<bits/stdc++.h>
using namespace std;

string cmpstr(string &s1,string &s2){

map<int,int>m1;
map<int,int>m2;

for(auto &c:s1)m1[c]++;
for(auto &c:s2)m2[c]++;

return m1==m2?"true":"false";


}
int main(){
    string s1,s2;
    cin>>s1>>s2;
    cout<<cmpstr(s1,s2);
    return 0;
}
于 2022-01-30T14:10:27.543 回答