1

さて、Scheme を使用して、各 [number] がリスト内に出現した回数を数えたいと思います。

どうやってやるの ?また、指定された番号のカウンターを保存して、新しいリストを再構築したいと思います。

たとえば、次のリストがあります((1 2)(2 5)(5 7)(7 8)(6 8)(4 6)(3 4)(1 3)(4 8))

最初にリストを平坦化してから、各番号にカウンターを設定することを考えていました(方法がわからない)。そして、元の番号に対応する新しいリストを再構築します。(これは難しいかもしれません。一時変数を保存する必要がありますか?)

この例から、番号 1 が 2 回表示され、番号 2 が 2 回表示され、番号 3 が 2 回表示されるなどと言うと、新しいリストを次のように再作成したいと思います。

(1 2) (2 2) (3 2) (4 3) (5 2) (7 2) (6 2) (8 3)

どうすればこれを達成できますか?

アップデート:

このようなインクリメントカウンターヘルパーを実装することを考えていましたか?

 (define inc-counter 
    (let ((counter 0)) 
      (lambda () (set! counter (+ counter 1))))) 
4

4 に答える 4

3

良い答えは、主に実装によって異なります(モジュロR6RS)。PLTスキームの場合、これを行う簡単な定義を次に示します。リストのフラット化を回避します。各アイテムをスキャンするだけでよいため、ツリーのスキャンが非常に単純な場合は、新しいコピーを作成しても意味がありません。また、この関数は結果のリストをソートします(ハッシュテーブルから出る途中ですべてスクランブルされるため)。まったく異なる実装を使用している場合でも、次のように簡単に翻訳できます。

(define (counts x)
  (define t (make-hash))
  (define (scan x)
    (if (list? x)
      (for-each scan x)
      (hash-set! t x (add1 (hash-ref t x 0)))))
  (scan x)
  (sort (hash-map t list) < #:key car))

(ところで、これが何らかのハードウェアの質問である場合、このコードは実用的すぎて答えとしては役立たないことに注意してください...)

于 2009-11-13T14:19:48.260 に答える
1

accumulator パラメーターを使用して、それぞれが出現した回数の関連リストを保持するフラット化を行います。そうすれば、ループのたびに必要なすべてのデータを取得できます。

たとえば、階乗は次のように記述できます。

(define (factorial num accum)
  (if (= num 0) accum (factorial (- num 1) (* accum num)))

そして、それを (階乗 10 1) で呼び出します。最後に、アキュムレータの値は関数の結果です。あなたの例では、 flatten を呼び出して各数値が出現した回数を追跡する小さなヘルパー関数を作成します。

于 2009-11-13T13:37:44.503 に答える
0

数値をその出現回数にマッピングするハッシュテーブルを使用できます。で作成します(make-hash)

于 2009-11-13T13:53:36.187 に答える
0

partitionおそらく最も効率的な解決策ではありませんが、リストに要素がなくなるまで最初の要素でリストを ing することでこれを達成できると思います。要素内のリストは、リスト内の最初の数値と同じすべての数値になります。リストに要素がなくなるまで、このプロセスを out-element のリストで繰り返すことができます。

于 2009-11-13T13:38:26.717 に答える