2013-04-10 80 views
0

我是一個初學者,我試圖學習一些算術遞歸。我似乎無法圍繞使用方案來做這件事併產生正確的結果。對於我的例子,我試圖通過對字符串中的每個字符進行算術運算來爲字符串生成一個整數鍵。在這種情況下,字符串是一個列表,例如:'(h e l l o)。我需要執行的算術如下:算術遞歸

對於字符串中的每個字符do - >(33 * constant +字母在字母表中的位置) 其中常量是輸入並且字符串以列表形式輸入。

到目前爲止,我有這樣的:

(define alphaTest 
    (lambda (x) 
    (cond ((eq? x 'a) 1) 
      ((eq? x 'b) 2)))) 

(define test 
    (lambda (string constant) 
     (if (null? string) 1 
     (* (+ (* 33 constant) (alphaTest (car string))) (test (cdr string))) 

我想測試一個簡單的字符串(測試「(A B)2),但我不能產生正確的結果。我意識到我的遞歸必定是錯誤的,但我一直在玩它幾個小時,每次都碰壁。任何人都可以提供任何幫助實現這種算術遞歸?謝謝,麻煩您了。請記住我在Scheme語言的業餘:)

編輯 我想向被輸入的常數通過使新常數=(+(* 33常數通過串的每次迭代變化)( alphaTest(車串)))。我期待輸入字符串'(ab)和常數2的輸出應該如下:

第一次迭代'(a):(+(* 33 2)(1))= 67總和= 67,常數變67
第二次迭代「(b):(+(33 * 67)(2))= 2213和= 2213,不斷成爲2213

(test '(a b) 2) => 2280 
+0

您已經描述瞭如何對字符串的每個字符執行操作,但沒有說明如何組合每個字符的結果以提供最終的單個數字。另外,如果你描述了'(test'(#\ a#\ b)2)' – GoZoner 2013-04-10 14:08:24

+0

我更新了問題的預期結果,它會有所幫助。感謝的GoZoner。 – Sixers17 2013-04-10 17:52:44

回答

1

這是你在找什麼?

(define position-in-alphabet 
    (let ([A (- (char->integer #\A) 1)]) 
    (λ (ch) 
     (- (char->integer (char-upcase ch)) A)))) 

(define make-key 
    (λ (s constant) 
    (let loop ([s s] [constant constant] [sum 0]) 
     (cond 
     [(null? s) 
      sum] 
     [else 
      (let ([delta (+ (* 33 constant) (position-in-alphabet (car s)))]) 
      (loop (cdr s) delta (+ sum delta)))])))) 

(make-key (string->list) 2) => 0 
(make-key (string->list ab) 2) => 2280 

順便說一句,是否應該對包含字母數字或空格以外字符的字符串起作用?在這種情況下,position-in-alphabet可能會產生一些令人驚訝的結果。要製作一個體面的鑰匙,您可以撥打char->integer,不要打擾position-in-alphabetchar->integer會爲您提供每個字符的不同數字,而不僅僅是字母表中的每個字母。

+0

感謝您的及時回覆本!要回答你的問題,不,我沒有考慮到字符串中的特殊字符,只有字母。你的代碼工作,但我忘了提到,我需要不斷更新常數,通過設置它等於每次迭代的總和。我試着向循環(x常量)中添加另一個參數,然後在調用循環時,添加(* 1 sum)以x的形式傳遞,但是在這種情況下它將0看作sum。我該怎麼做才能將總和的結果作爲新常數傳遞給我? – Sixers17 2013-04-10 06:13:11

+1

現在我想我明白了。在這種情況下,您可以使用當前常量計算總和,只需在第一次迭代中將新和數作爲新常數進行計算。我編輯瞭解決方案來說明。或者,如果常量應該是零長度字符串的關鍵字,那麼Ankur的解決方案是正確的。 – 2013-04-10 12:08:31

+0

感謝您更新您的解決方案。你給我的是非常有幫助的,非常感謝。我幾乎完成了這一點,但我的意思是不斷更新的是我不希望常量是:新的常量+總和,而只是新的常數而不加總和。我會通過更新我原來的問題並得到預期結果來澄清這一點。 – Sixers17 2013-04-10 17:45:46

1
(define position-in-alphabet 
    (let ([A (- (char->integer #\A) 1)]) 
    (lambda (ch) 
     (- (char->integer (char-upcase ch)) A)))) 


(define (test chars constant) 
    (define (loop chars result) 
    (if (null? chars) 
     result 
     (let ((r (+ (* 33 result) (position-in-alphabet (car chars))))) 
      (loop (rest chars) (+ r result))))) 
    (loop chars constant)) 

(test (list #\a #\b) 2) 
0

這裏有一個解決方案(在MIT-GNU計劃):

(define (alphaTest x) 
    (cond ((eq? x 'a) 1) 
    ((eq? x 'b) 2))) 

(define (test string constant) 
    (if (null? string) 
     constant 
     (test (cdr string) 
     (+ (* 33 constant) (alphaTest (car string)))))) 

樣品輸出:

(test '(a) 2) 
;Value: 67 

(test '(a b) 2) 
;Value: 2213 

我只是變換不斷的在每個遞歸調用和返回它的值當字符串用完時。

我擺脫了lambda表達式,使其更容易看到發生了什麼。 (另外,在這種情況下,lambda表單並不是真的需要。)


你的測試程序定義似乎被打破:

(define test 
    (lambda (string constant) 
    (if (null? string) 
    1 
    (* (+ (* 33 constant) 
      (alphaTest (car string))) 
     (test (cdr string))) 

您的代碼讀作:

  • 創建過程test其接受兩個參數; stringconstant

  • 如果string爲空,則傳遞值1以結束遞歸。否則,乘以下面的值:

    • 一些項x即=(33 *常數)+(alphaTest(汽車字符串)),和
    • 一些術語ÿ即遞歸地傳遞輸出(CDR串)在測試過程

我沒有看到長期Ÿ將如何評價,如「測試」需要兩個參數。我的翻譯出錯了。另外,括號不平衡。而且我無法忍受的計算有些奇怪 - 嘗試做一篇論文評估,看看在每次遞歸調用中可能會計算出什麼。