0

下面是我编写的代码,用于将所有字谜放在一组字符串中。输出没有按预期排序。实际上,输出与输入相同。我哪里错了?

package set2;

import java.util.Arrays;
import java.util.Comparator;

public class printAllAnagrams {
    public static void main(String[] args) {
        String[] s = { "Harsha", "ant", "sha", "tna", "ash" };
        sortAnagrams(s);
        for (String e : s) {
            System.out.println(e);
        }
    }

    private static void sortAnagrams(String[] s) {
        Arrays.sort(s, new Comparator<String>() {

            @Override
            public int compare(String s1, String s2) {
                s1.toLowerCase();
                s2.toLowerCase();

                if (s1.length() != s2.length()) {
                    return -1;
                } else {
                    char[] s1_char = s1.toCharArray();
                    char[] s2_char = s2.toCharArray();
                    Arrays.sort(s1_char);
                    Arrays.sort(s2_char);

                    for (int i = 0; i < s1_char.length; i++) {
                        if (s1_char[i] != s2_char[i]) {
                            return -1;
                        }
                    }
                }
                return 0;
            }

        });

    }
}
4

6 回答 6

0

不用仔细看,这

 s1.toLowerCase();

不会改变s1,而是返回一个字符串,它是 . 的小写变体s1。在 Java 中,字符串是不可变的。因此,您需要收集并使用从上面返回的值。

于 2013-03-20T15:40:50.780 回答
0

这不一定是正确的:

if (s1.length() != s2.length()) {
    return -1;
}

这将意味着如果s1.length() != s2.length() s1 < s2 s2 < s1

我认为你的意思是:

public int compare(String s1, String s2) {
    if (s1.length() == s2.length()) {                   
        char[] s1_char = s1.toLowerCase().toCharArray();
        char[] s2_char = s2.toLowerCase().toCharArray();
        Arrays.sort(s1_char);
        Arrays.sort(s2_char);

        for (int i = 0; i < s1_char.length; i++) {
            if (s1_char[i] != s2_char[i]) {
                return (int)(s1_char[i] - s2_char[i]);
            }
        }
        return 0;
    } else {
        return s1.length() - s2.length();
    }
}
于 2013-03-20T15:41:26.530 回答
0

你为什么不做以下事情:

        @Override
        public int compare(String s1, String s2) {
            return s1.toLowerCase().compareTo(s2.toLowerCase());
        }
于 2013-03-20T15:41:57.543 回答
0

您的比较器根本不稳定。

首先你return -1如果长度不同。这意味着根据操作数顺序,您可能会发现“asbd”>“ash”或相反。

你也对 char 比较做同样的事情。

if (s1_char[i] != s2_char[i]) {
   return -1;
}

将其替换为:

if (s1_char[i] != s2_char[i]) {
  return s1_char[i] > s2_char[i] ? 1 : -1;
}

使用相同的模式进行长度比较。

编辑compare方法返回 -1 意味着您发现第一个操作数小于文档中的第二个操作数。

于 2013-03-20T15:42:48.697 回答
0

字符串是不可变的,因此仅在对象上调用方法String不会改变其String本身。您应该使用以下内容:

s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
于 2013-03-20T15:44:38.450 回答
0

javadoc

实施者必须确保sgn(compare(x,y)) == -sgn(compare(y,x))所有xy. (这意味着compare(x,y)当且仅当compare(y,x)抛出异常时必须抛出异常。)。

这基本上意味着如果您调用compare(s1,s2)它必须产生 -1 *compare(s2,s1)并且您的任何return -1;陈述都不会遵循这一点。取而代之的是,您可以将整数和字符相互比较并返回该值,例如此代码有效(而不是return -1;):

return Integer.compare(s1.length(),s2.length()); //for the ints

return Character.compare(s1_char[i],s2_char[i]); //for the chars

另请查看 Vishal 的答案,这是另一个错误。

于 2013-03-20T15:49:02.690 回答