2012-01-05 46 views
1

我有一個給定的列表,表示一個二維列表x。此表包含的1兩「點」,你可以在下面的例子中看到:表中的序言點

xxxxxxxxxxxxxxxx 
xx1111xxxx111xxx 
xxx1111xxxx11xxx 
x1111xxxxxx111xx 

我只需要1第二點更改爲2如下面的例子:

xxxxxxxxxxxxxxxx 
xx1111xxxx222xxx 
xxx1111xxxx22xxx 
x1111xxxxxx222xx 

我需要一個叫做separate(L,M)謂詞會第一時間列表L,並會產生第二個圖表M

這將是極好的,如果我們能夠解決這個問題,而無需使用任何標準謂詞喜歡「的findall」等等......

+0

目前尚不清楚這些表格是如何表示的;你能舉個例子嗎?此外,你如何確定哪個「點」是第一個,哪個是第二個?你如何定義一個「點」? – 2012-01-05 14:47:29

+0

這些表是它們的元素是列表的列表。點是相鄰的元素,值爲1。我想通過將一個點的元素僅從1變爲2來分開這兩個點 – user1118501 2012-01-05 14:54:48

+0

沒有,沒有找到,對不起。 – 2012-01-08 16:57:25

回答

2

您可以使用定義語句語法(DCG)來實現有限狀態轉換器。雖然DCG在生產方面沒有提供太多的組合操作,但它們在實現識別方面非常出色。

所以你想要認識到的是兩種不同類型的1的運行。所以基本上我猜的輸入線看起來在如下擴展巴科斯範式(EBNF):

line :== exs run1 exs run2 exs | exs. 
exs :== { "x" } "x". 
run1 :== { "1" } "1". 
run2 :== { "1" } "1". 

對於識別問題,你可以寫一個DCG無屬性(接下來就是Prolog的文字,你可以把一個文件或直接通過諮詢一下吧 - [用戶]):

line --> exs, run1, exs, run2, exs | exs. 

run1 --> "1", run1. 
run1 --> "1". 

run2 --> "1", run2. 
run2 --> "1". 

exs --> "x", exs. 
exs --> "x". 

下面是一些例子運行:

?- phrase(line,"xxx"). 
Yes 
?- phrase(line,"xxx111xxx111xxx"). 
Yes 
?- phrase(line,"xxx111xxx"). 
No 

對於生產問題,你只可以將屬性添加到DCG。使用 差異列表最簡單的工作:

line(I,O) --> exs(I,H), run1(H,J), exs(J,K), run2(K,L), exs(L,O) | exs(I,O). 

run1([0'1|I],O) --> "1", run1(I,O). 
run1([0'1|H],H) --> "1". 

run2([0'2|I],O) --> "1", run2(I,O). 
run2([0'2|H],H) --> "1". 

exs([0'x|I],O) --> "x", exs(I,O). 
exs([0'x|H],H) --> "x". 

下面是一些例子運行:

?- phrase(line(R,[]),"xxx"). 
R = [120, 120, 120] 
?- phrase(line(R,[]),"xxx111xxx111xxx"). 
R = [120, 120, 120, 49, 49, 49, 120, 120, 120, 50, 50, 50, 120, 120, 120] 
?- phrase(line(R,[]),"xxx111xxx"). 
No 

注:0' 是Prolog的符號的字符代碼。在ascii中,我們有0'x = 120,0'1 = 49,0'2 = 50,這說明了結果。以上應該在大多數Prolog系統上運行,因爲它們支持DCG。

再見

定條款語法
http://en.wikipedia.org/wiki/Definite_clause_grammar

有限狀態傳感器
http://en.wikipedia.org/wiki/Finite_state_transducer

2

我們可以申請臨時音譯(只爲 '水平' 列表):

transliteration(Matrix, Translit) :- 
    maplist(transliteration(not_seen), Matrix, Translit). 

transliteration(_State, [], []). 
transliteration(State, [X|Xs], [Y|Ys]) :- 
    transliteration(State, X, NewState, Y), 
    transliteration(NewState, Xs, Ys). 

% handle only required state change 
transliteration(not_seen, 0'1, seen_first, 0'1). 
transliteration(seen_first, C, seen_last, C) :- C =\= 0'1. 
transliteration(seen_last, 0'1, seen_last, 0'2). 
% catch all, when no change required 
transliteration(State, C, State, C). 
+0

for this:音譯([[0,0,0,0,0],[0,1,0,0,0],[0,1,0,1,0],[0,0,0, 1,0],[0,0,0,0,0],L)。 我得到一個錯誤 – user1118501 2012-01-09 00:24:00

+0

貓和粘貼你的代碼也給我錯誤,但似乎在文本中有一些奇怪的字符!例如,如果我們重寫,那就沒問題......: - transliteration([[0,0,0,0,0],[0,1,0,0,0],[0,1,0,1, 0],[0,0,0,1,0],[0,0,0,0,0]],L),寫入(L)。 給出[[0,0,0,0,0],[0,1,0,0,0],[0,1,0,1,0],[0,0,0,1,0] ,[0,0,0,0,0]] – CapelliC 2012-01-14 10:54:35

1

與sol類似@chac建議使用,但更直接。

walk(L, R) :- walk(s0, L, R). 
walk(_, [], []). % finish 
walk(s0, [0'1|T], [0'1|R]) :- walk(s1, T, R). 
walk(s1, [0'x|T], [0'x|R]) :- walk(s2, T, R). 
walk(s2, [0'1|T], [0'2|R]) :- walk(s2, T, R). 
walk(S, [H|T], [H|R]) :- walk(S, T, R). % keep state and do nothing 
+0

我沒有得到我給出的正確結果: walk([[x,x,x,x,x],[x,1,x,x中,x],[X,1,X,1,X],[X,X,X,1,X],[X,X,X,X,X]],L)。 但我得到了同樣的清單,我給了 – user1118501 2012-01-09 00:20:38

+0

'walk(「xxx11xx11x」,L)。「你應該爲每一行使用它。如果您打算使用原子'x'和'1'而不是字符'0'x'和'0'1'。在適當的地方替換它們。另外你也許希望看看Prolog的一些內容 - 這是一種非常有趣的語言。我希望人們在其他情況下遇到它,而不是做作業...... – ony 2012-01-09 05:27:08

+0

我已經學過序言,但老師的筆記不包括這些練習的任何內容。我正在努力看到解決方案,以便我可以爲考試做好準備。 當我散步([0,1,0,0,1,1,1],L),我得到答案'不'。我想讓謂詞的第一個元素成爲一個列表並將第二個點轉換爲2 – user1118501 2012-01-09 11:56:44