Добавление чисел из списка (например, asdf125dkf вернет 8) - PullRequest
4 голосов
/ 04 ноября 2010

Мне нужна функция, которая будет принимать список символов и цифр, а затем возвращать сложенные числа (игнорируя символы). Это то, что я до сих пор:

(define (adder lst)
   (cond
     ((null? lst)
       0)
     ((number? (car lst))
      (+(adder (car lst)) (adder (cdr lst))))
     ((char? (car lst))
      ((adder(cdr lst))))
     ))

(display (adder '(asd12sdf)))

Запуск его на codepad.org просто отображает void. Я знаю, что код неправильный, потому что он выглядит неправильно, но я понятия не имею, как это исправить ... Как заставить функцию отслеживать первый найденный номер и добавлять его к следующему найденному, пропуская все символы?

Ответы [ 3 ]

3 голосов
/ 04 ноября 2010

Во втором случае cond нет причин запускать adder на (car lst). Простое добавление (car list) к рекурсивному шагу должно работать.

Для последней строки не проверяйте (char? (car lst)). Просто сделайте последнюю строку предложением else, означая, что все, НО число будет идти в строку else.

Причина, по которой вы становитесь недействительной, заключается в том, что ваш ввод не удовлетворяет любому из cond условий, а у вас нет else, поэтому ответ - ничто (т.е. ).

Последняя ошибка во вводимых вами данных. '(asd12sdf) это буквально список с одним символом с именем "asd12sdf". Я думаю, что вы хотите дать ему '(a s d 1 2 s d f) (список из 6 символов и 2 цифр), что должно привести к 3. Обратите внимание, что между символом 'a и символом #\a.

есть очень важное различие.

Похоже, у вас не работает логика, поэтому ваша проблема не в функциональных языках, а только в синтаксисе Схемы.

Редактировать: и в последней строке у вас есть ((adder(cdr lst))), который обернут вокруг него слишком много паренов. Это заставит Схему попытаться оценить результат сумматора (который является числом) как процедуру (ошибка!).

0 голосов
/ 09 ноября 2010

В Common Lisp:

(reduce #'+ '(1 #\a #\b 2 1 2 #\c #\d 4)
        :key (lambda (item) (if (numberp item) item 0)))

или

(loop for item in '(1 #\a #\b 2 1 2 #\c #\d 4)
      when (numberp item) sum item)
0 голосов
/ 04 ноября 2010

Вы должны заметить, что эта функция более или менее равна sum, которую можно определить просто с помощью fold.

(define (adder lst)
   (fold + 0 lst))

Что делает фолд?По сути, он определен так:

(define (fold f initial lst)
  (if (null? lst)
     initial
     (fold f (f (car lst) initial) (cdr lst))))

(Другими словами, он вызывает функцию f, состоящую из 2 аргументов, для каждого элемента lst, используя в качестве первого аргумента автомобиль из lst, инакопленный результат в качестве второго аргумента для f.)

Проблема, на которую вам нужно обратить внимание, заключается в том, что + не знает, как работать с нечисловыми значениями.Нет проблем, вы уже имели дело с этим.Что будет, если это персонаж?Ну, вы ничего не добавляете к общей стоимости, поэтому замените его на 0. Поэтому ваше решение так же просто, как:

(define (adder lst)
   (fold your-new-protected-+ 0 lst))
...