【问题标题】:Anagrams - how can I pass the below two test cases字谜 - 我怎样才能通过以下两个测试用例
【发布时间】:2019-03-11 13:35:14
【问题描述】:

这是我的代码,用于判断两个字符串是否为字谜

static boolean isAnagram(String a, String b) {
    if (a.length() != b.length()) return false;
    a = a.toLowerCase();
    b = b.toLowerCase();
    int m1=0;
    for(int i=0;i<a.length();i++){
        m1 += (int)a.charAt(i);
        m1 -= (int)b.charAt(i);

    }
        return m1==0;
}

我的代码在两个测试用例中都失败了

  • 案例1:String a="xyzw";String b="xyxy";
  • 案例 2:String a="bbcc";String b="dabc";

谁能帮我通过以上两种情况?

【问题讨论】:

  • 我相信你的代码是正确的。因为 xyxy 不是 xyzw 的字谜。字谜意味着使用一个单词中的相同字母,可以创建一个不同的单词。示例:pottop
  • 代码在某些特殊情况下不正确,因为您只考虑字符串中字符中 asci 值的总和。但有时不同的字符可以给出相同的 asci 值。例如 jl=214 和 nh=214 但这些不是字谜

标签: java string char anagram


【解决方案1】:

我认为您的代码不起作用,因为您总结了字符代码,但答案可能为零,但它们不相等,例如:“ad”“bc”
更好的方法是对字符串的字符进行排序,如果它们具有相同的数组长度和相同的顺序,那么两个字符串是字谜。

static boolean isAnagram(String str1, String str2) {
    int[] str1Chars = str1.toLowerCase().chars().sorted().toArray();
    int[] str2Chars = str2.toLowerCase().chars().sorted().toArray();
    return Arrays.equals(str1Chars, str2Chars);
}

希望对您有所帮助。 (这有点难,因为我使用流来创建和排序字符数组)

【讨论】:

  • 是的,我想我仍然不会在流中“思考”,所以错过了这一部分。
  • 如果您的问题解决了,请采纳答案,让其他人知道问题解决了!!! :)
【解决方案2】:

试试这个:

import java.io.*; 

class GFG{ 

    /* function to check whether two strings are  
    anagram of each other */
    static boolean areAnagram(char[] str1, char[] str2) 
    { 
        // Get lenghts of both strings 
        int n1 = str1.length; 
        int n2 = str2.length; 

        // If length of both strings is not same, 
        // then they cannot be anagram 
        if (n1 != n2) 
            return false; 

        // Sort both strings 
        quickSort(str1, 0, n1 - 1); 
        quickSort(str2, 0, n2 - 1); 

        // Compare sorted strings 
        for (int i = 0; i < n1;  i++) 
            if (str1[i] != str2[i]) 
                return false; 

        return true; 
    } 

    // Following functions (exchange and partition  
    // are needed for quickSort) 
    static void exchange(char A[],int a, int b) 
    { 
        char temp; 
        temp = A[a]; 
        A[a]   = A[b]; 
        A[b]   = temp; 
    } 

    static int partition(char A[], int si, int ei) 
    { 
        char x = A[ei]; 
        int i = (si - 1); 
        int j; 

        for (j = si; j <= ei - 1; j++) 
        { 
            if(A[j] <= x) 
            { 
                i++; 
                exchange(A, i, j); 
            } 
        } 
        exchange (A, i+1 , ei); 
        return (i + 1); 
    } 

    /* Implementation of Quick Sort 
    A[] --> Array to be sorted 
    si  --> Starting index 
    ei  --> Ending index 
    */
    static void quickSort(char A[], int si, int ei) 
    { 
        int pi;    /* Partitioning index */
        if(si < ei) 
        { 
            pi = partition(A, si, ei); 
            quickSort(A, si, pi - 1); 
            quickSort(A, pi + 1, ei); 
        } 
    } 

    /* Driver program to test to print printDups*/
    public static void main(String args[]) 
    { 
        char str1[] = {'t','e','s','t'}; 
        char str2[] = {'t','t','e','w'}; 
        if (areAnagram(str1, str2)) 
            System.out.println("The two strings are"+ 
                             " anagram of each other"); 
        else
            System.out.println("The two strings are not"+ 
                               " anagram of each other"); 
    } 
} 

