Racket - Добавить или удалить элемент из 2dlist - PullRequest
0 голосов
/ 30 октября 2019

Я делаю задачу, которая просит меня написать функцию, которая использует список (dict1) и список (действие), который содержит действие (удалить или добавить) и значение. Обновления должны соответствовать следующим спецификациям:

• Если первый элемент действия «удалить», а ключ находится в словаре, то соответствующее значение в связанном списке следует удалить.

• Если совпадающее значение оказывается последним элементом в связанном списке, то ключ должен оставаться в словаре, но связанный список становится пустым. Если значение отсутствует в словаре, словарь не изменяется.

• Если значение act равно «add» и ключ находится в словаре, то новое значение следует добавить в связанный список в словаре, если оно еще не существует. Если значение уже существует всвязанный список, обновленный словарь не изменится.

• Если значение act равно «add», а ключ не существует в словаре, то следует добавить новую запись списка ассоциаций для ключа. словарь.

Например:

(define dict1 (list (list "Num" (list 5 1.3 -1))
 (list "Char" (list #\p))
 (list "Str"
 (list "cs" "CS" "Computer Science"))))

Тогда

(update dict1 (list "add" true)) =>
(list (list "Num" (list 5 1.3 -1))
      (list "Bool" (list true))
      (list "Char" (list #\p))
      (list "Str" (list "cs" "CS" "Computer Science")))

(update dict1 (list "remove" "cs")) =>
(list (list "Num" (list 5 1.3 -1))
      (list "Char" (list #\p))
      (list "Str" (list "CS" "Computer Science")))

Я мог бы только сделать первый шаг, вот что я имею до сих пор:

(define (update dict1 act)
  (cond
    [(equal? (first act) "remove") (remove-value dict1 (second act))]
    [(equal? (first act) "add") (add-value dict1 (second act))]))

Для этого вопроса мне разрешено использовать только member? или remove. Я знал, что задавал много вопросов в последние пару дней, но я новичок в рэкетах и ​​прилагаю все усилия, чтобы научиться этому :( Пожалуйста, помогите

1 Ответ

0 голосов
/ 30 октября 2019
  • dict1 каждый подсписок мы называем его поддиктом (список поддикта1 субдикта2 субдикта3 субдикта4)
  • поддиректория состоит из двух частей. Мы называем это title и data.
  • мы называем input, имеют 3 части (2 переменные): dict, action, new-data
  • функция index-title находит, какой поддикт должен быть изменен.
  • Функция build-new-sub-dict состоит из двух частей. Если входной номер равен индексу. Выберите sub-dict (нужно изменить), действие и новые данные, а затем отправьте их в action-data (функция). Или выберите данный поддикт.
  • Функция «действие-данные» изменяет данные с помощью данного действия и новых данных.
  • Действие - удаление или добавление. Итак, нам нужна вспомогательная функция: существовать ?, добавить-если-не-существовать, удалить

Нам нужно добавить новые данные в dict1. Сначала мы проверяем тип новых данных. Тогда мы знали, какой субдикт является тем, что нам действительно нужно. И мы перестроили все dict1 с помощью build-new-dict с данным правилом. Некоторое подчинение не нужно менять, мы не меняемся. Для замены sub-dict мы используем функцию build-new-sub-dict.

Нет набора! нет локальной версии


(define dict1
  (list (list "Num" (list 1 2 3))
        (list "Char" (list #\p))
        (list "Bool" '())
        (list "Str" (list "a" "b" "c"))))



(define (index-title action)
  (cond
    [(number? (second action)) 0]
    [(char? (second action)) 1]
    [(boolean? (second action)) 2]
    [(string? (second action)) 3]
    [else (error "type error")]))


(define (my-remove word lst)
  (cond
    [(empty? lst) empty]
    [(equal? word (first lst))
     (rest lst)]
    [else
     (cons (first lst)
           (my-remove word (rest lst)))]))


(define (exist? word lst)
  (cond
    [(empty? lst) #f]
    [(equal? word (first lst)) #t]
    [else
     (exist? word (rest lst))]))

(define (add-if-not-exist word data)
  (if (exist? word data) data (cons word data)))

(define (action-to-data word data action)
  (cond
    [(equal? action "add")
     (add-if-not-exist word data)]
    [(equal? action "remove")
     (my-remove word data)]))


(define (build-new-dict i n dict act a-function)
  (cond
    [(= i n) empty]
    [else
     (cons (a-function i dict act)
           (build-new-dict (+ i 1) n dict act a-function))]))


(define (build-new-sub-dict n dict act)
  (cond
    [(= n (index-title act))
     (list (first (list-ref dict n))
           (action-to-data (second act) (second (my-list-ref dict n)) (first act)))]
    [else
     (list-ref dict n)]))


(define (my-list-ref lst n)
  (cond
    [(< n 0) (error "error")]
    [(= n 0) (first lst)]
    [else
     (my-list-ref (rest lst) (- n 1))]))


(define (update dict act-ls)
  (cond
    [(empty? act-ls) dict]
    [else
     (update
      (build-new-dict 0
                      (length dict)
                      dict
                      (first act-ls)
                      build-new-sub-dict)
      (rest act-ls))]))

;;; Test
(define act-list
  '(("add" 4) ("add" "d") ("add" #\s) ("add" #true) ("add" #false)
              ("remove" 2) ("remove" #\p) ("remove" #false) ("remove" "c") ("remove" "b")))
(update dict1 act-list)
dict1 ; no change

Используйте набор! и локальная версия

(define dict1
  (list (list "Num" (list 1 2 3))
        (list "Char" (list #\p))
        (list "Bool" '())
        (list "Str" (list "a" "b" "c"))))

; define similar sugar syntax (if you don't want to use)
(define (my-list-ref lst n)
  (cond
    [(< n 0) (error "error")]
    [(= n 0) (first lst)]
    [else
     (my-list-ref (rest lst) (- n 1))]))

; (my-list-ref '(0 1 2 3) 0)

; you can remove all word on list or remove first one. Here we remove first
(define (my-remove word lst)
  (cond
    [(empty? lst) empty]
    [(equal? word (first lst))
     (rest lst)]
    [else
     (cons (first lst)
           (my-remove word (rest lst)))]))

; (my-remove 1 '(5 4 3 2 1 0 1 2 3 4)


(define (my-build-list n a-function)
  (local ((define (aux i) 
            (cond
              [(= i n) empty]
              [else
               (cons (a-function i)
                     (aux (+ i 1)))])))
    (aux 0)))

;(my-build-list 10 add1)

(define (update dict act)
  (local ((define (exist? word lst)
            (cond
              [(empty? lst) #f]
              [(equal? word (first lst)) #t]
              [else
               (exist? word (rest lst))]))

          (define (add-if-not-exist word data)
            (if (exist? word data)
                data
                (cons word data)))

          (define (action-to-data word data action)
            (cond
              [(equal? action "add")
               (add-if-not-exist word data)]
              [(equal? action "remove")
               (my-remove word data)]))

          (define (index-title action)
            (local ((define action-type (second action)))
              (cond
                [(number? action-type) 0]
                [(char? action-type) 1]
                [(boolean? action-type) 2]
                [(string? action-type) 3]
                [else (error "type error")])))

          (define word (second act))
          (define action (first act))
          (define row-index (index-title act))

          (define (build-new-sub-dict n)
            (cond
              [(= n row-index)
               (list (first (my-list-ref dict n))
                     (action-to-data word (second (my-list-ref dict n)) action))]
              [else
               (my-list-ref dict n)])))

    ; or just
    ; (set! dict1 (my-build-list (length dict) build-new-sub-dict))
    (begin (set! dict1 (my-build-list (length dict) build-new-sub-dict))
           dict1)))
; TEST
(update dict1 '("add" #true))
(update dict1 '("add" #true))
(update dict1 '("remove" #false))
(update dict1 '("add" #false))
(update dict1 '("remove" #true))


(update dict1 '("add" 2))
(update dict1 '("remove" 3))
(update dict1 '("add" 4))
(update dict1 '("add" 4))
(update dict1 '("remove" 1))
(update dict1 '("remove" 2))

(update dict1 '("remove" "b"))
(update dict1 '("add" "d"))


(update dict1 '("add" #\x))
(update dict1 '("remove" #\p))

Используйте набор! нет локальной версии

(define dict1
  (list (list "Num" (list 1 2 3))
        (list "Char" (list #\p))
        (list "Bool" '())
        (list "Str" (list "a" "b" "c"))))

(define (index-title action)
  (cond
    [(number? (second action)) 0]
    [(char? (second action)) 1]
    [(boolean? (second action)) 2]
    [(string? (second action)) 3]
    [else (error "type error")]))


(define (my-remove word lst)
  (cond
    [(empty? lst) empty]
    [(equal? word (first lst))
     (rest lst)]
    [else
     (cons (first lst)
           (my-remove word (rest lst)))]))


(define (exist? word lst)
  (cond
    [(empty? lst) #f]
    [(equal? word (first lst)) #t]
    [else
     (exist? word (rest lst))]))

(define (add-if-not-exist word data)
  (if (exist? word data)
      data
      (cons word data)))

(define (action-to-data word data action)
  (cond
    [(equal? action "add")
     (add-if-not-exist word data)]
    [(equal? action "remove")
     (my-remove word data)]))


(define (aux-build-list i n dict act a-function)
  (cond
    [(= i n) empty]
    [else
     (cons (a-function i dict act)
           (aux-build-list (+ i 1) n dict act a-function))]))


(define (my-build-list n dict act a-function)
  (aux-build-list 0 n dict act a-function))


(define (build-new-sub-dict n dict act)
  (cond
    [(= n (index-title act))
     (list (first (list-ref dict n))
           (action-to-data (second act) (second (my-list-ref dict n)) (first act)))]
    [else
     (list-ref dict n)]))


(define (my-list-ref lst n)
  (cond
    [(< n 0) (error "error")]
    [(= n 0) (first lst)]
    [else
     (my-list-ref (rest lst) (- n 1))]))


(define (update dict act)
  (set! dict1
        (my-build-list (length dict)
                       dict
                       act
                       (lambda (n dict act) (build-new-sub-dict n dict act)))))

;;; Test
(update dict1 '("add" 2))
(update dict1 '("remove" 3))
(update dict1 '("add" 4))
(update dict1 '("add" 4))
(update dict1 '("remove" 1))
(update dict1 '("remove" 2))
dict1
...