Prolog将字符串转换为配对列表

时间:2012-05-26 19:00:16

标签: string list prolog

我正在学习Prolog,我需要知道如何转换字符串列表:

['f(a,45)', 'f(b,13)', 'f(c,12)']

到一个看起来像这样的对列表中:

[[45,'a'],[13,'b'],[12,'c']]

2 个答案:

答案 0 :(得分:1)

这是 atoms 的列表,而不是字符串。 Prolog中的字符串通常是字符代码列表,表示为

["f(a,45)", "f(b,13)", "f(c,12)"]

无论如何,使用递归函数对每个元素应用转换:

convert([], []).
convert([Atom|Atoms], [Pair|Pairs]) :-
  convert_element(Atom, Pair),
  convert(Atoms, Pairs).

您可以通过以下方式使用maplist / 3来代替递归:

convert(As, Ps) :- maplist(convert_element, As, Ps).

要转换元素,您需要一个解析器。 DCG很方便:

convert_element(Atom, [N, A]) :-
  atom_codes(Atom, Codes),
  phrase(("f(", atomc(Ac), ",", numc(Nc), ")"), Codes, []),
  atom_codes(A, Ac),
  number_codes(N, Nc).

atomc(A) --> ([C], {is_lowerc(C)}, atomc(Cs), {A = [C|Cs]}) ; {A = []}.
numc(N) --> ([C], {is_numc(C)}, numc(Cs), {N = [C|Cs]}) ; {N = []}.

is_lowerc(C) :- C @>= 0'a, C @=< 0'z.
is_numc(C) :- C @>= 0'0, C @=< 0'9.

试验:

?- convert(['f(a,45)', 'f(b,13)', 'f(c,12)'],L).
L = [[45, a], [13, b], [12, c]] .

atomc // 1&amp; numc // 1以紧凑的方式表示,但是非常简单的递归模式匹配过程,即atomc // 1可能是

atomc([C|Cs]) --> [C], {is_lowerc(C)}, !, atomc(Cs).
atomc([]) --> [].

答案 1 :(得分:0)

或者,您可以使用此代码:

convert :-
    L = ["f(a,45)", "f(b,13)", "f(c,12)"],
    maplist(extract_args,L, LA),
    writeln(LA).


extract_args(S, [A1,A2]) :-
    string_to_atom(S, A),
    term_to_atom(T, A),
    T =..[_, A2, A1].

如果你有原子,只需在extract_args / 2中使用term_to_atom / 2.