-2

问题:翻译成“Pig Latin”的简单规则是取一个以元音开头的单词并添加“yay”,同时取任何以一个或多个辅音开头的单词并将它们转移到后面,然后再添加“啊”。例如,“able”变成“ableyay”,“stripe”变成“ipestray”。编写一个函数,将一串字母转换成它的 Pig-Latin 翻译。

执行:

-- define function to detect vowel
isVowel :: Char -> Bool
isVowel c = elem c ['u','e','o','a','i']


-- define function Latin Pig
lp ::String -> String
lp str = if (isVowel (head str)) then do {str ++ "yay"} 
         else
            do {

                str ++ (head str)
                tail str
                lp str

                }   

问题:到目前为止,我的代码(逻辑)没有任何问题。老实说,这是我的 Haskell 入门课程的作业。但是编译器给了我错误:

**Couldn't match expected type `t0 -> t1 -> t2 -> t3 -> [Char]'
                with actual type `Char'
    Expected type: [t0 -> t1 -> t2 -> t3 -> [Char]]
      Actual type: String
    In the first argument of `head', namely `str'
    In the second argument of `(++)', namely
      `(head str) tail str lp str'
Failed, modules loaded: none.**

我的代码有什么问题?!

4

4 回答 4

7

首先,考虑模式匹配。
任何非空列表都可以定义为x:xs,其中
x 为头列表
xs为尾列表

然后你的代码变成,

-- define function Latin Pig
lp :: String -> String
lp [] = ""
lp (x:xs) = if (isVowel x) then str ++ "yay"
            else ..... -- fill here
                where str = (x:xs)   

别忘了 operator :是 list 的构造函数,例如
'a':"bab" => "abab"

请记住,字符串是一个字符列表。
此外,您可以跳过前面示例中的 where 子句,如下所示,

-- define function Latin Pig
lp :: String -> String
lp [] = ""
lp str@(x:xs) = if (isVowel x) then str ++ "yay"
                else ..... -- fill here

应该足以帮助你。
祝你好运

于 2013-02-03T22:52:06.383 回答
1

我不确定使用递归是否是您要求的一部分,但这是我对您的任务的看法。您不需要使用domonad 来实现您想要的(除非这是作业的目标?)。

您可能需要考虑使用模式匹配和守卫而不是 if else 块。

此外,就像 zurgl 所说,您可以像这样利用匹配字符串:string@(x:xs)这将允许您在使用整个字符串的同时使用 headx和 tail xs

注意:所有字符串都是列表。

这是我建议的一个简单示例。

-- define function to detect vowel
isNotVowel :: Char -> Bool
isNotVowel c = notElem c ['u','e','o','a','i']

-- define function Latin Pig
lp :: String -> String
lp [] = []
lp p@(x:xs)
    | not $ isNotVowel x = p++"yay"
    | otherwise = let (constants, rest) = span isNotVowel p
                    in (rest++constants++"ay")

玩得开心学习haskell!

一些学习haskell的好资源:

于 2013-02-04T06:11:29.940 回答
1

这是另一种放置猪拉丁规则的方式:

  • 如果一个词不以一连串的辅音开头,那么翻译就是原词后跟“yay”
  • 否则翻译是单词的其余部分,然后是最初的辅音,然后是“ay”

这更容易翻译成 Haskell。

(实际的 Haskell 代码省略了,因为这是家庭作业。)

您会发现将您isVowel的函数与breakData.List 中的函数结合起来很有帮助。

于 2013-02-04T09:19:23.627 回答
-1

请参考以下代码。

private static BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        System.out.print("Enter sentence: ");
        String sentence = getString();
        String latin = pigLatinForSentence(sentence);
        System.out.println(latin);
    }

    private static String pigLatinForSentence(String s) {
        String latin = "";
        int i = 0;
        while (i < s.length()) {
            while (i < s.length() && !isLetter(s.charAt(i))) {
                latin = latin + s.charAt(i);
                i++;
            }
            if (i >= s.length())
                break;
            int begin = i;
            while (i < s.length() && isLetter(s.charAt(i))) {
                i++;
            }
            int end = i;
            latin = latin + pigWord(s.substring(begin, end));
        }
        return latin;
    }

    private static boolean isLetter(char c) {
        return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
    }

    private static String pigWord(String word) {
        int split = firstVowelInSentence(word);
        return word.substring(split) + "-" + word.substring(0, split) + "ay";
    }

    private static int firstVowelInSentence(String word) {
        word = word.toLowerCase();
        for (int i = 0; i < word.length(); i++)
            if (word.charAt(i) == 'a' || word.charAt(i) == 'e' || word.charAt(i) == 'i' || word.charAt(i) == 'o'
                    || word.charAt(i) == 'u')
                return i;
        return 0;
    }

    private static String getString() throws IOException {
        return buf.readLine();

    }

希望此解决方案可以帮助您了解有关猪拉丁语的更多详细信息。

于 2019-11-07T10:26:54.950 回答