3

再帰を使用せずに文字列のリストから単一の文字にアクセスする方法を理解するのに問題がありますが、代わりにバックトラックします。

たとえば、この文字列のリストがあり、これらの文字列の1つ('。''o'、'*')から1文字を返すことができるようにしたいと考えています。私が取り組んでいるプログラムは、それを行と列として扱っています。私のデータベースでは、次のような事実があります。

matrix(["...o....",
        ".******.",
        "...o....",
        ".*...*..",
        "..o..*..",
        ".....*..",
        ".o...*..",
        "....o..o"].

私は述語を持っています:

get(Row,Col,TheChar) :- 

行と列の番号(インデックスは1から始まります)を受け取り、その特定の行と列のエントリ(TheEntry)を返します。

述語の頭が正しく構築されていない可能性があると感じていますが、リスト内の各文字列を再帰せずに文字ごとに調べて返す方法に焦点を当てています。

私はプロローグに不慣れで、これに大きな困難を抱えています。

どんな助けでも大歓迎です!

ありがとうございました!

4

2 に答える 2

3

get/3の実装は次のようになります。

get(Row,Col,TheChar) :-    
   matrix(M),
   nth(Row,M,RowList),
   nth(Col,RowList,TheChar).

TheCharは文字コードに統合されていることに注意してください。

| ?- get(1,4,X).
X = 111

文字を表示したい場合は、たとえばアトムコードを使用できます。

| ?- get(4,2,X), atom_codes(CharAtom,[X]).
X = 42
CharAtom = *

お役に立てれば。

于 2011-10-27T07:53:13.810 に答える
1

行列表現を使用すると、次のようなことができます。

cell(X、Y、Cell):-matrix(Rows)、Matrix = .. [matrix | Rows]、arg(X、Matrix、Cols)、Row = .. [row | Cols]、arg(Y、Row、セル)。

を使用=..してその場で用語を作成することは、マトリックス表現が最適ではないことを示唆している可能性があります。マトリックスのさまざまな表現を検討する場合があります。

固定長の行を持つ「標準」行列を想定すると、行列を表すことができます

A B C D
E F G H
I J K L

いくつかの異なる方法で:

  • セル値を単一の文字として表すことができ、プロローグが(char-atomsのリストとしての文字列ではなく)実際の文字列をサポートしている場合は、単一の文字列:

    "ABCDEFGHIJKL"
    

    ルックアップは単純でゼロ相対です(たとえば、最初の行と最初の列は両方とも0の番号が付けられます)。

    ( RowLength * RowOffset ) + ColOffset
    

    アトム内の適切な文字へのインデックスを提供します。取得は、単純な部分文字列操作で構成されます。これには、速度と単純さという利点があります。

  • 複合語は別のオプションです。

    matrix( rows( row('A','B','C','D') ,
                  row('E','F','G','H') ,
                  row('I','J','K','L')
                )
          ).
    

    ルックアップはまだ簡単です:

    cell(X、Y、Matrix、Value):-arg(X、Matrix、Row)、arg(Y、Matrix、Cell)。

  • 3番目のオプションは、データベースを使用してasserta、データベース述語、、、、、、、、を使用して行列をより直接的に表すことです。たとえば、次の行に沿ってデータベースにファクトの構造を構築できます。assertzretractretractallrecordarecordzrecordederase

    matrix( Matrix_Name ).
    
    matrix_cell( Matrix_Name , RowNumber , ColumnNumber , Value ).
    

    これには、スパース(空のセルを表す必要がない)とギザギザ(行の長さを変えることができる)の両方の表現を可能にするという利点があります。

  • 別のオプション(最後の手段、あなたが言うかもしれない)は、あなたのプロローグがそれを許すなら、手続き型言語に飛び出して、より...マトリックスのような方法でマトリックスを表現することです。私は一度それをしなければなりませんでした:データモデルが特定のサイズを超えると、メモリとCPUの両方で大きなパフォーマンスの問題に遭遇しました。私たちの解決策は、必要な関係をビットの巨大な配列として表すことでした。これは、Cで行うのは簡単でした(Prologではそれほど多くはありませんでした)。

行列を表現する他の方法も思いつくと思います。

彼らがPerlコミュニティで言うように、 TMTOWTDI(Tim-Toadyまたは「それを行うには複数の方法があります」)。

于 2011-10-27T17:27:12.457 に答える