方案

2015-04-18 63 views
0

中的(等於?)比較的類型不正確我正在編寫一個方案中的程序,該程序允許我管理與學生相關的信息列表。該列表中的每個元素都是包含關於學生的3個項目的另一個列表:ID(數字串),學生姓名(字符串)和等級(整數)。我目前正在嘗試編寫一個函數,按ID升序排列我的學生列表。隨着這個函數,我試圖寫兩個幫助函數,'最小'和'刪除'方案

我測試了我最小的函數,它正確返回最小的ID。現在我正在測試我的刪除功能,以查看它是否會返回帶有刪除最小ID的學生元素的列表:

當我撥打(顯示(刪除名單(最小名單(汽車(車名冊)) ))),我得到一個錯誤,說';作爲參數傳遞給string-> number的對象(「4」「lini」「94」)不是一個字符串。此次通話的最新列表是:((5 me 95)(4 lini 94)(3 rudy 93)(2 mark 92)(1 silas 91))。我使用了字符串 - >數字函數進行比較,所以我認爲它也可以在這裏工作,但我也沒有得到我想要甚至與之比較的列表的正確元素。這使我添加(汽車(汽車名冊)到第二個參數爲(等於?),它給了我錯誤';對象「5」,作爲第一個參數傳遞給汽車,是不正確的類型。 「

有誰知道我在做什麼錯在這裏? 我也使用一套限制!功能,do循環,並在排序功能的任何建。

(define smallest 
    (lambda (roster record) 
      (if (null? roster) 
       (begin (display record) record) 
       (if (> (string->number record) (string->number (car (car roster)))) 
        (smallest (cdr roster) (car(car roster))) 
        (smallest (cdr roster) record))) 
     )) 

(define remove 
    (lambda (roster record) 
    (if (equal? (string->number record) (string->number (car(car(car roster))))) 
      (cdr roster) 
      (remove (list (cdr roster) (car roster)) record) 
    ))) 

(define performtask 
    (lambda (n roster) 
     (cond ((= n 0) (begin 
         (display "\n\tOption 0.") 
         (display "\nReset Roster") 
         (menu '()) 
         )) 
       ((= n 1) (begin 
         (display "\n\tOption 1.") 
         (display "\nLoad Roster From File") 
         (menu roster) 
         )) 
       ((= n 2) (begin         
         (display "\n\tOption 2.") 
         (display "\nStore Roster To File") 
         (display (list (remove roster (smallest roster (car(car roster)))))) 
         (menu roster) 
         )) 
       ((= n 3) (begin         
         (display "\n\tOption 3.") 
         (display "\nDisplay Roster by ID") 
         (display "\nsmallest record is: ") 
         (smallest roster (car (car roster))) 
         (menu roster) 
         )) 
       ((= n 4) (begin         
         (display "\n\tOption 4.") 
         (display "\nDisplay Student Info") 
         (menu roster) 
         )) 
       ((= n 5) (begin         
         (display "\n\tOption 5.\n") 
         (display roster) 
         (newline) 
         (menu (cons (ano-read-3-items 0 '()) roster)) 
         )) 
       ((= n 6) (begin         
         (display "\n\tOption 6.") 
         (display "\nRemove a student from Roster") 
         (menu roster) 
         )) 
       ((= n 7) (begin(display "\n\tOption 7. Exit\n") 
         #t 
         )) 
       (else (begin 
         (display "\n\tTask No. ") 
         (display n) 
         (display " does not exit.\n\n") 
         (menu roster) 
        ) 
      ) 
     ) 
) 
) 

(define menu 
    (lambda (roster) 
     (begin 
      (display "\t============================\n") 
      (display "\t MENU\n") 
      (display "\t============================\n") 
      (display "\t0. Reset roster\n") 
      (display "\t1. Load roster from file\n") 
      (display "\t2. Store roster to file\n") 
      (display "\t3. Display roster sorted by ID\n") 
      (display "\t4. Display student information\n") 
      (display "\t5. Add a student to roster\n") 
      (display "\t6. Remove a student from roster\n") 
      (display "\t7. Exit\n") 
      (display "\tEnter your choice: ") 
      (performtask (read) roster) 
     ) 
) 
) 
+0

@Sylwester我對你的意思是端到端測試感到困惑嗎?你是指當我打電話給最小的電話作爲第二參數時刪除? –

回答

0

所以,你有問題如下:

(define roster '(("5" "me" 95) ("4" "lini" 94) ("3" "rudy" 93) ("2" "mark" 92) ("1" "silas" 91))) 
(remove roster "1") ; some error 

您的錯誤是這部零件:

(remove (list (cdr roster) (car roster)) record) 

想象一下,您發送的是(student1 student2),而student1不是要刪除的人。然後它以列表((student2) student1)作爲參數遞歸。圍繞錯誤的第二次顯示,因爲你正在尋找的數據是在一個低於你的預期的層。此外,這個列表並沒有縮短,所以如果你的測試沒有成功,你會得到無限的遞歸。

解決的辦法是提出答案。它與基本案例相匹配,當發現被移除的對象時,該基礎案例評估爲列表的尾部,因此之前的任何元素必須已經被consed,否則最終將刪除所有內容,直到您嘗試刪除的id爲止。它應該看起來像(cons non-match1 (cons non-match2 (cdr roster))因此遞歸發生在conscdr

(cons non-match (remove rest-of-list record)) 

你可能試圖通過訪問ID時加入另一個car解決這一問題?我看到,與smallest不同,它使用caar來獲取您在remove中使用caaar的ID。這是我看到的第一件事,我想知道爲什麼。