Arhn - архитектура программирования

получение самого большого числа в списке в схеме

Я не понимаю, почему у меня функция получения наибольшего числа не хочет работать. Если я правильно думаю об этом, если первый атом меньше второго атома, вы вызываете функцию минус первый в списке, иначе вы создаете первый атом, самый большой, с остальной частью списка. соответствующий код:

(define (getlargest a_list)
  (cond
    ((null? a_list) '())
    ((< (car a_list) (cadr a_list)) (getlargest (cdr a_list)))
    (else (cons (car a_list) (getlargest(cdr a_list))))))
25.11.2014

Ответы:


1

Ваша текущая процедура дает сбой во время выполнения. Даже если это не так, вы сравниваете один элемент со следующим, но это не сработает для нахождения максимума, например, в таком списке он вернет 1, что неверно: '(10 2 0 1). Есть и другие ошибки, например, почему вы строите список в качестве вывода, когда ответ должен быть числом? также вы должны быть очень осторожны с пограничными случаями, ваша процедура не работает, когда в списке остается один элемент.

Правильный способ - сравнить один элемент, который считается максимальным, со всеми остальными, если мы найдем элемент, который больше предполагаемого максимума, то мы нашли новый максимум. Это то, что я имею в виду:

(define (getlargest a_list)
  (if (null? a_list) ; edge case: empty list
      #f             ; return a special value signaling error   
      (let loop ((a_list (cdr a_list))   ; rest of the list
                 (maxval (car a_list)))  ; assumed maximum
        (cond ((null? a_list) maxval)    ; if the list is empty, return max
              ((> (car a_list) maxval)   ; current element > max
               (loop (cdr a_list) (car a_list))) ; found new max
              (else                      ; otherwise
               (loop (cdr a_list) maxval))))))   ; keep the same max

Конечно, в реальной жизни мы бы использовали встроенную процедуру max для той же цели:

(apply max a_list)
25.11.2014
  • И встроенный max довольно легко реализовать с точки зрения SRFI 1 reduce: (define (max . items) (reduce (lambda (a b) (if (> a b) a b)) #f items)) 25.11.2014
  • На этой ноте, я думаю, вы забыли apply где-то в своем последнем абзаце.... 25.11.2014
  • @ChrisJester-Янг понял! 25.11.2014

  • 2

    В вашем коде 2 ошибки:

    1) в предложении else следует рекурсивно вызывать себя, отбрасывая второй элемент:

    (else (getlargest (cons (car a_list) (cddr a_list))))))
    

    2) вам не хватает случая списка только из одного элемента, где cadr не получится

    ((null? (cdr a_list)) (car a_list))
    

    И лично я предпочитаю возвращать #f, если список пуст. Таким образом, код будет выглядеть так

    (define (getlargest a_list)
      (cond
        ((null? a_list)       
         #f)
        ((null? (cdr a_list))
         (car a_list))
        ((< (car a_list) (cadr a_list))
         (getlargest (cdr a_list)))
        (else 
         (getlargest (cons (car a_list) (cddr a_list))))))
    

    Конечно, решение с использованием foldl предпочтительнее:

    (define (getlargest lst)
      (foldl (lambda (e r) (if (or (not r) (> e r)) e r))
             #f
             lst))
    

    или, возможно, немного более эффективно:

    (define (getlargest lst)
      (if (null? lst)
          #f
          (foldl (lambda (e r) (if (> e r) e r))
                 (car lst)
                 (cdr lst))))
    
    25.11.2014
  • Обе версии, конечно, верны, но я предпочитаю вторую. Первый передает максимальное значение в качестве первого элемента в списке, я бы предпочел добавить для этого новый параметр. Просто мои пять копеек ;) 25.11.2014
  • @ ÓscarLópez Конечно, но OP, вероятно, хочет знать, в чем проблема в их коде. 25.11.2014

  • 3

    Это неверно, потому что при вводе (maximum '(2 1)) возникает ошибка (любой тест с обратным порядком не проходит) Без цикла, с использованием рекурсии:

    (define (maximum L)
         (if (null? (cdr L)) 
             (car L) 
             (if (< (car L) (maximum (cdr L)))  
                 (maximum (cdr L)) 
                 (car L)
             )
        )
    )
    
    25.02.2017
  • экспоненциальный код? В самом деле? 15.05.2021

  • 4

    Первая ошибка заключается в том, что вы возвращаете список в качестве вывода в базовом случае. Вам нужно вернуть число. Вы можете реализовать эту процедуру рекурсивным способом, сохраняя максимальное значение в аккумуляторе MaxVal, когда мы рекурсивно проходим по списку.

    Спецификация

    ввод : список положительных уникальных чисел inList

    выход: максимальное значение в списке MaxVal

    Ниже приведена реализация приведенной выше спецификации:

    Процедура

    (define (GetMaxVal MaxVal inList) 
        (cond ( (null? inList ) MaxVal )
              ( (> (car inList) MaxVal ) (GetMaxVal (car inList) (cdr inList)) ) 
              ( else ( GetMaxVal MaxVal (cdr inList)) ) ))
    
    (define inList '(1 67 3 5 176 4745 34 575)) 
    
    (display (GetMaxVal 0  inList) ) ; prints 4745 to screen
    

    Пояснение

    1. Если список пуст, мы достигли базового случая, поэтому возвращаем MaxVal
    2. Если первый элемент в списке больше MaxVal, чем обновление MaxVal; передать MaxVal и (cdr inList) в качестве аргумента при рекурсивном вызове.
    3. else первый элемент не больше, поэтому рекурсивно передавайте список без первого элемента, т.е. (cdr inList)
    15.10.2020
  • положительный? Зачем? положительного в вопросе нет. 15.05.2021

  • 5
    ;; ListOfNum Number -> Number
    (define (list-maximum-core lon max)
      (cond
        [(empty? lon) max]   ; base case
        [else
          (list-maximum-core (rest lon) (if (> (first lon) max) (first lon) max) )] ))
    
    ;; ListOfNum -> Number
    (define (list-maximum-main lon)
      (list-maximum-core lon 0) )
    
    • При вызове функции list-maximum-core сделайте max = 0 в качестве начального значения max
    • В каждом рекурсивном цикле списка мы проверяем, больше ли первый элемент в списке, чем max; если да, то это значение передается в переменную max; если нет, то максимальное значение переменной не меняется
    • В каждом рекурсивном цикле первый элемент списка удаляется, а список становится меньше; это продолжается до тех пор, пока список не станет пустым, и в это время он выводит любое значение max в это время (когда базовый случай истинен)
    • Чтобы избежать неудобств, связанных с добавлением 0 в качестве второй переменной каждый раз, когда вы вызываете функцию, мы создаем функцию list-maximum-main.
    15.05.2021
  • так что для ввода '(-1 -2 -3) вывод ..... ? 15.05.2021
  • Хорошая точка зрения. Я использую его для сценария, в котором задействованы только положительные числа; Мне также приходилось иметь дело с некоторыми нечисловыми экземплярами внутри моих списков, но я удалил этот код для ясности. Чтобы иметь дело с отрицательными числами, я думаю, вы можете сделать начальное значение переменной «max» пустым списком вместо числа 0, потому что использование числа мешает при работе с отрицаниями. Я могу опубликовать этот код, он просто немного сложнее, что, как правило, затемняет идею, хотя структура такая же. Я не могу найти умного способа сохранить максимальное значение внутри тела рекурсии, но я не эксперт. 16.05.2021

  • 6
    (define (max-list-element list)
      (define (aux list actual-max)
        (if (pair? (cdr list))
            (if (>= (car list) actual-max)
                (aux (cdr list) (car list))
                (aux (cdr list) actual-max))
            (if (> (car list) actual-max)
            (car list)
            actual-max)))
      (aux list (car list)))
    

    Моя реализация.

    21.05.2020
  • и поэтому вывод для ввода '() это..... ошибка? 15.05.2021
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..