【讨论】:

    【解决方案3】:

    实现不正确。虽然一对字谜总是具有相同的长度和相同的字符总和,但这不是充分条件。有许多对具有相同长度和相同字符总和且不是字谜的字符串。例如,"ad""bc"

    更好的实现是计算每个字符在每个字符串中出现的次数并进行比较。例如:

    public static boolean isAnagram(String a, String b) {
        return charCounts(a).equals(charCounts(b));
    }
    
    private static Map<Integer, Long> charCounts(String s) {
        return s.chars()
                .boxed()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    }
    

    【讨论】:

      【解决方案4】:
      static boolean isAnagram(String a, String b) {
              if (a.length() != b.length())
                  return false;
              a = a.toLowerCase();
              b = b.toLowerCase();
              HashMap<Integer, Integer> m1 = new HashMap<>(); // Key is ascii number, Value is count. For String a
              HashMap<Integer, Integer> m2 = new HashMap<>(); // Key is ascii number, Value is count. For String b
              for (int i = 0; i < a.length(); i++) {
                  int an = (int) (a.charAt(i));
                  int bn = (int) (b.charAt(i));
                  // Add 1 to current ascii number. String a.
                  if (m1.containsKey(an)) {
                      m1.put(an, m1.get(an) + 1);
                  }else {
                      m1.put(an, 1);
                  }
                  // Add 1 to current ascii number. String b.
                  if (m2.containsKey(bn)) {
                      m2.put(bn, m2.get(bn) + 1);
                  }else {
                      m2.put(bn, 1);
                  }
              }
      
              //Check both count equals().
              return m1.equals(m2);
          }
      

      您应该检查每个字母。 如果 (ascii of a[0] == ascii of b[0] + 1) 和 (ascii of a[1] == ascii of b[1] - 1) 它将返回 true,因为 1 - 1 为零。 抱歉,代码非常复杂。

      【讨论】:

        【解决方案5】:

        添加字符值是容易出错的逻辑,因为A+CB+B 生成相同的数字。这种情况下最好的选择是使用数组。看下面的代码——

        static boolean isAnagram(String a, String b) {
            if (a.length() != b.length()) return false;
            a = a.toLowerCase();
            b = b.toLowerCase();
        
            char[] charA = a.toCharArray();
            Arrays.sort(charA);
        
            char[] charB = b.toCharArray();
            Arrays.sort(charB);
        
            return Arrays.equals(charA, charB);
        }
        

        这应该会给你你想要的。

        【讨论】:

          【解决方案6】:

          试试这个。它将在 O(word.length) 中执行。

          public boolean checkForAnagram(String str1, String str2) {
              if (str1 == null || str2 == null || str1.length() != str2.length()) {
                  return false;
              }
              return Arrays.equals(getCharFrequencyTable(str1), getCharFrequencyTable(str2));
          }
          
          private int[] getCharFrequencyTable(String str) {
              int[] frequencyTable = new int[256]; //I am using array instead of hashmap to make you realize that its a constant time operation.
              char[] charArrayOfStr = str.toLowerCase().toCharArray();
              for(char c : charArrayOfStr) {
                  frequencyTable[c] = frequencyTable[c]+1;
              }
              return frequencyTable;
          }
          

          【讨论】:

            【解决方案7】:

            查看以下方法:

            /**
             * Java program - String Anagram Example.
             * This program checks if two Strings are anagrams or not
             */
            public class AnagramCheck {
            
            /*
             * One way to find if two Strings are anagram in Java. This method
             * assumes both arguments are not null and in lowercase.
             *
             * @return true, if both String are anagram
             */
            public static boolean isAnagram(String word, String anagram){       
                if(word.length() != anagram.length()){
                    return false;
                }
            
                char[] chars = word.toCharArray();
            
                for(char c : chars){
                    int index = anagram.indexOf(c);
                    if(index != -1){
                        anagram = anagram.substring(0,index) + anagram.substring(index +1, anagram.length());
                    }else{
                        return false;
                    }           
                }
            
                return anagram.isEmpty();
            }
            
            /*
             * Another way to check if two Strings are anagram or not in Java
             * This method assumes that both word and anagram are not null and lowercase
             * @return true, if both Strings are anagram.
             */
            public static boolean iAnagram(String word, String anagram){
                char[] charFromWord = word.toCharArray();
                char[] charFromAnagram = anagram.toCharArray();       
                Arrays.sort(charFromWord);
                Arrays.sort(charFromAnagram);
            
                return Arrays.equals(charFromWord, charFromAnagram);
            }
            
            
            public static boolean checkAnagram(String first, String second){
                char[] characters = first.toCharArray();
                StringBuilder sbSecond = new StringBuilder(second);
            
                for(char ch : characters){
                    int index = sbSecond.indexOf("" + ch);
                    if(index != -1){
                        sbSecond.deleteCharAt(index);
                    }else{
                        return false;
                    }
                }
            
                return sbSecond.length()==0 ? true : false;
            }
            

            }

            【讨论】:

              【解决方案8】:

              您在给定字符串中添加字符的 ascii 值并比较它们,这并不总是会给您正确的结果。考虑一下:

              String a="acd"String b="ccb"

              他们都会给你 296 的总和,但这些不是字谜。

              您可以计算两个字符串中字符的出现次数并进行比较。在上面的例子中,它会给你 {"a":1,"c":1,"d":1} 和 {"c":2,"b":1}。

              此外,您可以将素数与每个字符集 [a-z] 相关联,其中“a”匹配 2,“b”匹配 3,“c”匹配 5,依此类推。

              接下来,您可以计算与给定字符串中的字符相关联的素数的乘积。乘法遵循关联规则 (xy = yx)。

              例子:

              abc --> 2*3*5 = 30

              cba --> 5*3*2 = 30

              注意:如果字符串很大,这可能不是最好的方法,因为您可能会遇到溢出问题。

              【讨论】:

                猜你喜欢
                • 2022-11-28
                • 2019-11-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-04-05
                • 2018-05-17
                • 2013-05-13
                • 2019-09-28
                相关资源
                最近更新 更多