1

開始リストとすべてのサブリストのn番目の位置にある要素を削除する関数が必要です。動作するコードは必要ありません。アドバイスが必要です。

4

3 に答える 3

3

最終的な解決策ではなく、アドバイスを求めることは称賛に値します。私はあなたにそれを説明しようとします。

片方向リストは、最初から最後まで再帰的に処理されるのに適しています。リストの最初の要素と残りの要素を取得し、新しい要素を前に置いてリストを構築する安価な操作があります。1 つの単純な再帰スキームは次のようになります: リストから最初の要素を取得し、それで何かを行い、リストの残りの部分でプロセス全体を繰り返した結果の先頭に配置します。この一連の要素と休符のプロセスの繰り返しが再帰部分です。入力リストが空の場合は、何もする必要がなく、空のリストが返され、処理が終了します。これは、基本ケース、アンカー、または任意の名前です。覚えておいてください: 再帰ケース、基本ケース、チェック - 両方が必要です。

(Lisp の評価規則により、実際に処理済みの要素を処理済みの残りの要素の前に置くには、リストを構築する操作が新しいリストを返す前に両方の引数を評価するため、残りが実際に処理されるまで覚えておく必要があります。これらの中間結果これは大きなリストでは問題になるかもしれません. これを回避する方法はありますが, ここでは簡単にします.)

さて、実際には、単純なリストだけでなく、ツリーも求めています。便利なことに、そのツリーはネストされたリストとして表されるため、少し複雑なことを除いて、一般的には上記が引き続き適用されます。処理する要素自体がブランチ、つまりリストであるかどうかを確認する必要があります。そうである場合、プロセス全体もそのブランチで実行する必要があります。

基本的にはそれだけです。ツリーから要素を削除するには、要素が一致するかどうかを確認し、一致する場合は削除するだけです。さらに詳細に:

  • 空のリストから要素を削除するには、空のリストを返すだけです。

  • 最初の要素自体がリストの場合、最初の要素から構築されたリストを返します。最初の要素はすべての一致が削除され、残りの要素はすべての一致が削除されます。

  • 最初の要素が一致する場合、一致するすべての要素が削除された残りのリストを返します。(ここで何かが「ドロップ」されることに注意してください。)

  • それ以外の場合は、最初の要素から作成されたリストを最初として返し、リストの残りの部分をすべての一致する要素を削除して残りとして返します。

これを見て、再帰ケース、基本ケース、およびネストされたツリー構造のウォークを処理するものを見つけてみてください。これらがすべて理解できれば、実装は簡単です。これらすべてを実際に学んだことがなく、今でも頭が回転していない場合は、自分が生まれながらの Lisp プログラマーであると考えてください。そうでなければ、再帰は単なる基本的な概念であり、最初は理解するのが難しいかもしれませんが、一度クリックすると、自転車に乗るようなものになります。

Ed: どういうわけか、「位置」の部分を見逃して、読み間違えました – 質問のタイトルにもかかわらず。それが疲労が人にできることです。

とにかく、ツリー内の要素を位置で削除したい場合は、関数にオプションのカウンター引数を持たせることができます (または、それを提供するラッピング関数を使用できます)。上記のポイントを見ると、新しいブランチの再帰がカウンターをリセットする場所になります。基本的な再帰スキームは同じままですが、要素自体を比較する代わりに、カウンターをチェックします。削除したい位置と一致する場合は、要素を削除します。すべての再帰的なケースでは、インクリメントされたカウンターを関数に渡します。ただし、新しいブランチに入る場合は、カウンターをリセットします。つまり、カウンター引数に 0 を渡します。(要素がドロップされたら、リストの残りを返すこともできます。これにより、関数のパフォーマンスが向上します。特に、最初の近くの要素が削除される長いリストの場合は、

于 2013-03-12T02:53:18.313 に答える
-1

わかりました。必要なものはわかりました。

2つの関数が必要です

エントリ関数は、(DeleteHelper position position myList) のようなヘルパー関数を呼び出すだけです。

DeleteHelper は再帰的に自身を呼び出し、現在の位置が 0 でない場合はオプションでリストの現在の要素を含めます。 (cons (car myList) (DeleteHelper (- position 1) originalPosition (cdr myList)) など)

DeleteHelper がリストに遭遇した場合、元の受信位置にリセットされた位置でリストを再帰的にトラバースします。(cons (DeleteHelper originalPosition originalPosition (car myList)) (DeleteHelper (- position 1) originalPosition (cdr myList))) など

また、基本ケースにも注意してください(リスト全体をトラバースすると、空のリストが返されると思います)。

これにより、正しい方向に進むはずです。また、Lisp を書いてから数年経っているので、構文が少しずれている可能性があります。

于 2013-03-11T23:36:07.213 に答える