以递归方式计算排序数组中键的出现次数

时间:2015-11-10 05:28:31

标签: c++11 recursion vector

我试图递归地解决这个问题http://www.geeksforgeeks.org/count-number-of-occurrences-in-a-sorted-array/。 我现在的代码使用了一个带有静态变量的愚蠢的小黑客。虽然这样可行,但如果使用不同的键重复调用该函数,它将失败(因为静态变量仍会记住先前的设置值)。

int FindCount(const vector< int > &A, int l, int r, int B)
{
    static int count =0;
    // cout<<l<<' '<<r<<endl;
    if(l <= r)
    {
        int mid = (l+r)/2;
        // cout<<mid<<endl;
        if(A[mid] == B)
        {
            count++;
            FindCount(A, l, mid-1, B);
            FindCount(A, mid+1, r, B);
        }
        else if (A[mid] < B)
        {
            FindCount(A, mid+1, r, B);
        }
        else
        {
            FindCount(A, l, mid-1, B);
        }
    }
    return count;
}

我可以弄清楚它应该如何工作,但很难将其转换为代码。它应该是这样的,一旦你找到特定的键然后返回1并继续重复搜索键的左右。

如果不使用带有更干净代码的静态变量,你可以帮我做这个吗?)

3 个答案:

答案 0 :(得分:2)

你还丢弃了所有调用的返回值,但是在递归堆栈的底部(堆栈向上增长);您可以将递归的返回值添加到automatic局部变量static,而不是count count

答案 1 :(得分:2)

int FindCount(const vector< int > &A, int l, int r, int B)
{
      int count = 0;
      if(l <= r)
      {
          int mid = (l+r)/2;
          if(A[mid] == B)
          {
              count++;
              count += FindCount(A, l, mid-1, B);
              count += FindCount(A, mid+1, r, B);
          }
          else if (A[mid] < B)
          {
              count = FindCount(A, mid+1, r, B);
          }
          else
          {
              count = FindCount(A, l, mid-1, B);
          }
      }
      return count;
 }

这应该可行,虽然它仍然是O(n)算法,效率不高。

答案 2 :(得分:1)

该代码包含严重错误:您应该使用size_t而不是int。结果可能会溢出。索引器和计数应为size_t - 这是32位平台上的无符号32位整数和64位平台上的无符号64位整数。

u_seem_surprised有一个完全有效的答案。解决此问题的另一种方法是使用lambdas并捕获count变量:

#include <vector>
#include <functional>

size_t FindCount(const std::vector<int> &A, size_t l, size_t r, int B)
{
    using namespace std;
    size_t count = 0;

    function<void(const vector<int>&, size_t, size_t, int)> impl;
    impl = [&count, &impl](const vector<int> &A, size_t l, size_t r, int B)
    {
        if (l <= r)
        {
            auto mid = (l + r) / 2;
            if (A[mid] == B)
            {
                count++;
                impl(A, l, mid - 1, B);
                impl(A, mid + 1, r, B);
            }
            else if (A[mid] < B)
            {
                impl(A, mid + 1, r, B);
            }
            else
            {
                impl(A, l, mid - 1, B);
            }
        }
    };

    impl(A, l, r, B);
    return count;
}