List 在Racket中对列表进行细分

List 在Racket中对列表进行细分,list,function,scheme,racket,List,Function,Scheme,Racket,我想在Scheme中创建一个函数,它从列表中生成子列表,我可以给它一个值来启动细分,给它一个值来停止细分,类似这样: (function '(1 2 3 1 4 5 6 3) 1 3) >'((1 2 3) (1 4 5 6 3)) 我找不到正确的方法,正如您所看到的,函数将以1开始子列表,以3结束子列表,我如何实现类似的功能?这是非贪婪的,因此它会给出最短的答案(在遇到start后在第一个端点停止),并在最后一个端点位置后继续查找匹配项。这是一个滚动您自己的解决方案,没有花哨的列表过程

我想在Scheme中创建一个函数,它从列表中生成子列表,我可以给它一个值来启动细分,给它一个值来停止细分,类似这样:

(function '(1 2 3 1 4 5 6 3) 1 3)
>'((1 2 3) (1 4 5 6 3))

我找不到正确的方法,正如您所看到的,函数将以1开始子列表,以3结束子列表,我如何实现类似的功能?

这是非贪婪的,因此它会给出最短的答案(在遇到start后在第一个端点停止),并在最后一个端点位置后继续查找匹配项。这是一个滚动您自己的解决方案,没有花哨的列表过程,但它也是尾部递归的

(定义(子列表src start-end)
(let循环((lst src)(acc#f)(结果’())
(续)
((null?lst)(反向结果));如果匹配顺序没有问题,请删除反向
((非acc)(循环(cdr lst)(如果(eqv?(车辆lst)启动)(列表(车辆lst))#f)结果))
((非(eqv?(车辆lst)结束))(循环(cdr lst)(cons(车辆lst)acc)结果))
(其他(循环(cdr lst)#f(反方向(cons(汽车lst)acc))结果‘‘‘‘‘‘‘‘)
(子列表’(1 2 13 2 2)1 2);=>((1 2) (1 3 2))
(小名单)(1 2 3 1 4 5 6 3 1 4 8 7 9 5)4 5 ;;((4 5) (4 8 7 9 5))
要找到重叠的结果,这可能是可行的:

(定义(子列表完整src开始-结束)
(让循环((lst src)(acc#f)(回溯#f)(结果’())
(如果(空?lst)
(如果返回)
(循环回溯#f#f结果)
(结果相反)
(出租((a(车辆lst)))
(如果符合
(条件((和(eqv?a启动)(非回溯))(循环(cdr lst)(cons a acc)lst结果)
((eqv?a结束)(循环(cdr lst)(cons a acc)回溯(cons(反向(cons a acc))结果)))
(其他(循环(cdr lst)(cons a acc)回溯结果)
(如果(eqv?a启动)
(循环(cdr lst)(cons a’())#f结果)
(循环(cdr lst)#f#f结果(()(()())())))
(子列表完整’(1 2 13 2 2 2 2)1 2)
; ==> ((1 2) (1 2 1 3 2) (1 2 1 3 2 2) (1 2 1 3 2 2 2) 
;      (1 2 1 3 2 2 2 2) (1 2 1 3 2 2 2 2 2) (1 3 2) 
;      (1 3 2 2) (1 3 2 2 2) (1 3 2 2 2 2) (1 3 2 2 2 2 2))

以下是我能想到的最好的方法——毫无疑问,还有更优雅的方法

其思想是删除所有内容,直到找到“开始”值,然后将所有内容保留到“停止”值(如果有),然后在剩余列表上递归

#lang racket
(require srfi/1) ; For drop-while

(define (subdiv ls start stop)
  (let ([part-one (drop-while (lambda (x) (not (= x start))) ls)])
    (let-values ([(main rest) (splitf-at part-one (lambda (x) (not (= x stop))))])
      (if (null? rest)         ; empty means the stop value wasn't found
          '()
          (cons (append main (list stop)) 
                (subdiv (cdr rest) start stop))))))
例如:

> (subdiv '(3 4 5 1 111 1 1 1 2 2 3 1 2) 1 2)
'((1 111 1 1 1 2) (1 2))
> (subdiv '(3 4 5 1 2 3 1 2) 1 2)
'((1 2) (1 2))
> (subdiv '(1 2) 1 2)
'((1 2))
> (subdiv '(1) 1 2)
'()
> 

问题有点不明确-不“适合”的值会发生什么情况,例如
(函数“(1 2)1 3)
(函数“(2 1 3 4 1 3 5)1 3)
?它们刚刚被删除了吗?你是对的,对于不符合条件的值,我不需要任何特定的输出,一个错误或返回相同的输入就可以了。
(function'(123456)45)
的结果如何?该输出应该是这样的:'(1231(45)631)如果您更愿意以列表中的第一个元素必须是第二个输入(在本例中为:4)的方式进行操作,那么就做我的客人,让我们假设一切都按照我在原始问题中所述的方式进行。编辑:更好的方法是,将输出设置为“(4 5)。为什么要在输出中使用符号?我不知道为什么会出现这种情况,但我得到了:(子列表“(1 2 3 4 5)2 4);==>(3 4 5)另一个大问题是,我希望输出是符合条件的所有子列表,例如,这是可以的:
(子列表’(1 2 3 1 4 5 6 3 1)4 5);==>(4 5)
但这是错误的:
(子列表’(1 2 3 1 4 5 6 3 1 8 7 9 5)4 5);==>(4 5)
它应该是
(子列表'(1 2 3 1 4 5 6 3 1 4 8 7 9 5);=>'((4 5)(4 8 7 9 5))
正如我所说,我真的不关心与标准不匹配的输入,最后两个示例对我来说很好。你是说开始和结束不是索引,而是子列表开始和结束处的实际值吗?因此
(子列表“(12)12);=>((12)(12)(12)(12)(12)(12)(12)(12)(12)(12)(12))
?我的意思是,您指出的情况并不完全是我要寻找的,我只是想假设这不会发生,列表中从来没有两个[子列表末尾]值相邻。我唯一担心的是原始问题中的情况,我不介意它在其他类型的组合中表现如何。虽然我知道你是怎么担心的,但这种情况也意味着类似的事情:
(function'(123141563)13);==>'((1 2 3)(1 2 3 1 4 5 6 3))
如果你看到原始问题,这不是我要找的。我在找'((123)(143))。