Prolog中有一段代码,用于将txt文件转换为4个列表(每行3个1D_list,最后一个是2D_list,其余各行一个子列表。
inp :-
open('3by3data.txt', read, Str),
read_line_to_string(Str,Line), %read a line from Str(Stream)
split_string(Line," ","",L_list1), %Split a line into a list by " "
maplist(atom_number,L_list1,RL), !, %Conver atom list into number list
read_line_to_string(Str,Line1), %read a line from Str(Stream)
split_string(Line1," ","",L_list2), %Split a line into a list by " "
maplist(atom_number,L_list2,FQty), !, %Conver atom list into number list
read_line_to_string(Str,Line2), %read a line from Str(Stream)
split_string(Line2," ","",L_list3), %Split a line into a list by " "
maplist(atom_number,L_list3,WQty),!, %Conver atom list into number list
read_Costs(Str,Costs),
write(RL),nl,write(FQty),nl,write(),nl,write(Costs),nl.
read_Costs(Str,Costs) :-
\+at_end_of_stream(Str),
read_line_to_string(Str,Line3),
split_string(Line3," ","",L_list4), %Split a line into a list by " "
maplist(atom_number,L_list4,Costs1),%Conver atom list into number list
append([costs1],[Costs2],Costs),
read_Costs(Str,Costs2).
read_Costs([],[]).
file.txt:
3 4
10 60 30 40
50 30 60
2 4 5 6
7 8 9 4
1 2 4 6
...
=>
[3,4]
[10,60,30,40]
[50,30,60]
[[2,3,5,6],[7,8,9,4],[1,2,4,6],...]
以上代码中存在边界条件错误。
答案 0 :(得分:1)
当然这行
append([costs1],[Costs2],Costs),
不起作用,因为错误地拼写了变量 Costs1,并且循环终止的替代子句-EOF-无法将流Str
与[]
匹配。 / p>
关于代码的样式说明。像任何其他语言一样,在Prolog中,将可重复使用的“子例程”中的重复的通用功能分组是很有价值的。
read_line_to_string,split_string,maplist(atom_number)
的组合经常使用。用它们作为服务谓词。
如果使用SWI-Prolog,则可以使用DCG增强解析。例如
:- use_module(library(dcg/basics)).
:- use_module(library(dcg/high_order)).
parse_3by3data(Rl, FQty, Costs) -->
a_line_of_numbers(Rl),
a_line_of_numbers(FQty),
sequence(a_line_of_numbers,Costs).
a_line_of_numbers(L) -->
whites,
sequence(number,whites,L),
whites, "\n".
parse_3by3data // 3是一种语法产生形式,您可以直接在文件中使用带有短语/ from_file或字符串...的带有短语/ 3的语法。即
test :-
phrase(parse_3by3data(Rl, FQty, Costs),
` 3 4
10 60 30 40
50 30 60
2 4 5 6
7 8 9 4
1 2 4 6
`), writeln(parse_3by3data(Rl, FQty, Costs)).