我的问题是,我有2个字符串,说String1 & String2。现在我想检查这两个字符串是否包含相同的字符,而不管它们的顺序如何。如何比较包含相同字符的2个字符串
假设String1= "qwerty"
,String2= "qywter"
。现在这些字符串包含相同的字符,但顺序不同。那么是否有任何函数可以用来表明这些字符串包含相同的字符?可以equals()方法做到这一点?
所有帮助表示赞赏。
我的问题是,我有2个字符串,说String1 & String2。现在我想检查这两个字符串是否包含相同的字符,而不管它们的顺序如何。如何比较包含相同字符的2个字符串
假设String1= "qwerty"
,String2= "qywter"
。现在这些字符串包含相同的字符,但顺序不同。那么是否有任何函数可以用来表明这些字符串包含相同的字符?可以equals()方法做到这一点?
所有帮助表示赞赏。
char[] chars1 = string1.toCharArray();
char[] chars2 = string2.toCharArray();
Arrays.sort(chars1);
Arrays.sort(chars2);
return Arrays.equals(chars1, chars2);
您可以使用String.equals
,尽管是间接的。首先,你需要一个辅助方法:
// given a String, sorts its chars and return it as another String
public static String sorted(String s) {
char[] arr = s.toCharArray();
Arrays.sort(arr);
return new String(arr);
}
然后,你可以有:
String s1 = "qwerty";
String s2 = "qywter";
System.out.println(sorted(s1)); // eqrtwy
System.out.println(sorted(s1).equals(sorted(s2))); // true
注意,这不是最有效的算法 - 这是O(N log N)
时间,并利用多余的空间 - 但应该工作罚款的短弦。对于长字符串,您希望手动通过每个char
(或Unicode代码点)(而不是toCharArray()
),并且可能使用线性时间counting sort。
如果你不关心具体的字符数匹配(例如"xxxyyy"
和"xy"
具有相同的字符,尽管在不同的数字),那么你可以使用一组类似的表示(java.util.BitSet
)。
// given a string, returns its used char set as a java.util.BitSet
public static BitSet usedChar(String s) {
BitSet bs = new BitSet();
for (int i = 0; i < s.length(); i++) {
bs.set(s.charAt(i));
}
return bs;
}
然后,你可以有:
System.out.println(
usedChar("xxxyyy").equals(usedChar("xy"))
); // true
System.out.println(
usedChar("xyz").equals(usedChar("abc"))
); // false
这取决于你是否真的想要的字符或你真的想码点,然后它的事项是否要算重复与否。这里有一个解决方案:
public class a {
public static void main(String[] args) {
String s1 = "qwerty";
String s2= "qywter";
System.out.println(codePointSet(s1).equals(codePointSet(s2)));
}
public static Set<Integer> codePointSet(String s) {
Set<Integer> set = new TreeSet<Integer>();
for (int i = 0, cp; i < s.length(); i += Character.charCount(i)) {
cp = s.codePointAt(i);
set.add(cp);
}
return set;
}
}
String.equals()
将不适用于您的特定情况。您可能需要编写自己的方法来以这种方式来对字符串进行等同处理。
int[] f = new int[(int)char.MaxValue];
foreach (var c in string1) f[(int)c]++;
foreach (var c in string2) f[(int)c]--;
return f.Max() == 0 && f.Min() == 0;
当string1.length()>> char.MaxValue和它具有较低的大O符号复杂度时,这是更好的解决方案。
编辑这实际上是C#代码,但您可以很容易地在Java
中实现类似的结果。
有趣的方法,但肯定不是Java。 – 2010-08-23 18:33:13
如果您有需要比较长的字符串,你并不需要成功的保证,你可以做这样的事情:
其实我花了一些时间试图弄清楚哪里不行,但我想不出一个。我的直觉告诉我,我在这里错过了一些东西,或者这是一个很好的比较器。
两个步骤需要
做两个字符串的异或,如果XOR为0,那么你肯定部分。
如果xor为0,则找到两个字符串的ascii值的总和,如果ascii总和相同,则 这两个字符串都是相同的。
希望这有助于
应的结果是在什么情况下,他们有相同的字符,但不相同的字符数? (如“qwerty”和“qywtery”?)它们包含相同的字符,但不包含相同数量的字符。 – MikeTheReader 2010-08-23 18:29:26