2016-06-27 39 views
0

我正在使用臨時保持在臨時搜索列表中的值,從最大數量的臨時(temp-5)開始到最小數量的臨時(temp-1)。我想在search-list的undo函數中加上這個函數。如果我使用temp-100而不是temp-1到temp-5,如何將代碼行縮短爲循環?如果我使用「for循環」,我會在哪裏放置cond?縮短代碼的重複行

#lang racket 
(define temp-flag 0) 
(define temp-1 '()) 
(define temp-2 '()) 
(define temp-3 '()) 
(define temp-4 '()) 
(define temp-5 '()) 
(define search-list '(1 2 3 4 5 6 7 8 9 10)) 
(define (place-temp tf) 
    (cond 
    [(equal? tf 1) 
    (set! temp-1 search-list) 
    (set! temp-flag 5)] 
    [(equal? tf 2) 
    (set! temp-2 search-list) 
    (set! temp-flag 1)] 
    [(equal? tf 3) 
    (set! temp-3 search-list) (set! temp-flag 2)] 
    [(equal? tf 4) 
    (set! temp-4 search-list) (set! temp-flag 3)] 
    [(set! temp-5 search-list) (set! temp-flag 4)] 
    )) 

(place-temp temp-flag) 
+2

只需將臨時列表放在一個向量中,並使用'tf'作爲索引。 –

+0

什麼是較大的目標,這個地方溫度需要解決? – soegaard

回答

1

您的問題的基本解決方案是Michael Vehrs建議的。第(侵入性最小的)嘗試可能是這樣的:

(define temp-flag 0) 
    (define search-list '(1 2 3 4 5 6 7 8 9 10)) 

    (define *num-of-temps* 5) ;; you will just have to change it to 100 
    (define *temps* (make-vector *num-of-temps* '())) 

    (define (next-temp-flag tf) 
     (cond ((= tf 1) *num-of-temps*) 
     ((and (> tf 1) (< tf *num-of-temps*)) (- tf 1)) 
     (else (- *num-of-temps* 1)))) 

    (define (place-temp tf) 
     (vector-set! *temps* (- tf 1) search-list) 
     (set! temp-flag (next-temp-flag tf))) 

但從臨時標誌點它的工作原理完全一樣。但它不是一個很酷的程序,所以我們試着改進它。

首先,這下的臨時標誌是有點怪異,但它正是模擬了您對於COND語句的行爲TF臨時標誌。 我假設你正在使用臨時標誌僅用於索引溫度-1溫度-2等,你不很在乎TF大於5(或100,或一般比*臨時數*)。所以,首先你可以把它簡化一下:

(define (next-temp-flag tf) 
     (if (= tf 1) *num-of-temps* (- tf 1))) 

現在第二件事是,在位置向量(「」指標「」)(CF https://docs.racket-lang.org/reference/vectors.html)爲0,而不是1開始,所以例如您的temp-1現在*(vector-ref temps 0)*。所以,你可以使用「」這樣的「小號TF下降」:

(define (next-temp-flag tf) 
     (if (= tf 0) (- *num-of-temps* 1) (- tf 1))) 

    (define (place-temp tf) 
     (vector-set! *temps* tf search-list) 
     (set! temp-flag (next-temp-flag tf))) 

顯然(或沒有;))這下的臨時標誌可以與模函數現在表示:

(define (next-temp-flag tf) (modulo (- tf 1) *num-of-temps*)) 

...如果你想要一個較短的代碼,你也可以在temp-temp內聯它。

的最後一件事是命名約定:也許你剛剛使用這些定義 s到建立一個最小的例子,但如果你真的在你的項目中的這些「」全局變量',命名慣例是使用明星,所以你寧願使用* search-list ** temp-flag *。 另請注意,temp-temp正在引起副作用,因此您可能想將它稱爲place-temp!。如果你打算申請地方溫度!* temp-flag *只有您可以完全放棄參數。並且可能* temp-position *聽起來可能比* temp-flag *更容易,因爲它現在是一個位置。 所以總結起來,你可能會像這樣結束:

(define *num-of-temps* 5) ;; you will just have to change it to 100 
    (define *temps* (make-vector *num-of-temps* '())) 

    (define *temp-position* (- *num-of-temps* 1)) ;; because (modulo -1 n) is n-1. 
    (define *search-list* '(1 2 3 4 5 6 7 8 9 10)) 

    (define (place-temp!) 
     (vector-set! *temps* *temp-position* *search-list*) 
     (set! *temp-position* (modulo (- *temp-position* 1) *num-of-temps*))) 

    (place-temp!) 

對不起這是這麼長的答案,但正如詩人說:'我沒有足夠的時間來寫一個短的一個'。我還懷疑,如果你想實現撤銷,你可能需要其他的東西(一個堆棧而不是一個循環緩衝區) - 但是這超出了你的問題。

祝您的項目順利!我希望你習慣於計劃,你將更少地依賴於全局變量和過程,更多地依賴於本地綁定和函數(正如另一位詩人說的''保持功能我的朋友!'')。但事情需要時間,最重要的是你喜歡你的黑客。