Java 中的字符串变位词

String anagram in Java

我正在尝试为满足以下条件的字符串变位词创建程序:

  1. 方法应该只允许字母、白色 space、逗号和点在变位词中。如果有任何其他字符,则该字符串不能包含变位词。
  2. 该方法在检查文本时应忽略所有白色 space、逗号和点。
  3. 如果文本中没有字母,则文本不能是字谜。
import java.util.Arrays;
import java.util.Scanner;

public class StringAnagram {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        System.out.print("Enter first string: ");
        String first = in.nextLine().toUpperCase();


        System.out.print("Enter second string: ");
        String second = in.nextLine().toUpperCase();

        String result = isAnagram(first, second);
        System.out.println(result);
    }

private static String isAnagram(String first, String second) {
    String answer = "";


    if (first.matches("[A-Z\.\,\s]")) {
        String st = first.replaceAll("\.\,\s", "");
        String nd = second.replaceAll("\.\,\s", "");
        char[] arraySt = st.toCharArray();
        char[] arrayNd = nd.toCharArray();
        Arrays.sort(arraySt);   
        Arrays.sort(arrayNd);

            if(Arrays.equals(arraySt, arrayNd)) {
                answer = "Anagram.";
            }

            else {
                answer = "No anagram.";
            }
        }

    else  {
        answer = "No anagram.";
    }
    return answer;
}
}

但是当程序测试这两个句子时,它们不是变位词但应该是变位词。我不知道在哪里寻找错误。

  1. 十一加二等于十三。
  2. 十二加一等于十三。

这:first.matches("[A-Z\.\,\s]") 测试 first 值是否为 单个字符 ,即 1 个大写字母、点或逗号,或任何空白字符。

完全不是你想要的

您可以在各处添加 System.out.println 语句来打印您的代码所在的位置以及相关变量的值。就像您是计算机一样遵循代码。你认为应该发生的地方与 sysout 语句告诉你的不匹配——那里有一个错误(可能有很多,特别是如果你在没有先测试任何东西的情况下写了这么多东西)。

更好的是,使用调试器。

注意:将您的 No anagram. 字符串中的一个替换为任何其他内容这样微不足道的事情只是为了让您知道触发了两个字符串中的哪一个已经有很大帮助了。

注意:first.replaceAll("\.\,\s", ""); 也坏了;你在这里写了太多代码;测试每个单独的移动件。这就像一辆自行车,当你把它组装起来后什么也做不了:一块一块地拆开,单独测试每一块。

如果您按如下方式启动您的方法,它将完成您问题的 1st3rd 点中提到的验证:

if (first == null || second == null || first.equals("") || second.equals("") || !first.matches("[A-Za-z,. ]+")
        || !second.matches("[A-Za-z,. ]+")) {
    return "No anagram.";
}

接下来您应该做的是将所有白色 space、逗号和点替换为 "" 以忽略它们:

String st = first.replaceAll("[,. ]+", "");
String nd = second.replaceAll("[,. ]+", "");

完整代码如下:

private static String isAnagram(String first, String second) {
    if (first == null || second == null || first.equals("") || second.equals("") || !first.matches("[A-Za-z,. ]+")
            || !second.matches("[A-Za-z,. ]+")) {
        return "No anagram.";
    }
    String answer = "";

    String st = first.replaceAll("[,. ]+", "");
    String nd = second.replaceAll("[,. ]+", "");

    if (st.equals("") || nd.equals("")) {
        return "No anagram.";
    }

    char[] arraySt = st.toCharArray();
    char[] arrayNd = nd.toCharArray();
    Arrays.sort(arraySt);
    Arrays.sort(arrayNd);

    if (Arrays.equals(arraySt, arrayNd)) {
        answer = "Anagram.";
    } else {
        answer = "No anagram.";
    }
    return answer;
}

测试运行:

Enter first string: london
Enter second string: britain
No anagram.

另一个测试运行:

Enter first string: ram
Enter second string: mar
Anagram.

另一个测试运行:

Enter first string: .
Enter second string: .
No anagram.

另一个测试运行:

Enter first string: ,
Enter second string: .
No anagram.

另一个测试运行:

Enter first string: ra.m
Enter second string: a.m.r
Anagram.

此解决方案接受来自控制台输入的字符串。该部分被省略,因为它对您有用。

我们的想法是有选择地将您所比较的内容的本质减少到最低限度。提供评论来解释逻辑。在示例中,除第三个以外的所有示例都报告为变位词。

        System.out.println(isAnagram("radar", "darar"));
        System.out.println(isAnagram("ra.,. dar", "d.,a  rar"));
        System.out.println(isAnagram("r+a.,. dar", "d.,a + rar"));
        System.out.println(isAnagram("Eleven plus two is thirteen.", "Twelve plus one is thirteen."));

   // This method accepts mixed case strings.  The conversion to upper case is
   // done within the method.   
    public static String isAnagram(String first, String second) {  

        // get rid of allowed characters and convert to upper case 
        String st = first.replaceAll("[., ]","").toUpperCase();
        String nd = second.replaceAll("[., ]","").toUpperCase();

        // Now get rid of all alpha characters and compare to the empty string.
        // Only if both are equal are the strings potential anagrams.  
        // Otherwise, the illegal characters would be present.
        if (st.replaceAll("[A-Z]","").equals("") &&
                nd.replaceAll("[A-Z]","").equals("")) {

             // this is your original code
             char[] arraySt = st.toCharArray();
             char[] arrayNd = nd.toCharArray();
             Arrays.sort(arraySt);   
             Arrays.sort(arrayNd);

             // don't set a value just return it's an
             // anagram
             if (Arrays.equals(arraySt, arrayNd)) {
                     return "Anagram.";
             } 
        }
        // Otherwise, it's not
        return "No Anagram.";
   }