您好我正在使用matlab并且需要编写一个函数来计算向量中大于或等于k的数字。如果没有,它应该返回0.
到目前为止,这就是我所做的:
function totalnumb = numbgreater(v,k)
if any(v>=k) == 0
totalnumb = 0
else
end
end
我正在努力编写下面应该写的内容。我曾想过使用find(v> = k)找到数字> = k的索引,但后来我很困惑如何使用递归来计算它们。 如果有人能提供帮助就会很棒。 非常感谢
答案 0 :(得分:1)
正如我在对@ rayryeng的回答的评论中提到的,他的解决方案使用尾递归。递归通常会产生问题,解决部分问题,在其余部分再次调用相同的函数,并将两个答案组合在一起。在这种情况下,给定矢量的两个部分:
v(1) and v(2:end)
我们找到v(1)
的解决方案,然后在numbgreater
上调用v(2:end)
。这是在Ray的代码的Recursive case
部分完成的。为简洁起见,我删除了大部分注释,并做了一个小改动以明确说明:
else %// Recursive case
if v(1) > k
totalnumb = 1 + numbgreater(v(2:end), k);
else
totalnumb = 0 + numbgreater(v(2:end), k);
end
end
现在两个案例都有v(1)
的解决方案加上其余的解决方案。
说,我们不是找到仅v(1)
的解决方案,而是想找到整个矢量前半部分的解决方案,然后将其添加到整个矢量后半部分的解决方案中。那怎么样?好吧,我们不是要确定是添加0
还是1
,而是将矢量分成两部分并在两部分上调用numbgreater
:
else
mp=floor(numel(v)/2); %// find the midpoint
%// Call numbgreater() on both halves and add the results
totalnumb = numbgreater(v(1:mp),k) + numbgreater(v(mp+1:end),k);
end
那么我们在哪里计算是否添加1
?这仍然在代码的Base case
部分处理:
if numel(v) == 1
if v > k % //Is input number > k? If it is, return 1
totalnumb = 1;
else % //If not, return 0
totalnumb = 0;
end
因此我们继续将向量分割并调用函数的新版本,直到每个子向量的长度为1,然后在我们弹回递归堆栈时将它们全部重新添加。所以这是我们的新功能:
function totalnumb = numbgreater(v,k)
%// Base case - if number of input elements is 1
if numel(v) == 1
if v > k
totalnumb = 1;
else %
totalnumb = 0;
end
else %// Recursive case
mp=floor(numel(v)/2); %// find the midpoint
totalnumb = numbgreater(v(1:mp),k) + numbgreater(v(mp+1:end),k);
end
end
我使用以下命令生成一些测试数据并调用函数:
v=randi(10,1,10)
n=numbgreater(v,4)
输出应该是这样的:
v =
9 10 3 2 9 8 2 2 10 7
n = 6
答案 1 :(得分:0)
对于你的问题,写一些递归的东西实际上非常简单。在这种特殊情况下,您可以使用递归程序来确定如何使用for
循环完成此操作,然后对其进行修改以使其递归。想想你如何在循环中做到这一点。我们会一次检查此向量中的每个数字,看看它是否大于k
。如果是,我们将计数器增加1.如果不是,我们不会增加。
正如patrik在下面对我的评论中所提到的,递归远不止于此。有一些非常复杂的算法使用递归作为解决不依赖于此问题的方法的一种方法。结构体。例如,深度优先搜索是一种图搜索算法,它以特定顺序搜索节点。它归结为使用堆栈,您可以使用递归优雅地表示它。这可以在for
循环中实际完成(while
循环),但在递归中表示它会更加优雅。但是,对于您的情况,以这种方式开始递归。它至少会让你的双脚离开地面。
因此,使用任何递归算法,您需要所谓的 base 大小写。基本情况是当我们确定在给出最简单的输入时输出应该是什么时。在我们的例子中,这只是当我们指定长度为1或1的元素的输入时。如果我们只有1个元素,那么如果此元素大于k
,则返回1,否则返回0.
如果输入不是一个元素而是一个向量,那么您将检查此向量中的第一个元素是否大于k
。如果是,结果将是1 +对向量的递归调用,其中我们跳过第一个元素并查看其余元素。如果它不是,那么我们不会添加一个,但仍然会查看其余的元素。这就是所谓的递归情况。
因此,您的代码可能如下所示:
function totalnumb = numbgreater(v,k)
%// Base case - if number of input elements is 1
if numel(v) == 1
if v > k % //Is input number > k? If it is, return 1
totalnumb = 1;
else % //If not, return 0
totalnumb = 0;
end
else %// Recursive case
if v(1) > k %// Is first element in this vector greater than k?
%// if yes, then that's 1 number that's greater, so we take 1
%// then add with calling this function again looking at the
%// second element of this vector onwards
totalnumb = 1 + numbgreater(v(2:end), k);
else
%// if no, then do the same thing as above, but don't add 1 as
%// the condition isn't satisfied
totalnumb = numbgreater(v(2:end), k);
end
end
所以,如果我们宣布v
类似于:
v = [2 3 4 1 5 6 2 3];
...如果我们宣布k = 3
,如果我们使用v
和k
调用此函数,我们会得到:
totalnumb = numbgreater(v, 3)
totalnumb =
3
这是有道理的。只有三个数字大于3.分别为4,5和6,分别位于第3,5和6位。
递归是一项棘手的业务。一旦掌握了它,就可以使用递归来雄辩地解决许多算法。
祝你好运!