转载自:https://mp.weixin.qq.com/s/G1rBTwds5bkObtQfHq5YDw
(注意:程序段行首的数字是为了注释单独编制的行号,后面的注释是对应行号写的)
10、列表的游程编码
encode(L1,L2):-通过游程长度编码从列表L1获得列表L2。
元素的连续重复项被编码为项[N,E],其中N是元素E的重复项数。
1 encode(L1,L2) :-
2 pack(L1,L),
3 transform(L,L2).
4
5 transform([],[]).
6 transform([[X|Xs]|Ys],[[N,X]|Zs]) :-
7 length([X|Xs],N),
8 transform(Ys,Zs).
注释行:
1.L1编码后的列表为L2
2. 如果列表L1 是各自打好包的列表的列表L
3. 并且L2是列表L编码后的列表
4.
5. 空列表的编码列表是空列表
6.
7. 算好包中(列表)元素的长度N,和[N,X]合取
8. 继续编码后续包(递归)
?- consult('p1_09.pl').
true.
?- consult('p1_10.pl').
true.
?- encode([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
X = [[4, a], [1, b], [2, c], [2, a], [1, d], [4, e]] .
11、列表的游程编码衍生版本
通过游程(run-length)编码从列表L1获得列表L2。元素的连续重复项被编码为
项[N,E],其中N是元素E的重复项数。
但是,如果N等于1,则将元素简单地复制到输出列表中。
1 encode_modified(L1,L2) :-
2 encode(L1,L),
3 strip(L,L2).
4
5 strip([],[]).
6 strip([[1,X]|Ys],[X|Zs]) :-
7 strip(Ys,Zs).
8 strip([[N,X]|Ys],[[N,X]|Zs]) :-
9 N > 1,
10 strip(Ys,Zs).
注释行:
1. L1编码后的列表为L2
2. 如果列表L1 是各编码好包的列表的列表L
3. 并且L2是列表L编码后的列表
4.
5. 空列表的编码列表是空列表
6. 当N等于1([1,X]|Ys])时直接将元素放入主表内不另列
7. 继续编码后续包(递归)
8. 取[[X|Xs]|Ys]列表中的打好的包
9. 算好包中(列表)元素的长度N,和[N,X]合取
10.继续编码后续包(递归)
?- consult('p1_09.pl').
true.
?- consult('p1_10.pl').
true.
?- consult('p1_11.pl').
true.
?- encode_modified([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
X = [[4, a], b, [2, c], [2, a], d, [4, e]] .
12、解码游程压缩列表
decode(L1,L2) 将列表L1解码到列表L2
1 decode([],[]).
2 decode([X|Ys],[X|Zs]) :-
3 \+ is_list(X),
4 decode(Ys,Zs).
5 decode([[1,X]|Ys],[X|Zs]) :-
6 decode(Ys,Zs).
7 decode([[N,X]|Ys],[X|Zs]) :-
8 N > 1,
9 N1 is N - 1,
10 decode([[N1,X]|Ys],Zs).
注释行:
1. 空列表解码后的列表仍为空列表
2. 列表[X|Ys]解码后的列表为[X|Zs]
3. 如果元素X不是列表,将元素X直接放入[X|Zs]中
4. 继续解码后续包
5. 如果要解码包列表的首元素是1则将元素X直接放入[X|Zs]中
6. 继续解码后续包
7. 列表[[N,X]|Ys]解码后的列表为[X|Zs]
8. 如果N大于1
9. 并且 N减以后赋值给N1,
10.继续递归剩余部分
?- consult(p1_12).
true.
?- decode([[4, a], [1, b], [2, c], [2, a], [1, d], [4, e]],X),write('X = '),write(X),nl.
X = [a,a,a,a,b,c,c,a,a,d,e,e,e,e]
X = [a, a, a, a, b, c, c, a, a|...] .
?- decode([[4, a], b, [2, c], [2, a], d, [4, e]],X),write('X = '),write(X),nl.
X = [a,a,a,a,b,c,c,a,a,d,e,e,e,e]
X = [a, a, a, a, b, c, c, a, a|...] .
13、列表的游程长度编码(直接解决方案)
encode_direct(L1,L2):- 通过游程长度编码从列表L1获得列表L2。元素的连续重复项被编码为项[N,E],其中N是元素E的重复项数。但是,如果N等于1,则该元素将被简单地复制到输出列表中。
1 encode_direct([],[]).
2 encode_direct([X|Xs],[Z|Zs]) :-