2011-10-27 196 views
3

我無法弄清楚如何從字符串列表中訪問單個字符而不使用遞歸,而是回溯。Prolog - 從列表中獲取元素

例如我有這個字符串列表,我希望能夠從這些字符串之一返回單個字符('。''o','*')。我正在處理的程序將其視爲行和列。這是我的數據庫中的事實是這樣的:

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

我有謂:

get(Row,Col,TheChar) :- 

,需要一個行和列數(用從1開始的索引),並返回條目( TheEntry)在特定的行和列。

我有一種感覺,我的謂詞頭可能無法正確構建,但我真的更關注如何通過字符逐個字符串地瀏覽每個字符串而無需遞歸併返回它。

我是新來的prolog和我有這個主要困難。

任何幫助都將不勝感激!

謝謝!

+0

你能解釋一下你的意思嗎?「通過列表中的每個字符串按字符而不遞歸」?如果你想遍歷一串不確定的長度,你將無法做到這一點,沒有某種類型的遞歸。只有當你知道字符串的長度時,你纔可以像寫n個子句(如果length = n)來訪問單個字符。 – twinterer

回答

3

的實現獲得/ 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 = * 

希望這會有所幫助。

+3

在swi-prolog中沒有'nnth',所以'get/3'不是真的正確和安全。有'nnth0/3'和'nth1/3'謂詞可能是有用的。 –

+0

這就是我也會這樣做的,以及dmalikov(+1)使用['nth0/3'](http://www.swi-prolog.org/pldoc/man?predicate= nth0%2F3)或'nth1/3',如果它們不存在於你的實現中,很容易實現。 – sharky

1

使用矩陣表示,你可以做這樣的事情:

細胞(X,Y,細胞): - 矩陣(行), 矩陣= .. [矩陣|行], ARG( X,Matrix,Cols), Row = .. [row | Cols], arg(Y,Row,Cell) 。

使用=..來動態構建術語可能暗示您的矩陣表示不是最好的。您可能會考慮對您的矩陣進行不同的表示。

假設固定長度行的「標準」矩陣,可以表示在幾個不同的方式矩陣

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

  • 單個串,如果該單元格的值可以表示爲單個字符,並且您的序言支持真正的字符串(而不是字符串作爲char-原子列表):

    "ABCDEFGHIJKL" 
    

    Lookup是簡單和零相(例如,第一行和第一列均爲編號爲0):

    (RowLength * RowOffset) + ColOffset 
    

    給你的索引在原子相應的字符。檢索由一個簡單的子字符串操作組成。這具有速度和簡單性的優點。

  • 化合物術語是另一種選擇:

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

    查找仍然是簡單的:

    細胞(X,Y,矩陣,值): - ARG(X,矩陣,行), (Y,Matrix,Cell) 。

  • 第三種選擇可能是使用數據庫來代表你的矩陣更直接地使用數據庫謂詞assertaassertzretractretractallrecordarecordzrecordederase。你可以建立事實的結構,例如在沿線的數據庫:

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

    這樣具有允許兩個稀疏(空細胞不需要被代表)和鋸齒(行可以改變的優勢長度)表示。

  • 如果你的序言允許的話,另一個選擇(最後的手段,你可能會說)會跳出一種程序語言,並以更像矩陣的方式表示矩陣。我必須這樣做一次:一旦數據模型超過了一定的大小,我們就會遇到內存和CPU兩方面的巨大性能問題。我們的解決方案是將所需的關係表示爲一個巨大的位數組,這在C中是微不足道的(在Prolog中並不那麼重要)。

我相信你可以想出其他表示矩陣的方法。

TMTOWTDI(Tim-Toady或「有很多方法可以做到這一點」),正如他們在Perl社區中所說的那樣。