簡體   English   中英

使用Scheme,我如何合並兩個以上的列表

[英]Using Scheme, how do I merge more than two lists

我正在嘗試在計划中合並多個列表。 我必須確保對最終列表進行了排序,但是幸運的是,這不會太難,因為必須對給定的列表進行排序。 另一方面,我還必須檢查列表是否已排序。

這是我到目前為止的代碼:

/ * mergeALot未完成; 由於某種原因,我在“和”以及“其他”上收到語法錯誤。 另外,我不知道如何檢查第一個元素是否為列表(停止迭代)* /

(define (mergeALot a)
(cond (and
     ordered? (car a)
     ordered? (cadr a))
      (mergeALot(cons
                (merge (car a)(cadr a))
                (cdr (cdr a))))
(else
 (display "Some lists are not ordered"))))


(define (ordered? lst)
  (cond ((null? lst) #t)
        ((eq? (length lst) 1) #t)
  ((> (car (cdr lst)) (car lst))
    (ordered? (cdr lst)))
  (else #f))
 )

(define (merge a b)
  (cond ((null? a) b)
    ((null? b) a)
    ((>= (car a) (car b))
     (cons (car b) (merge a (cdr b))))
    (else
     (cons (car a) (merge (cdr a) b)))))

這看起來有點像功課,但我會給你基本的想法。 您可能會獲得列表列表。 由於術語有些失控,因此我們將列表列表稱為未合並列表。 如果未合並列表中只有一個列表,那么您就完成了! 但是說有兩個。 未合並列表中有兩個列表。 然后,您需要一個使用兩個列表並產生合並結果的函數。 然后,我必須更新未合並列表。 如果我的函數被稱為:合並排序,則可能有:

(cons (my-merge (first unmerged-lists) (second unmerged-lists))
      (rest (rest unmerged-lists)))

您將繼續這樣做,直到未合並列表僅包含一個元素,此時您將停止,因為當列表僅包含一個元素時您將無法使用(休息(休息列表))。 希望你能得到遞歸!

有兩種進行多路合並的基本方法。

第一種方法是連續合並列表:合並前兩個列表。 然后將第三個列表合並到前兩個列表的合並中。 然后將第四個列表合並到前三個列表的合並中。 等等。

第二種方法使用堆,並且速度更快。 創建一個每個列表一個節點的堆,並按每個列表中的最小項排序。 然后重復從堆中提取最小的項,然后重新堆。

假設您有3個排序列表:

unmerged: ((1 2 3) (3 5 6) (1 4 5))

找到最小值

找到第一個元素最少的列表。 在下文中,我將其稱為min-listmin是該min-list的第一個元素:

min-list: (1 2 3)
min: 1

遞歸調用

min值限制為遞歸調用的結果,以使用相同的未unmerged列表進行merge-all ,除了用(cdr min-list)代替min-list 所有其他列表保持不變。 在您的示例中,就好像您調用了:

(cons 1 (merge-all '((2 3) (3 5 6) (1 4 5))))

例如,您計算遞歸未unmerged列表的方式如下:

(map (lambda (u) (if (eq? u min-list) (cdr u) u)) unmerged) 

終止條件

您應該忽略未unmerged列表中的任何空列表,並在所有列表為空后立即停止遞歸。 或者,請始終從未unmerged列表中刪除空列表,並在未unmerged列表為空時停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM