Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Prolog列表与递归_List_Recursion_Prolog - Fatal编程技术网

List Prolog列表与递归

List Prolog列表与递归,list,recursion,prolog,List,Recursion,Prolog,我在理解Prolog中的人为递归时遇到问题 一些仅分别附加到开始和结束的帮助器谓词: add_number(Numbers, N, NewNumbers). add_letter(Letters, L, NewLetters). 我的目标是获取一个字母和数字列表,并返回两个列表:一个按外观顺序排列的数字列表,递增1;和一个字母列表,按与外观相反的顺序排列。我的理由如下: foo([], [], [], [], []). foo([X|Xs], Nums, NewNums, Letters,

我在理解Prolog中的人为递归时遇到问题

一些仅分别附加到开始和结束的帮助器谓词:

add_number(Numbers, N, NewNumbers).
add_letter(Letters, L, NewLetters).
我的目标是获取一个字母和数字列表,并返回两个列表:一个按外观顺序排列的数字列表,递增1;和一个字母列表,按与外观相反的顺序排列。我的理由如下:

foo([], [], [], [], []).

foo([X|Xs], Nums, NewNums, Letters, Letters) :-
    number(X),
    X1 is X+1,
    add_number(Nums, X1, NewNums),
    foo(Xs, ???, ???, Letters, Letters).

foo([X|Xs], Nums, Nums, Letters, NewLetters) :-
    letter(X),
    add_letter(Letters, X, NewLetters),
    foo(Xs, Nums, Nums, ???, ???).
第二个和第四个参数是累加器

那么应该这样称呼它:

realfoo(Xs, Nums, Letters) :- foo(Xs, [], Nums, [], Letters).
foo( List , Numbers , Letters ) :-
  worker( List , [] , Numbers , [] , Letters ).

worker( []     , Numbers           , Numbers , Letters           , Letters ).
worker( [X|Xs] , NumberAccumulator , Numbers , LetterAccumulator , Letters ) :-
  digit(X),
  X1 is X+1 ,
  append( NumberAccumulator , [X1] , NumberAccumulator1 ) ,
  worker( Xs , NumberAccumulator1 , Numbers , LetterAccumulator , Letters ).
worker( [X|Xs] , NumberAccumulator , Numbers , LetterAccumulator , Letters ) :-
  letter(X) ,
  worker( Xs , NumberAccumulator , Numbers , [X|LetterAccumulator] , Letters ).
worker( [X|Xs] , NumberAccumulator , Numbers , LetterAccumulator , Letters ) :-
  not letter(X) ,
  not digit(X)  ,
  worker( Xs , NumberAccumulator , Numbers , LetterAccumulator , Letters ).

letter( a ). letter( b ). letter( c ). ... letter( z ).
letter('A'). letter('B'). letter('C'). ... letter('Z').

digit('0'). digit('1'). digit('2'). ... digit('9').

如何编写此代码?

使用累加器以相反顺序建立列表。不要使用
add_number
,否则您将得到一个二次时间算法,而您可以在线性时间内解决此问题

foo([], NumsR, Nums, Letters, Letters) :-
    reverse(NumsR, Nums).
foo([X|Xs], NumsR, Nums, LettersR, Letters) :-
    % the following is the Prolog syntax for if-then-else;
    % you could also do this with two recursive clauses,
    % but this option is faster because of first-argument indexing
    (number(X) ->
        X1 is X+1,
        foo(Xs, [X1|NumsR], Nums, LettersR, Letters)
    ;
        foo(Xs, NumsR, Nums, [X|LettersR], Letters)
    ).
foo([],Nums,Nums,字母,字母)

foo([X|Xs],Nums_1,Nums,Letters_1,Letters):- 编号(X), X1是X+1, 添加数字(Nums_1、X1、Nums_2), foo(Xs,Nums_2,Nums,Letters_1,Letters)

foo([X|Xs],Nums_1,Nums,Letters_1,Letters):- 字母(X), 添加字母(字母1、X、字母2), foo(Xs,Nums_1,Nums,Letters_2,Letters)

添加数字(Nums_1、X、Nums_2):- 追加(Numbs_1[X],nums_2)

添加字母(字母1、X、字母2):-
附加(字母1,[X],字母2)。

我会这样做:

realfoo(Xs, Nums, Letters) :- foo(Xs, [], Nums, [], Letters).
foo( List , Numbers , Letters ) :-
  worker( List , [] , Numbers , [] , Letters ).

worker( []     , Numbers           , Numbers , Letters           , Letters ).
worker( [X|Xs] , NumberAccumulator , Numbers , LetterAccumulator , Letters ) :-
  digit(X),
  X1 is X+1 ,
  append( NumberAccumulator , [X1] , NumberAccumulator1 ) ,
  worker( Xs , NumberAccumulator1 , Numbers , LetterAccumulator , Letters ).
worker( [X|Xs] , NumberAccumulator , Numbers , LetterAccumulator , Letters ) :-
  letter(X) ,
  worker( Xs , NumberAccumulator , Numbers , [X|LetterAccumulator] , Letters ).
worker( [X|Xs] , NumberAccumulator , Numbers , LetterAccumulator , Letters ) :-
  not letter(X) ,
  not digit(X)  ,
  worker( Xs , NumberAccumulator , Numbers , LetterAccumulator , Letters ).

letter( a ). letter( b ). letter( c ). ... letter( z ).
letter('A'). letter('B'). letter('C'). ... letter('Z').

digit('0'). digit('1'). digit('2'). ... digit('9').
因为这是一个学习练习,所以我不会推迟列表的反转:我会做显而易见的事情,并以相反的顺序构建列表,尽管性能受到了影响。我相信这个练习的重点是,你需要学会用两种方式建立列表