【问题标题】:Is there a way to find the INDEX of the minimum value in an array using a recursive function? C++有没有办法使用递归函数找到数组中最小值的索引? C++
【发布时间】:2020-05-28 14:24:05
【问题描述】:

我需要使用 c++ 中的递归函数找到数组中最小数字的索引,该函数只能获取 2 个参数:指向数组的指针及其大小。

int smallest(int arr[], int num);

我设法做到了这一点,但是我得到了一个静态的辅助变量并在函数外部声明:

static int flag = 0;
int smallest(int* arr, int num) {
   if (flag == num - 1)
      return flag;
   if (arr[num - 1] > arr[flag]) {
      return smallest(arr, num - 1);
   } else {
      flag++;
      return smallest(arr, num);
   }
}

现在我的问题是我可以在没有静态变量或num 以外的任何其他变量的情况下执行此操作吗?这是我到目前为止得到的:

int smallest(int arr[], int num) {
    if (arr != &arr[num - 1])
        if (*arr < arr[num - 1])
            smallest(arr, num - 1);
        else
            smallest(arr + 1, num);
    return num - 1;
}

它不返回最小值的索引,但它确实到达了它的地址,当数组指针地址与最小值的地址相同时,函数结束。我怎样才能让它返回索引?

我是一名学生,我对 C++ 还很陌生,感谢您的帮助!谢谢!

===

编辑:

这最初来自家庭作业,但不使用外部帮助变量或函数的约束是我的!我很想知道它是否可能。

【问题讨论】:

  • 函数只能获取2个参数那是谁的约束?
  • arr != &amp;arr[num - 1] 应该是 arr != (arr + num - 1)*arr &lt; arr[num - 1] 应该是 *arr &lt; *(arr + num - 1)arr[0] &lt; arr[num - 1]。最好不要混合和匹配 *[] 符号。
  • 如果能得到地址,索引为address - arr。减去指针会给你两个指针之间元素数量的差异。如果两个地址不在同一个数组中,显然这是没有意义的。
  • 有了您的约束,我能想到的唯一方法是返回arr 和对smallest 的调用之间的差异,其中smallest 返回arr 内的指针。
  • 你有一个数组 int[N]。你想找到最小元素的索引。您可以要求其他人找到数组 int[N-1] 的最小元素的索引。你会怎么做?

标签: c++ arrays function recursion


【解决方案1】:

因为这显然是家庭作业,所以我不会完整地透露实际答案,但我会给出一些(希望是)好的建议。

使用递归,首先要考虑你的结束条件是什么。那应该是一个包含 1 个元素的数组。在这种情况下,您返回索引0,因为您拥有数组,它是唯一的元素,所以返回它的索引。

if(num == 1)
{
    return 0;
}

那么这对你有什么用处?将其与另一个元素进行比较。这就是你如何分解它。您的数组变成“一个元素和许多”或“它只是一个元素”。如果只有一个,则返回唯一的值。如果它很多,从第二个元素(索引 1)开始递归调用自己:

int restOfArraySmallest = smallest(arr+1, num-1) + 1;

您需要+1,因为您已经偏移了它的起点。但是您知道restOfArraySmallest 中的值是您的arr 中所有除了第一个元素的最小值的索引。因为您的递归调用不包含第一个元素,只包含其余元素。

希望这足以让您完成剩下的工作。

编辑:因为 OP 已回应并表示这对他们的家庭作业不是必需的,所以这是整个功能:

// Recursively finds the index of the smallest element of the passed-in array
int smallest(int* arr, int num)
{
    if(num <= 1)
    {
        return 0;  // If we're in the last element, the smallest is the only element
    }
    // More than one element, so find the least element in all the elements
    // past the first element of the array
    // Note: the index returned is offset from our current view of the array,
    //       so add +1 to any returned result so we can index directly from it
    int restOfArraySmallest = smallest(arr+1, num-1) + 1;

    // Compare the first element in the array to the smallest of the entire rest
    // of the array:
    if(arr[0] < arr[restOfArraySmallest])
    {
        // The first element is smaller, it's the smallest, so return that index
        return 0;
    }
    else
    {
        // The element already found is smaller, so return that index.  It's already
        // correctly offset
        return restOfArraySmallest;
    }
}

就是这样。如果最小的条目有重复,它将优先于最后一个。

递归的诀窍是不保留外部变量。您作为参数传递的内容和 RETURN BACK 是您拥有的所有信息。对于一些算法来说,这就够了。

注意,如果你对足够大的数据集使用递归函数,你最终会得到堆栈溢出。不是网站,而是崩溃类型。这个算法非常简单,因为每次传递只分配一个额外的变量和两个参数本身,但它最终会加起来。

【讨论】:

  • 感谢凯文的帮助!我今天花了至少 5 个小时试图弄清楚!您对作业的看法是正确的,但作业不需要不使用附加变量,所以我的第一个解决方案对此很有用,但是因为我很好奇,我想挑战自己,我试图找到一个解决方案,但我仍然无法弄清楚如何在递归函数中保留“计数器”以跟踪整数。或如何返回递归函数。谢谢
  • 使用完整功能对其进行了编辑。我希望我不需要额外的全局变量是有意义的。如果您觉得它有用,请将其标记为已接受的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2015-09-03
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多