【问题标题】:Boundary Case conditions for String Anagrams字符串字谜的边界条件
【发布时间】:2019-10-13 12:40:26
【问题描述】:

我尝试编写一个字符串 Anagram 程序,但在检查边界条件时卡住了。

我知道互联网上有很多与使用单循环或使用集合框架的字符串字谜相关的方法和程序,但我需要我的代码的解决方案,我如何才能涉及代码的边界情况。

public class StringAnagram {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    String str = "abc";
    String strAnagram = "cba";

    boolean areAnagrams = ifAnagrams(str, strAnagram);
    System.out.println(areAnagrams);
}

private static boolean ifAnagrams(String str, String strAnagram) {
    // TODO Auto-generated method stub

    int count = 0;
    char[] a = strAnagram.toCharArray();

    if (str.length() != strAnagram.length()) {
        return false;
    }

    for (int i = 0; i < str.length(); i++) {
        {
            System.out.println("str.charAt(i) in outer loop :" + str.charAt(i));

            for (int j = 0; j < strAnagram.length(); j++) {
                if (str.charAt(i) == strAnagram.charAt(j)) {
                    System.out.println("str.charAt(i) : " + str.charAt(i));
                    System.out.println("strAnagram.charAt(j) : " + strAnagram.charAt(j));

                    count++;
                }
            }
        }
        System.out.println(count);
        if (count == str.length()) {
            return true;
        }
    }

    return false;
}
}

如果我输入喜欢的输入,代码工作正常 - “abc”或“abcd”,其中字符串中的每个字符只出现一次,但是当输入像“aab”可以与“abc”进行比较时它会失败,它会显示字符串是字谜。 那么,我如何在我的代码中处理这种情况。请指教。

【问题讨论】:

  • 你可以使用排序。如果您的字母少于 20,我认为插入排序是可以的。
  • 但是如果我写一个字谜检查器,我可能会声明 2 个数组,每个数组都包含另一个数组,其索引是要检查的字母,即arr[letters['j']];,它只不过是一个计数器。在最后阶段,我会比较计数器是否匹配。程序的时间复杂度很可能是O(n)
  • 不使用数组,你可以使用HashMap数据结构来完成。

标签: java data-structures


【解决方案1】:

您的解决方案的问题在于它只检查第一个字符串中的每个字符是否存在于第二个字符串中。您还需要考虑 2 个条件:

  1. 如果第二个字符串中的每个字符也出现在第一个字符串中
  2. 如果第一个和第二个字符串中每个字符的字符数匹配

对于("aaa", "abc") 的输入,您当前的解决方案将返回True,而它应该返回False。实现我上面提到的第一个条件将解决这个问题。

实现第一个条件后,您的解决方案将返回True 以输入("abb", "aab"),而它应该返回False。实现我上面提到的第二个条件将解决这个问题。

这里有一个简单的方法来完成这项工作:

Map<Character, Integer> charCount = new HashMap<Character, Integer>();

for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);
    if (charCount.containsKey(c)) {
        charCount.put(c, charCount.get(c)+1);
    } else {
        charCount.put(c, 1);
    }
}

for (int i = 0; i < strAnagram.length(); i++) {
    char c = strAnagram.charAt(i);
    if (!charCount.containsKey(c)) return false;
    if (charCount.get(c) == 0) return false;
    charCount.put(c, charCount.get(c)-1);
}

for (char k : charCount.keySet()) {
    if (charCount.get(k) != 0) return false;
}

return true;

由于没有嵌套循环,时间复杂度为O(n)。即使使用了 Map,空间复杂度也是 O(1),因为它保证了键的总数不会超过所有可能的字符数。

这种解决方案在时间和空间复杂度方面甚至比排序还要好。

【讨论】:

    【解决方案2】:

    这可能仍然非常低效。我再次为最初忽略您的要求而道歉,即不能包含任何集合框架。

    public class StringAnagram {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            // String str = "abc";
            // String strAnagram = "cba";
    
            String str = "abcdd";
            String strAnagram = "dccba";
    
            boolean areAnagrams = ifAnagrams(str, strAnagram);
            System.out.println(areAnagrams);
        }
    
    
    
        private static boolean ifAnagrams(String str, String strAnagram) {
    
            int count = 0;
            char[] a = strAnagram.toCharArray();
            char[] b = str.toCharArray();
    
            String alphaString = "abcdefghijklmnopqrstuvwxyz";
            char[] alpha = alphaString.toCharArray();
    
            System.out.println(a);
            System.out.println(b);
            System.out.println("");
    
            if (str.length() != strAnagram.length()) {
                return false;
            }
    
    
            for (int i=0; i < alpha.length; i++) {
                int countA = 0;
                int countB = 0;
    
                for(int j = 0; j < a.length; j++){
    
                    if (a[j] == alpha[i]) {
                        countA++;
                    }
                    if (b[j] == alpha[i]) {
                        countB++;
                    }
    
                }
    
                if (countA != countB) {
                    return false;
                }
            }
    
            return true;
        }
    }
    

    此替代解决方案使用包含字母表中所有字母的字符串,并遍历它们以检查两个字符串是否具有相同的每个字母计数。这次没有框架:)

    【讨论】:

    • 你正在使用 Arrays.util 函数,我已经暗示请尝试不使用集合。它在互联网人上最常见的答案,你只是从那里复制粘贴:),你能建议我如何在我的代码中处理这种情况。
    • 我编辑并更改了我的解决方案。它不再使用框架导入。
    猜你喜欢
    • 2021-09-16
    • 2020-10-28
    • 2020-06-20
    • 1970-01-01
    • 2016-06-24
    • 2015-11-11
    • 2018-09-11
    • 2020-09-21
    • 2017-07-15
    相关资源
    最近更新 更多