简体   繁体   English

递归 Function 方案编程

[英]Recursive Function Scheme Programming

How do I make a recursive function from my current code?如何从我当前的代码中生成递归 function? I'm still new to scheme so I don't really understand the basic tbh.我还是新手,所以我不太了解基本的 tbh。

so for now I am only able to run the function (total_func "SST" 2) and I want to make it (total_func '(("SST" 2) ("LST" 1) ("JNS" 3)) )所以现在我只能运行 function (total_func "SST" 2)并且我想做它(total_func '(("SST" 2) ("LST" 1) ("JNS" 3)) )

this is my current code.这是我当前的代码。

(define (total_func code quan);total_func is the function name
  (if (equal? code "SST")
    (define price 20))

  (if (equal? code "LST")
    (define price 25))

  (if (equal? code "JNS")
    (define price 70))
  
(define total (* price quan));total will calculate price * quantity
(print total);display the total value```

First of all, let's break things down a bit.首先,让我们把事情分解一下。

We have some sort of product code with a fixed price.我们有某种固定价格的产品代码。 Let's handle that in a function让我们在 function 中处理它

(define (code->price code)
  (cond
    ((equal? code "SST") 20)
    ((equal? code "LST") 25)
    ((equal? code "JNS") 70)
    (else 999)))

You can now test this code by just calling (code->price "SST") .您现在只需调用(code->price "SST")即可测试此代码。

Note that there is an else at the end - you didn't say what to do when the code isn't recognized.请注意,最后有一个else - 当代码无法识别时,您没有说明该怎么做。

Now, you seem to have a list of "orders" which comprise a (CODE QUANTITY) pairing.现在,您似乎有一个包含(CODE QUANTITY)配对的“订单”列表。 Note that a "pair" in scheme is a particular thing that is slightly different from a list of two items.请注意,方案中的“对”是与两个项目的列表略有不同的特定事物。 What you have shown is a list of two items, so I'll use that.您显示的是两个项目的列表,所以我将使用它。

; order = (code quantity) - a list of 2 items
(define (order->price order)
  (let ((code (car order))
        (quan (cadr order)))
    (* quan (code->price code))))

And if we test this with (order->price '("SST" 2)) we get 40 which is reassuring.如果我们使用(order->price '("SST" 2))进行测试,我们会得到40 ,这是令人放心的。 Now, we clearly just need a way to run that for each of the orders in our order-list and add up the results.现在,我们显然只需要一种方法来为我们的订单列表中的每个订单运行它并将结果相加。

(define (recursive-totaller subtot orders)
  (if (null? orders)
    subtot
    (let ((new-subtot (+ subtot (order->price (car orders)))))
      (recursive-totaller new-subtot (cdr orders)))))

Now, a recursive function is going to need the same "shape" for its parameters in every call, from the first to the last.现在,递归 function 在每次调用中都需要相同的“形状”,从第一个调用到最后一个调用。 So we are going to give it a subtot that for the first call will be 0. If our list of orders is empty then we will just return whatever the current subtot will be - which for an empty list is 0, which is correct.因此,我们将给它一个subtot ,第一次调用将为 0。如果我们的订单列表为空,那么我们将返回当前subtot的任何内容 - 对于空列表,它是 0,这是正确的。

If orders is not empty, we calculate a new sub-total by calling order->price on the first item in orders .如果orders不为空,我们通过在orders中的第一个项目上调用order->price来计算新的小计。 Then we recurse, calling ourself with the new subtotal and the tail of the orders list.然后我们递归,用新的小计和订单列表的尾部调用我们自己。

Assuming our list of orders is not infinite we will eventually call ourselves with an empty list and just return the final sub-total all the way back through the call-stack until it reaches the original caller.假设我们的订单列表不是无限的,我们最终会用一个空列表调用自己,并通过调用堆栈一直返回最终的小计,直到它到达原始调用者。

(define (test-totaller)
  (recursive-totaller 0 '(("SST" 2) ("LST" 1) ("JNS" 3))))

Now, you might not be quite so verbose in "real" code, but to be honest I'd rather several functions like this that are clear about what they do rather than one bigger function that is harder to understand.现在,您在“真实”代码中可能不会那么冗长,但老实说,我更喜欢这样的几个函数,它们清楚它们的作用,而不是一个更难理解的更大的 function。

Finally - applying the same function to all the elements of a list and getting a new list back is very common (it is called "mapping") and summarizing a list is also very common (it is called "folding") and scheme has functions to help you (you may need to import "srfi-1").最后 - 将相同的 function 应用于列表的所有元素并返回一个新列表是非常常见的(称为“映射”)并且总结列表也很常见(称为“折叠”)并且方案具有功能为您提供帮助(您可能需要导入“srfi-1”)。

(let* ((orders '(("SST" 2) ("LST" 1) ("JNS" 3)))
       (order-prices (map order->price orders)))
  (fold + 0 order-prices)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM