将一个元素添加到列表的末尾,方案

时间:2015-10-25 22:07:06

标签: scheme

我坚持认识的事情是微不足道的,但我不知道该怎么做。我将字符串转换为列表,稍微更改列表,然后将其转换回字符串。

我将单词翻译成猪拉丁语,但我在添加" ay"到一个字的结尾。我知道如何获取列表的第一个元素并将其发送到后面,但出于某种原因,我的代码不会添加" ay"同样。我在计划之前已经附加到列表中,它相对简单,但我无法弄清楚它为什么不在这里工作,我尝试了几种不同的方法。

以下是代码:

(define (member? item seq)
  (sequence-ormap (lambda (x)
                    (equal? item x))
                  seq))

(define (vowel? letter)
  (member? letter '(a e i o u)))

(define (first-to-last x) (append (cdr x) (list (car x))))

(define (piglatin wd)
  (define stringlist (string->list wd))
  (cond
    [(vowel? (car stringlist)) (append 'yay stringlist)]
    [else (define pigstringlist (first-to-last stringlist)) (append pigstringlist '(ay)) (list->string pigstringlist)])
  )

我希望看起来没事,除了无法附加到列表的末尾。我觉得我错过了一些简单的东西,但是我试图学习来自C / Java背景的方案,而这些小东西是巨大的时间消费者。如果有人看到任何东西,我会非常感激。我可以使用一些建议并稍微修改一下这段代码,因为它对我来说似乎有点多了。

这是"home"

上的输出
(piglatin "home")
"omeh"

2 个答案:

答案 0 :(得分:0)

(define (piglatin wd)
  (define stringlist (string->list wd))
  (cond
    [(vowel? (car stringlist)) (append 'yay stringlist)]
    [else (define pigstringlist (first-to-last stringlist)) 
          (append pigstringlist '(ay))    ;;
          (list->string pigstringlist)]))

您计算了附加列表'(ay)的新列表,但是:

  1. '(ay)是包含单个符号的列表。在这里,你应该操纵不同的字符列表。例如见:

    (string->list "wow")
    => (#\w #\o #\w)
    
  2. append函数的结果将被丢弃。请记住,append不会修改现有列表。因此,else案例中返回的值为pigstringlist,a.k.a。(first-to-last stringlist)

  3. else中的整个表达式可能是(第一个版本):

    ...
    [else (list->string 
            (append (first-to-last stringlist)
                    '(#\a #\y)))]...
    

    上面的'yay也是如此,这不是一个列表。 您正在使用列表函数操作字符串,但您可以使用与字符串相关的函数,例如string-append

    (define (pig-latin wd)
      (cond
        [(vowel? (string-ref wd 0)) (string-append "yay" wd)]
        [else (string-append (first-to-last wd) "ay")]))
    

    当然,first-to-last应该重新定义,因为它需要一个列表。 实现它的一种方法是:

    (define (first-to-last word)
      (string-append (substring word 1)
                     (substring word 0 1)))
    

    当您定义vowel?时,成员资格测试总是失败,因为您再次将字母(字符)与作为标识符的符号进行比较。你应该考虑大写字母:

    (define (vowel? letter)
      (member letter '(#\a #\e #\i #\o #\u #\y) char-ci-=?))
    

    我正在使用现有的member函数,该函数接受等式谓词。这里,该函数不区分大小写地比较字符。

答案 1 :(得分:0)

如果我是你,我不会将字符串转换为列表并返回。我会直接玩字符串。这是我想到的解决方案:

  1. 将字符串封下来。
  2. 在字符串中查找最长的辅音。
  3. 如果辅音运行是空的,那么只需追加" yay"到字符串的末尾。
  4. 否则,在辅音运行后取子串,然后追加辅音运行" ay"。
  5. 如果原始字符串以大写字母开头,则选中结果字符串。 (这意味着,如果原始单词是全部大写的,那么这将是错误的。太糟糕了。不要为胜利而大喊大叫。)
  6. 以下是代码(需要SRFI 1314):

    (define vowels (char-set #\a #\e #\i #\o #\u))
    (define (pig-latin word)
      (define downcased (string-downcase word))
      (define index (string-index downcased vowels))
      (define result (if (zero? (or index 0))
                         (string-append downcased "yay")
                         (string-append (substring downcased index)
                                        (substring downcased 0 index)
                                        "ay")))
      (if (and (not (zero? (string-length word)))
               (char-upper-case? (string-ref word 0)))
          (string-titlecase result)
          result))