对字谜的改进

Bil*_*ill 2 java anagram

刚刚完成了最近的作业,但我知道它可能更有效率.它从命令行读取两个单词,忽略空格和标点符号,并确定它们是否是字谜.我的内容如下; 据我所知,它功能齐全.

/**
 * Find out if a string is an anagram of another string
 * 
 */

import java.util.Arrays;

public class Anagram
{
    public static void main(String[] args)
    {
        if (args.length != 2)
            System.out.println("You did not enter two words!");        
        else            
            printWords(args[0], args[1]);                              
    }

    // method to determine whether two strings have the same chars
    public static boolean areAnagrams(String wordOne, String wordTwo) 
    {
        // new strings for letters only
        String ltrsOnlyOne = lettersOnly(wordOne);
        String ltrsOnlyTwo = lettersOnly(wordTwo);      

        // convert strings to lowercase char arrays
        char[] first = ltrsOnlyOne.toLowerCase().toCharArray();
        char[] second = ltrsOnlyTwo.toLowerCase().toCharArray();

        // sort char arrays using sort method
        Arrays.sort(first);
        Arrays.sort(second);

        if (Arrays.equals(first, second))
            return true;
        else
            return false;
    }

    public static String lettersOnly(String word) 
    {
        int length = word.length();
        StringBuilder end = new StringBuilder(length);
        char x;

        for (int i = (length - 1); i >= 0; i--) {
            x = word.charAt(i);
            if (Character.isLetter(x)) {
                end.append(x);
            }
        }
        return end.toString();
    }

    public static void printWords(String wordOne, String wordTwo)
    {
       boolean b = areAnagrams(wordOne, wordTwo);
       if (b == true) {
            System.out.println(wordOne + " is an anagram of "+ wordTwo);
       }

       if (b == false) {
            System.out.println(wordOne + " is not an anagram of "+ wordTwo);
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 11

错误修复:lettersOnly返回值丢失

您的lettersOnly方法不会修改其参数,它会返回新的字符串.当你调用它时,你需要用这个返回值做一些事情.否则你只是在调用它并丢弃结果.

// method to determine whether two strings have the same chars
public static boolean sameChars(String wordOne, String wordTwo) 
{
    lettersOnly(wordOne);
    lettersOnly(wordTwo);
    wordOne = lettersOnly(wordOne);
    wordTwo = lettersOnly(wordTwo);

    ...
}
Run Code Online (Sandbox Code Playgroud)

死代码删除

main()sameChars没有检查其返回值的情况下调用.由于sameChars不会修改其参数或具有任何其他副作用,因此此调用是死代码,应删除.

public static void main(String[] args)
{
    if (args.length != 2) {
        System.out.println("You did not enter two words!");
    }

    sameChars(args[0], args[1]);        
    printWords(args[0], args[1]);             
}
Run Code Online (Sandbox Code Playgroud)

重构if语句

虽然你的if陈述是正确的,但==用来比较true并且false不是惯用的.使用布尔值时,无需进行显式比较.它更短,读取更好,简单地省略比较.

if (sameChars(wordOne, wordTwo) == true) {
if (sameChars(wordOne, wordTwo)) {
    System.out.println(wordOne + " is an anagram of "+ wordTwo);
}
if (sameChars(wordOne, wordTwo) == false) { if (!sameChars(wordOne, wordTwo)) { System.out.println(wordOne + " is not an anagram of "+ wordTwo); }

注意如何== false用等效!(NOT)替换.

实际上,没有理由重复这个电话sameChars.拥有看起来如此相似的代码应该在你的脑海中引起一个小小的警报."应该有办法消除重复的代码,"你想.啊,是的,让我们把第二个切换ifelse!

if (sameChars(wordOne, wordTwo)) {
    System.out.println(wordOne + " is an anagram of "+ wordTwo);
}
else {
    System.out.println(wordOne + " is not an anagram of "+ wordTwo);
}

高级

沿着类似的方向,您可以简化以下语句集:

if (Arrays.equals(first, second))
    return true;
else
    return false;
Run Code Online (Sandbox Code Playgroud)

如果结果equals()为true,则返回true.否则当它为假时你返回false.如果你考虑一下,你实际上只是返回任何equals返回的东西.其实你可以消除ifelse完全和简单的返回结果equals直接.咦!

return Arrays.equals(first, second);
Run Code Online (Sandbox Code Playgroud)

这个变化比前一个更先进.如果您以前从未见过这种变化,您可能会发现这种变化有点奇怪.但它确实相当于四线版本.

循环反转

通常,当程序员编写for循环时,它们从0开始并迭代到某个上限.您是否有理由将循环编写为降序循环?

for (int i = (length - 1); i >= 0; i--) {
    x = word.charAt(i);
    if (Character.isLetter(x)) {
        end.append(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

一些程序员会像这样向后循环,这是一种"更有效"的可疑尝试.如同,它们只执行(length - 1)一次计算,所以它稍快一些.我个人认为这浪费时间和脑力.

事实上,向后写你的lettersOnly函数有一个奇怪的副作用,即在删除不需要的字符后以相反的顺序返回字符串.事实证明这并不重要,因为您稍后将字符按字母顺序排序.但这是一种可以在以后咬你的东西.事情就是这样,你因为排序而逃脱了逆转.我会切换循环以正常的0到n顺序迭代:

for (int i = 0; i < length; ++i) {
    x = word.charAt(i);
    if (Character.isLetter(x)) {
        end.append(x);
    }
}
Run Code Online (Sandbox Code Playgroud)