【问题标题】:Scheme: populating a vector using recursion?方案:使用递归填充向量?
【发布时间】:2011-11-17 20:09:08
【问题描述】:

我是 Scheme 的新手——我目前正在尝试学习语法以及如何递归思考。我来到了关于向量的部分,并希望能够通过某种循环(当然使用递归)在我的向量中设置值。我有这个变量:

(define my-vector (make-vector 5))

然后我想使用vector-set! 过程填充它。通常在 C++(我真正熟悉的唯一其他语言)中,这将以迭代方式完成,例如

//...

std::vector<int> myVector;

for(int i = 0; i < 5; ++i)    // populate the vector
    myVector.push_back(i);

std::vector<int>::const_iterator outIter;

for(outIter = myVector.begin();
    outIter != myVector.end(); ++outIter)
    std::cout << *outIter << " ";

std::cout << std::endl;

//...

但是,我知道这种事情应该通过 Scheme 中的递归来完成。递归populate-vector 过程可能是什么样的??

【问题讨论】:

  • Scheme 中的向量与 C++ 中的 vectors 不同。 Scheme 中的向量在创建时具有固定的大小,并且无法调整大小;有点像 C++ 中用new int[size] 分配的数组
  • 注明。是的,我看到 vector 必须定义为固定大小,这与 C++ 中的 &lt;vector&gt; 不同。我只是想知道如何在 Scheme 中抽象出“填充某个容器”的概念。

标签: recursion vector scheme


【解决方案1】:
(let f ((i 0))
  (when (< i 5)
    (vector-set! my-vector i i)
    (f (+ i 1))))

您可以在线试用here

您也可以尝试使用DO 语法,但大多数人觉得很难记住:)

学习使用命名LET 非常重要。

另外请注意,Scheme 向量只是一个固定大小的数组。

【讨论】:

  • 好的。谢谢。仍然试图围绕何时使用 LET 而不是 LAMBDA 等来解决问题。
  • 另外,我正在使用 guile 作为我的方案解释器,而上述方法似乎不起作用。似乎不像“未绑定变量WHEN”这是一个非标准程序吗??
  • 我使用了;; (let f ((i 0)) (if (&lt; i 5) (begin ...,这似乎有效。
  • 您可能使用的是旧版本的 guile。
  • @djhaskin987:没见过什么? (我猜你说的是在线评估器;p)
【解决方案2】:

一个选项是这样的:

void PopulateVector(vector<int>& vec, int n) {
    if (n < 0) return;

    PopulateVector(vec, n - 1);

    vec.push_back(n);
}

思路如下。首先,如果你试图创建一个值从 0 到某个负数的向量,我们什么也不做;没有要添加的值。否则,我们首先用值 0 到 n - 1 填充向量,然后将 n 附加到向量。

请注意,就内存使用而言,这是一个非常低效的过程;它需要用于调用堆栈的线性内存。迭代版本可能要好得多。我们可以将此函数重写为尾递归,并希望优化器消除递归,但不能保证这会发生(而 IIRC,Scheme 要求尾调用消除)。这个想法是使用一个包装函数,这样我们就可以向上计数而不是从 n 向下计数:

void PopulateVector(vector<int>& vec, int n) {
    if (n < 0) return;

    PopulateVectorRec(vec, 0, n);
}

void PopulateVectorRec(vector<int>& vec, int current, int n) {
    if (current > n) return;

    vec.push_back(current);

    PopulateVectorRec(vec, current + 1, n);
}

希望这会有所帮助!

【讨论】:

  • 是的,我听说迭代版本更适合这种事情。但它仍然使用递归正确吗?除了它在程序的“尾部”?我可能应该阅读更多关于消除尾音的内容......
猜你喜欢
  • 2011-09-15
  • 1970-01-01
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多