【问题标题】:How to ignore spaces while Sorting a string in java?如何在java中对字符串进行排序时忽略空格?
【发布时间】:2022-01-02 08:15:16
【问题描述】:

我尝试编写一个程序来检测一个给定 2 个字符串的字谜。 我的方法是将两个字符串都转换为 char 数组,然后在比较它们之前对它们进行排序。 我知道我可以使用 sort() 函数,但我不想将任何导入用于培训目的。

问题是我希望我的程序在扫描字谜时忽略空格。 在当前版本中,输出是这样的: (三角形,相关)--->真 (三角形,相关)--->错误

虽然它应该都是真的。

如果有任何帮助,我将不胜感激!

这是我的代码,(请忽略我的 cmets):

public static boolean anagramCheck(String a, String b) {
        boolean r = true;
        // In Char Arrays umwandeln /
        char[] Ca = a.toCharArray();
        char[] Cb = b.toCharArray();

        // Laengen Abfrage
        int L1 = Ca.length;
        int L2 = Cb.length;

        // Erste For-Schleife

        for (int i = 0; i < L1; i++) {
            for (int j = i + 1; j < L1; j++) {
                if (Ca[j] < Ca[i]) {
                    char temp = Ca[i];
                    Ca[i] = Ca[j];
                    Ca[j] = temp;
                }
            }
        }

        // Zweite For-schleife

        for (int i = 0; i < L2; i++) {
            for (int j = i + 1; j < L2; j++) {
                if (Cb[j] < Cb[i]) {
                    char temp = Cb[i];
                    Cb[i] = Cb[j];
                    Cb[j] = temp;
                }
            }
        }

        // Char Arrays zu Strings
        String S1 = String.valueOf(Ca);
        String S2 = String.valueOf(Cb);

        // Vergleich und Ausgabe

        if (S1.compareTo(S2) == 0) {
            return r;
        }

        else {
            r = false;
            return r;
        }

    }
}

【问题讨论】:

  • 在转换为数组之前去掉空格:char[] Ca = a.replaceAll("\\s", "").toCharArray();

标签: java arrays string loops sorting


【解决方案1】:

可以使用 String one 中的字符递增和 String two 中的字符递减来创建频率图,然后生成的映射应仅包含 0 作为值。

要跳过非字母,可以使用Character::isLetter

public static boolean isAnagram(String a, String b) {
    Map<Character, Integer> frequencies = new HashMap<>();
    for (int i = 0, na = a.length(), nb = b.length(), n = Math.max(na, nb); i < n; i++) {
        if (i < na && Character.isLetter(a.charAt(i)))
            frequencies.merge(Character.toLowerCase(a.charAt(i)),  1, Integer::sum);

        if (i < nb && Character.isLetter(b.charAt(i)))
            frequencies.merge(Character.toLowerCase(b.charAt(i)), -1, Integer::sum);
    }
    return frequencies.values().stream().allMatch(x -> x == 0);
}

【讨论】:

    【解决方案2】:

    通常,代码越少越好(如果可读的话)。学习一门语言意味着学习内置库。

    这是一个返回排序字符字符串的方法:

    public static String sortChars(String str) {
        return str.replace(" ", "").chars().sorted()
          .mapToObj(c -> (char)c + "")
          .collect(Collectors.joining(""));
    }
    

    有了这个方法,你的主要方法就变成了:

    public static boolean anagramCheck(String a, String b) {
        return sortedChars(a).equals(sortedChars(b));
    }
    

    Refactoring 像这样,使用有名的方法让你的代码更容易理解、测试、调试和维护。


    值得注意的是,您实际上并不需要排序的 String……排序的 array 也同样适用,并且需要更少的代码:

    public static int[] sortChars(String str) { return str.replace(" ", "").chars().sorted().toArray(); }

    public static boolean anagramCheck(String a, String b) {
        return Arrays.equal(sortedChars(a), sortedChars(b));
    }
    

    【讨论】:

      【解决方案3】:
      public static boolean isAnagram(String one, String two) {
          char[] letters = new char[26];
      
          for (int i = 0; i < one.length(); i++) {
              char ch = Character.toLowerCase(one.charAt(i));
      
              if (Character.isLetter(ch))
                  letters[ch - 'a']++;
          }
      
          for (int i = 0; i < two.length(); i++) {
              char ch = Character.toLowerCase(two.charAt(i));
      
              if (Character.isLetter(ch))
                  letters[ch - 'a']--;
          }
      
          for (int i = 0; i < letters.length; i++)
              if (letters[i] != 0)
                  return false;
      
          return true;
      }
      

      【讨论】:

        【解决方案4】:

        String.replace(String, String) 是非正则表达式替换方法。 所以删除所有空格:

            String S1 = String.valueOf(Ca).replace(" ", "");
            String S2 = String.valueOf(Cb).replace(" ", "");
        

        ab 上执行此操作会更好。

        【讨论】:

        • 我认为不需要创建一个新的String,如果没有它我们可以做到。
        • @oleg.cherednik 在他的代码中确实 S1 和 S2 用于 compareTo,我发现字符串的使用还不错:Unicode 字母、西里尔字母、Locale toUpperCase(德语 ß 变为 SS,土耳其语 i-带/不带点)。我只是赞成您的回答,尽管Map&lt;Integer, Integer&gt; 和使用 code points 会更好(在理想世界中)。我使用了 OP 的 代码。
        猜你喜欢
        • 2017-04-07
        • 1970-01-01
        • 2015-08-02
        • 2020-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-17
        • 1970-01-01
        相关资源
        最近更新 更多