使用递归的C ++查找Vector中的非零数

时间:2015-05-05 23:02:48

标签: c++ recursion

EDIT 我得到了这个代码来处理一个数组,但是我不能让它使用向量,有没有人知道如何将它从使用数组改为向量?

int count(double* arr, int length);

int main() 
{
double arr[10] = {0.0, 1.3, 2.5, 11.34, 0.0, 9.8, 6.4, 0.0, 4.3, 0.0};

cout << "There are " << count(arr, 10) << " nonzeros in this array!\n\n";

return 0;
}

int count(double* arr, int length) 
{
if (!length)
{
    return 0;
}

int c = count(arr+1, length-1);

return arr[0] != 0.0 ? c + 1 : c;
}

2 个答案:

答案 0 :(得分:2)

您循环while (i < s)永远不会退出,因为您不会在循环中修改is

实际上你可以让函数变得更简单一点,首先是没有循环(这就是递归的目的),然后意识到你只需要大小和当前索引作为参数。然后你可以像

那样
int nonzeroes(double* digits, size_t size, size_t index)
{
    if (index < size)
    {
        return (digits[index] != 0.0) + nonzeroes(digits, size, index + 1);
    }
    return 0;
}

这是有效的,因为布尔值可以隐式转换为inttrue1false0。然后它添加使用递归调用获取的下一个索引的返回值。

main功能的初始通话应该是

nonzeroes(digits, s, 0)

使用索引零开始计数。

我建议您使用调试器逐行遍历代码,同时输入递归调用以查看其工作原理。

另外,如果你想在C ++中使用动态数组,你应该使用std::vector

另一方面,对于像你这样的简单案例,与0.0进行比较会有效,但如果你通过其他算法或算术创建值,则会出现复合舍入错误,这意味着值可能是关闭但不完全等于零。这可以通过使用 epsilon 值来解决,例如使用std::numeric_limits<double>::epsilon

答案 1 :(得分:0)

我可能错了,但是使用递归你需要一个基本案例,停止调用,我认为你也不需要传递计数。

我认为一个选择可能就是这样:

int nonzeros(double digits[], int s, int i)
{
    if (i == s)
    {   
        return 0;
    }
    else if (digits[i] != 0.0)
    {
        return  (1 + nonzeros(digits, s, i + 1));
    }
    else
    {
        return (nonzeros(digits, s, i + 1));
    }
}