Scheme 方案:按枢轴对元素排序

Scheme 方案:按枢轴对元素排序,scheme,racket,Scheme,Racket,我不熟悉Scheme和函数式编程,所以请温柔一点。 我正在尝试实现一个函数,该函数接受一个列表和一个轴,并返回一个包含以下两个列表的列表: 一个用于小于或等于轴的所有元素 一个用于大于轴的所有元素 因此,我编写了以下代码(已编辑(&工作)代码-问题已解决): 定义辅助对象(lambda(lst枢轴) (定义lst1 null) (定义lst2 null) (定义我的拆分(lambda(第一枢轴lst1 lst2) (如果(空?lst) (列表lst1 lst2) (如果(您正确地识别了主要问题的

我不熟悉Scheme和函数式编程,所以请温柔一点。 我正在尝试实现一个函数,该函数接受一个列表和一个轴,并返回一个包含以下两个列表的列表:

一个用于小于或等于轴的所有元素

一个用于大于轴的所有元素

因此,我编写了以下代码(已编辑(&工作)代码-问题已解决):

定义辅助对象(lambda(lst枢轴)
(定义lst1 null)
(定义lst2 null)
(定义我的拆分(lambda(第一枢轴lst1 lst2)
(如果(空?lst)
(列表lst1 lst2)

(如果(您正确地识别了主要问题的两行。
cons
只构建并返回一个新列表,而您正试图变异变量
lst1
lst2
。正确的方法是
(set!lst1(cons(car lst)lst1))
(set!lst2(cons(car lst)lst2))
。但是要记住,好的函数式编程风格可以避免变异。在这种情况下,一个好的方法是在主列表下循环时将两个子列表作为参数传递,然后在结束时返回它们。

您正确地识别了主要问题的两行。
cons
只是构建了一个d返回一个新的列表,而您正试图变异变量
lst1
lst2
。正确的方法是
(set!lst1(cons(car lst)lst1))
(set!lst2(cons(car lst)lst2))
。但是请记住,好的函数式编程风格可以避免变异。在这种情况下,一个好的方法是在主列表下循环时将两个子列表作为参数传递,然后在结束时返回它们。

就像
str.concat(“嘿”)这样的表达式一样
在Java中不会改变
str
是什么
(cons 1 lst1)
不会改变
lst1
是什么。它只是返回一个新值。大多数函数都由死代码组成,如果你真的想学习函数编程,那么改变绑定和对象是不允许的

您需要这样做:

(define (count-odds lst)
  (define (helper lst odds)
    (cond ((null? lst) 
           odds)
          ((odd? (car lst)) 
           (helper (cdr lst) (+ 1 odds)))
          (else 
           (helper (cdr lst) odds))))    
  (helper lst 0))

(count-odds '(1 2 3))
; ==> 2

我们从不改变
几率
,我们只是更新发送到下一个递归的内容。由于Scheme具有尾部调用消除功能,这就像在while循环中更新变量而不发生实际变异一样。

就像Java中的
str.concat(“hey”)
表达式一样,不会改变
str
(cons 1 lst1)
不会改变什么是
lst1
。它只会返回一个新值。大多数函数都由死代码组成,如果你真的想学习函数编程,那么改变绑定和对象是不允许的

您需要这样做:

(define (count-odds lst)
  (define (helper lst odds)
    (cond ((null? lst) 
           odds)
          ((odd? (car lst)) 
           (helper (cdr lst) (+ 1 odds)))
          (else 
           (helper (cdr lst) odds))))    
  (helper lst 0))

(count-odds '(1 2 3))
; ==> 2

我们从不改变
几率
,我们只是更新发送到下一个递归的内容。由于Scheme具有尾部调用消除功能,这就像在while循环中更新变量,而没有实际的变异。

感谢您的回答,但正如我提到的,我不允许使用
set!
,我尝试添加
lst1
&
lst2
到输入参数,然后将它们作为参数传递,但结果是相同的(请参见我的编辑)。您能提供您提供的代码示例吗?@Noam您就快到了。将
(list lst1 lst2)
从最后一行移动到第一个
if
表达式的第一个臂(替换
null
)。谢谢,已解决。@Noam不客气。如果您在理解解决方案时遇到任何问题,请告诉我。哈哈,实际上,我正在尝试使用此
拆分
函数并实现一个完整的快速排序算法,我在那里遇到了一些问题,因此我打开了另一篇文章,如果您有空,我将感谢您的帮助:谢谢您的帮助回答,但正如我提到的,我不允许使用
set!
,我尝试将
lst1
&
lst2
添加到输入参数中,然后将它们作为参数传递,但结果是相同的(请参见我的编辑)。你能提供你提供的代码示例吗?@Noam你就快到了。移动
(列出lst1 lst2)
从最后一行到第一个
if
表达式的第一个臂(替换
null
)。谢谢,已解决。@Noam不客气。如果您在理解解决方案时遇到任何问题,请告诉我。哈哈,实际上,我正在尝试使用此
拆分
函数并实现一个完整的快速排序算法,我在那里遇到了一些问题,因此我打开了另一篇文章,如果您有空,我将感谢您的帮助:谢谢您的帮助解释,我理解你的例子,但是我不知道如何将它应用到我的问题上,我编辑了我的代码,尝试按照你说的做,但结果是一样的。有什么想法吗?当
处拆分时返回
lst1
并且
lst2
再次返回空值。你想从
中删除它,因为你想从
中得到结果>结果是在
处拆分。当您到达
lst
的末尾时,您可能还希望对
lst1
lst2
执行某些操作,而不是返回null。此外,过程中定义的
lst1
lst2
与参数无关。它们恰好具有相同的名称。感谢您的解释我理解你的例子,但是我不知道如何把它应用到我的问题上,我已经编辑了我的代码,试图按照你说的做,但是结果是一样的。有什么想法吗?当
处拆分时返回
lst1
并且
lst2
再次以空值结束。你想从
拆分中删除它,因为你想从
拆分中得到结果-结果是在
处。当您到达
lst
的末尾时,您可能还希望对
lst1
lst2
执行一些操作,而不是返回null。另外
lst1
和<