代码之家  ›  专栏  ›  技术社区  ›  Sergio Tapia

我能改进这个猪拉丁语转换器吗?[关闭]

  •  0
  • Sergio Tapia  · 技术社区  · 14 年前

    我是全新的爪哇打爪哇,我做了这个小翻译为猪拉丁。

    package stringmanipulation;
    
    public class PigLatinConverter {
        public String Convert(String word){
            int position = 0;
            if (!IsVowel(word.charAt(0))) {
                for (int i= 0; i < word.length(); i++) {
                    if (IsVowel(word.charAt(i))) {
                        position = i;
                        break;
                    }
                }
                String first = word.substring(position, word.length());
                String second = word.substring(0, position) + "ay";
    
                return first + second;
            } else {
                return word + "way";
            }
        }
    
        public boolean IsVowel(char c){
            if (c == 'a')
                return true;
            else if(c == 'e')
                return true;
            else if(c == 'i')
                return true;
            else if(c == 'o')
                return true;
            else if(c == 'u')
                return true;
            else
                return false;        
        }
    }
    

    我能做些什么改进吗?

    在我可能不知道的最新Java版本中是否有任何漂亮的Java技巧?我来自C背景。

    谢谢您!

    7 回复  |  直到 11 年前
        1
  •  4
  •   polygenelubricants    14 年前

    我会重写 isVowel(char ch) 如下:

    return "aeiou".indexOf(ch) != -1;
    

    我改写以下内容:

    // String first = word.substring(position, word.length());
       String first = word.substring(position);
    

    我还将重命名方法名以遵循编码约定。

    当然,作为我,我也会使用regex而不是 substring for 循环。

    System.out.println("string".replaceAll("([^aeiou]+)(.*)", "$2$1ay"));
    // ingstray
    

    工具书类

        2
  •  1
  •   strager    14 年前

    免责声明:我不懂Java。

    倒置逻辑令人困惑,请写下 if 声明如下:

        if (IsVowel(word.charAt(0))) {
            return word + "way";
        } else {
            for (int i= 0; i < word.length(); i++) {
    
            // ...
    
            return first + second;
        }
    

    你甚至可以放下 else .

    IsVowel 可能需要保密。它也可以用一个 || 链,或作为 "".indexOf (或者Java中的任何内容)。

    你的 for 逻辑可以简化为 while :

            while (position < word.length() && !IsVowel(word.charAt(position)) {
                ++position;
            }
    
        3
  •  1
  •   polygenelubricants    14 年前

    下面是一个完整的重写,如果您知道如何读取regex,可以使代码更具可读性:

    String[] words =
        "nix scram stupid beast dough happy question another if".split(" ");
    
    for (String word : words) {
        System.out.printf("%s -> %s%n", word,
            ("w" + word).replaceAll(
                "w(qu|[^aeiou]+|(?<=(w)))([a-z]*)",
                "$3-$1$2ay"
            )
        );
    }
    

    这张照片( as seen on ideone.com ):

    nix -> ix-nay
    scram -> am-scray
    stupid -> upid-stay
    beast -> east-bay
    dough -> ough-day
    happy -> appy-hay
    question -> estion-quay
    another -> another-way
    if -> if-way
    

    注意 question 变成 estion-quay ,这是根据 Wikipedia article . 事实上,以上的单词和译文都是从文章中摘录的。

    regex的工作方式如下:

    • 首先,所有单词的前缀都是 w 以防万一
    • 那么,跳过这个 W ,查找 qu 或者一个非空的辅音序列。如果两者都找不到,则实际单词以元音开头,因此抓住 W 使用捕获后视镜
    • 然后重新排列组件以获得翻译

    即:

    "skip" dummy w
    |
    w(qu|[^aeiou]+|(?<=(w)))([a-z]*)   -->  $3-$1$2ay
     \                2\_/ /\______/
      \_________1_________/    3
    

    工具书类

        4
  •  1
  •   No_name    11 年前

    我知道这个问题已经一年多了,但我想我会把我的修改放在上面。这段代码有几个改进。

    public String convert(String word)
    {
        int position = 0;
        while(!isVowel(word.charAt(position)))
        {
            ++position;
        }
        if(position == 0)
        {
            return word + "-way";
        }
        else if(word.charAt(0) == 'q')
        {
            ++position;
        }
        return word.substring(position) + "-" + word.substring(0, position) + "ay";
    }
    public boolean isVowel(char character) 
    {
        switch(character)
        {
            case 'a': case 'e': case 'i': case 'o': case 'u':
                return true;
            default:
                return false;
        }
    }
    

    首先,代码将找到第一个元音的位置,然后跳出循环。这比使用for循环迭代每个字母和使用break;跳出循环要简单得多。其次,这将匹配维基百科网站上的所有测试案例。最后,由于chars实际上是一个有限的range int,因此可以使用switch语句来提高性能和可读性。

        5
  •  0
  •   Ryan M Jordan    14 年前

    并不是严格的改进,但是Java约定规定方法应该以小写字母开头。

        6
  •  0
  •   Steven    14 年前

    我已经从Java中删除了几年,但是总体来说,代码看起来很好。如果你想吹毛求疵,这里有一些评论:

    • 添加注释。它不必遵循javadoc规范,但至少要明确地描述接受的参数和预期的返回值,并可能给出一些关于它如何工作的提示(取决于第一个字符是否是元音,行为不同)
    • 你可能想抓住 IndexOutOfBoundsException ,我认为如果你给它传递一个零长度的字符串,可能会发生这种情况。
    • 方法名称应为小写。
    • IsVowel 可以重写 return c == 'a' || c == 'e' 等等。由于短路,性能方面的比较数量应相似。
        7
  •  0
  •   tc.    14 年前

    这是作业吗?如果是,请按此方式标记。

    • 不清楚“诚实”或“镱”的预期行为是什么。
    • 它不尊重大写字母(“foo”应该变成“oofay”,aeiou也是元音)。
    • 如果传入空字符串,它将崩溃。