prolog - 查找一定长度的子串
问题描述
我是 prolog 的初学者,我在开始解决以下问题时遇到了麻烦:
定义 predicate
partstr/3
,其中第一个参数是一个列表,它生成一个A
长度列表L
,您在第一个列表中发现该列表是连续的。您应该能够通过回溯呈现所有答案。
例如:
?- partstr([1, 2 , 3], L, A).
如果L
=2
那么A
=[1,2]
和[2,3]
,或者如果L
=2
那么 F=[1,2] 和 [2,3]。等等...
我觉得你会使用递归来解决它,但我不知道从哪里开始。我真的很感激一些关于如何解决这个问题的提示,因为我觉得我无处可去。
解决方案
这个问题的核心是你需要一种方法来N
从一个列表中拉出所有长度的子列表,对吗?
所以...
考虑
append/3
可以连接两个列表:append( [a,b,c], [1,2,3], L)
返回L
为[a,b,c,1,2,3]
. 但它也可以将一个列表分解为前缀和后缀,所以append( Pfx, Sfx, [a,b,c])
将在回溯时连续产生:
特效 音效 []
[a,b,c]
[a]
[b,c]
[a,b]
[c]
[a,b,c]
[]
...and...
length/2
不仅可以告诉您列表的长度,还可以生成指定长度的列表,其中填充了唯一的、未绑定的变量,因此length(L,3)
返回[V1,V2,V3]
.
您可以将它们组合起来以获得您想要的行为:
partstr( Xs, N, SL ) :- % To get all the contiguous sublists of length N from Xs...
append(_,Sfx,Xs) , % - repeatedly get all possible suffixes of Xs, and...
length(SL,N) , % - construct an empty, unbound list of the desired length (N), and...
append(SL,_,Sfx) % - pull that prefix off the suffix
. % Easy!
这是一种方法。我想这是课程作业,您的讲师可能希望您从头开始推出自己的解决方案。
为此,我们首先需要一个将产生源列表的谓词,并在回溯时删除列表的头部。就像是:
suffix( Xs , Xs ) .
suffix( [_|Xs] , Sfx ) :- suffix(Xs,Sfx).
然后我们需要一种从列表中获取第一个n元素的方法,如下所示:
take( _ , 0 , [] ) :- ! .
take( [X|Xs] , N , [X|Sfx] ) :- N1 is N-1 , take(Xs,N1,Sfx) .
鉴于这两个...
partstr( Xs, N , SL ) :-
suffix(Xs,Sfx),
take(Sfx,N, SL )
.
您甚至可以省去suffix/2
谓词,从而将其功能融入partstr/3
自身:
partstr( Xs , N , SL ) :- take(Xs,N,SL).
partstr( [_|Xs] , N , SL ) :- partstr(Xs,N,SL).
我认为,这就是最佳点:很难击败 4 行代码——</p>
partstr( Xs , N , SL ) :- take(Xs,N,SL) .
partstr( [_|Xs] , N , SL ) :- partstr(Xs,N,SL) .
take( _ , 0 , [] ) :- ! .
take( [X|Xs] , N , [X|Sfx] ) :- N > 0 , N1 is N-1 , take(Xs,N1,Sfx) .\
推荐阅读
- java - 我正在研究 Java 中的静态和实例变量,我无法理解代码的输出
- google-oauth - Google 身份验证端点重定向到 400 错误页面
- java - java Netbeans显示带参数的ireport文档但选择日期时出错,它说报告上没有文档
- php - 使用文件 guzzle laravel 上传数据
- docker - 在 Ubuntu 20.04 LTS(Vmware)上安装 docker 失败
- python - 如何将 Fairlearn 与自定义公平约束一起使用?
- javascript - 如何在本机反应中仅更改特定的子样式属性?
- javascript - 如何在 jquery 的每个链接后添加“br”?
- mysql - SQL 查询根据客户使用过的唯一商户数量对客户进行排名
- sql-server - SQL Server管理系统中如何查看所有列的数据类型