【问题标题】:How to determine if two strings are permutable in java?如何确定两个字符串在java中是否可置换?
【发布时间】:2021-09-29 06:09:32
【问题描述】:

我正在尝试确定两个字符串是否是彼此的排列。当我输入以下字符串(见下面的代码)时,程序应该打印出这两个字符串是可置换的。但是,这不是我可以在屏幕上看到的声明。谁能帮我?这是我的代码:

public static void main(String[] args) {
    String str1 = "abcrdt";
    String str2 = "barcdt";
    char[] arr1 = str1.toCharArray();
    Arrays.sort(arr1);
    char[] arr2 = str2.toCharArray();
    Arrays.sort(arr2);
    if (isPermutation(arr1, arr2)) {
        System.out.print("The strings are permutable.");
    } else {
        System.out.print("The strings are not permutable.");
    }
}

static boolean isPermutation(char[] arr1, char[] arr2) {
    if (arr1.length != arr2.length) {
        return false;
    }
    for (int i = 0; i <= arr1.length; i++) {
        for (int j = 0; j <= arr2.length; j++) {
            if (arr1[i] != arr2[j]) {
                return false;
            }
        }
    }
    return true;
}

【问题讨论】:

    标签: java loops if-statement boolean permutation


    【解决方案1】:

    您在 for 循环中实现的逻辑引发了该错误。您正在使用嵌套循环,在其中检查 arr1 的每个索引,如果 char 与 arr2 中的任何字符不匹配,则返回 false。

    例如,如果arr1 中的第一个字符是a,则您正在检查它是否与arr2 中的任何字符不匹配。这就是为什么你会被重新调整为假。

    此外,即使您的逻辑在循环内没有问题,您仍然会得到一个 ArrayIndexOutOfBoundException,因为您正在从索引 0 迭代到包括 arr.length 在内的索引,其中零索引数组具有有效索引到arr.length-1

    要解决这个问题,您可以简单地检查它们从排序数组中构造的字符串是否相同:

    public static void main(final String[] args) {
        final String str1 = "abcrdt";
        final String str2 = "barcdt";
        if (isPermutation(str1.toCharArray(), str2.toCharArray())) {
            System.out.print("The strings are permutable.");
        } else {
            System.out.print("The strings are not permutable.");
        }
    }
    
    static boolean isPermutation(final char[] str1, final char[] str2) {
        Arrays.sort(str1);
        Arrays.sort(str2);
        return new String(str1).equals(new String(str2));
    }
    

    同样,如果您省略 isPermutation 并直接检查 if 条件,您可以使这段代码更简洁:

    public static void main(final String[] args) {
        final String str1 = "abcrdt";
        final String str2 = "barcdt";
        char[] arr1 = str1.toCharArray();
        Arrays.sort(arr1);
        char[] arr2 = str2.toCharArray();
        Arrays.sort(arr2);
        if (new String(arr1).equals(new String(arr2))) {
            System.out.print("The strings are permutable.");
        } else {
            System.out.print("The strings are not permutable.");
        }
    }
    

    【讨论】:

      【解决方案2】:

      正如@chrylis-cautiouslyoptimistic- 已经暗示了这个问题,但这并没有解决,这里是解决方案:

      您对问题的思考太深,导致解决方案过于复杂。

      看看这个,它工作得很好,而且更容易:

      import java.util.Arrays;
      
      public class Permutat0r {
      
          public static void main(final String[] args) {
              final String str1 = "abcrdt";
              final String str2 = "barcdt";
              final char[] arr1 = str1.toCharArray();
              Arrays.sort(arr1);
              final char[] arr2 = str2.toCharArray();
              Arrays.sort(arr2);
              if (isPermutation(arr1, arr2)) {
                  System.out.print("The strings are permutable.");
              } else {
                  System.out.print("The strings are not permutable.");
              }
          }
      
          static boolean isPermutation(final char[] arr1, final char[] arr2) {
              System.out.println("CA1");
              for (final char c : arr1) {
                  System.out.println("\t" + c);
              }
              System.out.println("CA2");
              for (final char c : arr2) {
                  System.out.println("\t" + c);
              }
      
              if (arr1.length != arr2.length) {
                  return false;
              }
              for (int i = 0; i < arr1.length; i++) {
                  if (arr1[i] != arr2[i]) {
                      return false;
                  }
              }
              return true;
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        要检查两个字符串是否可置换,即一个字谜,您必须比较这些字符串的两个 排序 字符数组。为此,从 Java 9 开始,您可以使用 String#codePoints 方法。此代码适用于常规字符和代理项对。

        public static void main(String[] args) {
            // regular characters & surrogate pairs
            System.out.println(checkIfAnagram("twowords", "dortwswo")); // true
            System.out.println(checkIfAnagram("??????", "??????")); // true
        }
        
        /**
         * @param str1 the first string
         * @param str2 the second string
         * @return whether two strings are an anagram
         */
        public static boolean checkIfAnagram(String str1, String str2) {
            // check if the input strings are not null
            if (str1 == null || str2 == null) return false;
            // sorted arrays of code points of input strings
            int[] arr1 = str1.codePoints().sorted().toArray();
            int[] arr2 = str2.codePoints().sorted().toArray();
            // check if two sorted arrays are equal
            return Arrays.equals(arr1, arr2);
        }
        

        不使用流,您可以分别调用String#toCharArray()Arrays.sort() 方法。结果是一样的,但是代码多了一点。这足以检查两个数组的相等性,但是在这种情况下,代理对在排序后会被分开,这样的数组无法恢复为字符串。

        public static boolean checkIfAnagram(String str1, String str2) {
            // check if the input strings are not null
            if (str1 == null || str2 == null) return false;
            // arrays of characters of input strings
            char[] arr1 = str1.toCharArray();
            char[] arr2 = str2.toCharArray();
            // sorting arrays, surrogate pairs will be separated
            Arrays.sort(arr1);
            Arrays.sort(arr2);
            // check if two sorted arrays are equal
            return Arrays.equals(arr1, arr2);
        }
        

        另见:How can I check if two strings are anagrams?

        【讨论】:

          猜你喜欢
          • 2019-08-21
          • 2022-12-03
          • 2011-04-25
          • 1970-01-01
          • 1970-01-01
          • 2011-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多