【问题标题】:Determine if two words are anagrams确定两个单词是否是字谜
【发布时间】:2014-09-03 05:02:22
【问题描述】:

我最近参加了一个测验,要求我确定数组中的元素是否是字谜。我完成了一个实现,但在运行他们的测试时,我只通过了 5 个测试用例中的 1 个。问题是,他们不允许我看到测试是什么,所以我真的不确定我失败了什么。我在下面重新创建了我的答案,它基本上将一个单词中的字母相乘并将这个数字添加到一个数组中。然后它将一个数组中的数字与另一个数组中的数字进行比较,如果它们相同,则打印 true。我基本上是在问在哪些情况下会失败,我将如何修改此代码以解决这些情况?

public class anagramFinder {
    public static void main (String[] args){
        String[] listOne = new String[5];
        listOne[0] = "hello";
        listOne[1] = "lemon";
        listOne[2] = "cheese";
        listOne[3] = "man";
        listOne[4] = "touch";

        String[] listTwo = new String[5];
        listTwo[0] = "olleh";
        listTwo[1] = "melon";
        listTwo[2] = "house";
        listTwo[3] = "namer";
        listTwo[4] = "tou";

        isAnagram(listOne,listTwo);
    }

    public static void isAnagram(String[] firstWords, String[] secondWords){
        int firstTotal = 1;
        int secondTotal = 1;
        int[] theFirstInts = new int[firstWords.length];
        int[] theSecondInts = new int[secondWords.length];

        for(int i = 0;i<firstWords.length;i++){
            for(int j = 0;j<firstWords[i].length();j++){
                firstTotal = firstTotal * firstWords[i].charAt(j);
            }

            theFirstInts[i] = firstTotal;
            firstTotal = 1;
        }

        for(int i = 0;i<secondWords.length;i++){
            for(int j = 0;j<secondWords[i].length();j++){
                secondTotal = secondTotal * secondWords[i].charAt(j);
            }

            theSecondInts[i] = secondTotal;
            secondTotal = 1;
        }

        for(int i=0;i<minimum(theFirstInts.length,theSecondInts.length);i++){
            if(theFirstInts[i] == theSecondInts[i]){
                System.out.println("True");
            } else {
                System.out.println("False");
            }
        }
    }
    public static int minimum(int number,int otherNumber){
        if(number<otherNumber){
            return number;
        } else {
            return otherNumber;   
        }
    }
}

在上面我在 main 方法中运行的示例中,这会打印 True True False False False,这是正确的

【问题讨论】:

  • 我不知道该代码应该做什么。
  • 你真的应该和你的教授或助教谈谈这个代码(在测验中)。他们需要知道您为什么会遇到问题。另外,在我上大学的时候,我们被教导“手部处决”。手动运行此代码,输入一些不同的输入,然后尝试找出错误可能出在哪里。
  • 任何超过 5 个字符的单词都会失败,因为int 会溢出。此外,尚不清楚您不能让两个不同的字母组合产生相同的产品。
  • 并学习如何编写 cmets。在您的 cmets 中说明您在计算的每个步骤中知道是正确的。
  • 嗯,这是一个网站上的测验,不是为了学校,所以我没有办法得到测试用例

标签: java arrays string char anagram


【解决方案1】:

从类似问题中复制我的答案。

这是一个简单的快速 O(n) 解决方案,无需使用排序或多个循环或哈希映射。我们增加第一个数组中每个字符的计数并减少第二个数组中每个字符的计数。如果结果计数数组全为零,则字符串是字谜。可以通过增加计数数组的大小来扩展以包含其他字符。

class AnagramsFaster{

    private static boolean compare(String a, String b){
        char[] aArr = a.toLowerCase().toCharArray(), bArr = b.toLowerCase().toCharArray();
        if (aArr.length != bArr.length)
            return false;
        int[] counts = new int[26]; // An array to hold the number of occurrences of each character
        for (int i = 0; i < aArr.length; i++){
            counts[aArr[i]-97]++;  // Increment the count of the character at i
            counts[bArr[i]-97]--;  // Decrement the count of the character at i
        }
        // If the strings are anagrams, the counts array will be full of zeros
        for (int i = 0; i<26; i++)
            if (counts[i] != 0)
                return false;
        return true;
    }

    public static void main(String[] args){
        System.out.println(compare(args[0], args[1]));
    }
}

【讨论】:

    【解决方案2】:

    ASCII 码相乘的想法不错,但并不完美。需要深入分析才能表明两个不同的单词可能具有相同的产品,具有给定的“a”到“z”范围,并且在合理的长度内。

    一种传统的方法是创建一个用于计算字母的地图,然后比较这些地图。

    另一个人会对字母进行排序并比较排序后的字符串。

    第三个会遍历第一个单词的字母,尝试找到第二个单词中的字母,然后用那个字母减少第二个单词。

    我想不出第四种方法,但我几乎可以肯定有一个 ;-)

    稍后

    好吧,这是第四种方法:将 26 个素数分配给 'a' 到 'z',然后(使用 BigInteger)根据单词的字母将素数相乘。字谜产生相同的产品。

    【讨论】:

    • 好的,我明白为什么这样更好了。第四种方法基本上是我想要的,但我想如果数字不是素数,你最终可能会有不同的字母组合等于相同的产品。感谢您的澄清
    • 嗯,那个,以及用“无限”位数计算乘积的必要性。
    猜你喜欢
    • 2013-02-09
    • 2011-05-13
    • 1970-01-01
    • 2015-05-04
    • 2017-08-13
    • 2016-04-07
    • 2017-12-02
    • 2017-08-12
    相关资源
    最近更新 更多