Функция Scheme для возврата длинного из двух списков или true, если они равны - PullRequest
1 голос
/ 17 апреля 2019

Я новичок в схеме и работаю над проблемой, определенной следующим образом:

Напишите функцию с именем long-list, которая принимает два аргумента списка и возвращает более длинный список из двух входных данных.Если два списка имеют одинаковую длину, функция возвращает #t, а если один из аргументов не является списком, функция должна вернуть #f.Примечание. Вы не можете использовать предопределенную функцию длины;тем не менее, вы можете написать свою версию длины или другие вспомогательные функции, которые вы можете вызывать из более длинного списка.

Sample runs:

(longer-list '(1 2 3 4) '(a b c d e)) returns (a b c d e)
(longer-list '(d e f) '(4 5 6)) returns #t (or true)
(longer-list '(g h i) 3) returns #f (or false)

, что у меня пока есть:

;;helper function to determine the length of a list
(define (list-length lst)
  (if (null? length)
    0
    (+1 (list-length (cdr lst)))))

 ;;main function to return the longer of 2 lists or True if they are equal 
 (define (longer-list lst1 lst2)
   ;;check if both parameters are actually lists
   (and (list? lst1)
      (list? lst2)
      ;;if lst1 is the longer list return lst1
      (if(> (list-length lst1) (list-length lst2))
         lst1)
      ;;else lst2 is longer, return that 
      (else (> (list-length lst1 (list-length lst2))
         lst2))

     ;define comp as comparing list1 abbreviated by x and list2 abbreviated by y???
     (let comp ((x lst1) (y lst2))
       (cond
         ;;if both lists are null return true
         ((and (null? x) (null? y)) #t)
         ;;not sure what this means?
         ((null? x) lst2)
         ;;not sure what this means? 
         ((null? y) lst1)
         ;;else invoke comp after the first element of each list is removed???
         (else (comp (cdr x) (cdr y)))))))

В настоящее времяЯ получаю следующую ошибку:

"if: отсутствует выражение" else "в: (if (> (длина списка lst1) (длина списка lst2)) lst1)"

Мой вопрос заключается в том, что является причиной этой ошибки.Кроме того, я нашел этот код в Интернете и должен убедиться, что полностью его понимаю, поэтому, если кто-то сможет проверить мои комментарии, чтобы понять, имеют ли они смысл, это будет с благодарностью.

Ответы [ 2 ]

3 голосов
/ 17 апреля 2019

Ваше решение, конечно, хорошо. Ошибки в исходном коде были вызваны неправильным использованием if, пожалуйста, прочитайте документы . Код, который вы нашли в сети, просто обходит оба списка одновременно, и если один заканчивается раньше другого, это потому, что он короче.

Лучшим вариантом было бы просто использовать процедуру list-length, которая у вас уже есть - это имеет преимущество в том, что вам не нужно писать явный цикл. В Схеме мы пытаемся повторно использовать существующие процедуры вместо написания новых; например:

(define (list-length lst)
  (if (null? lst)
      0
      (+ 1 (list-length (cdr lst)))))

(define (longer-list lst1 lst2)
  (if (or (not (list? lst1)) (not (list? lst2)))
      #f
      (let ((len1 (list-length lst1))
            (len2 (list-length lst2)))
        (cond ((> len1 len2) lst1)
              ((< len1 len2) lst2)
              (else #t)))))

Работает как положено, и его легче понять!

(longer-list '(1 2 3 4) '(a b c d e))
=> '(a b c d e)
(longer-list '(d e f) '(4 5 6))
=> #t
(longer-list '(g h i) 3)
=> #f
1 голос
/ 17 апреля 2019

похоже, это сработало

#lang racket

(define (longer-list lst1 lst2)
  (and (list? lst1)
     (list? lst2)

     (let comp ((x lst1) (y lst2))
       (cond
         ((and (null? x) (null? y)) #t)
         ((null? x) lst2)
         ((null? y) lst1)
         (else (comp (cdr x) (cdr y)))))))
...