所以在编程课程中,我正在学习递归。我得到了一个编写递归函数的赋值,该函数获取排序数组和数字,如果存在则返回数组中该数字的索引。
我还不太了解递归的主题所以我需要一点帮助我的代码。我认为我正朝着正确的方向前进,但我再次对这个问题感到挣扎,所以我觉得我可以在这里找到指导和帮助。
这是我目前的代码:
private static int arrayIndexValue(int[] arr, int ind)
{
if (ind > arr.Length/2)
{
return arrayIndexValue(arr.Length/2, ind)
}
else if (ind < arr.Length/2)
{
return arrayIndexValue(arr.Length/2)
}
}
基本上我想在这里写的是这样的:
如果用户插入的数字小于数组的中间部分,则继续使用该函数,但将数组切成两半(二进制搜索)
相同如果数字更大(我建议使用我的函数与二进制搜索,但你可以看到我不知道如何将它应用于我的代码)
答案 0 :(得分:2)
递归的工作原理是将整个问题分解为更小的部分。如果您处于最小的部分(意味着您的数组只有一个值),那么您将获得解决方案。这也是你必须处理的第一个案例。
if (arr.Length == 1) return arr[0];
现在你可以开始解决这个问题了。二进制左或右决定。正如您已经写过的那样,您想要检查天气,数字是从数组中间向左或向右的。因此,在您的情况下,您需要使用[ ]
运算符访问数组中的元素:
if (ind > arr[arr.Length / 2]) // check if larger than the middle element
要提取阵列的一部分,您需要第二个阵列,您可以在其中复制所需的内容。由于您打算只将当前数组的一半传递给递归调用,因此您只需要一半的大小。
int [] temp = new int[arr.Length / 2];
现在您可以根据您的情况复制您想要的部分(第一个或第二个),并继续使用递归调用进行搜索。
要复制数组,您可以使用Arra.Copy方法。您可以将开始和长度传递给此方法,它会将左侧或右侧部分复制到int [] temp
数组中。以下是如何复制正确部分的示例:
Array.Copy(arr, arr.Length / 2, temp, 0, arr.Length / 2);
最后,您需要触发递归调用。此调用将期望新数组和仍然相同的数字。因此,既然您复制了前一个数组的左半部分或右半部分,现在将新的短数组传递给递归调用:
return arrayIndexValue(temp, ind);
你有它吗
答案 1 :(得分:1)
我得到了一个编写递归函数的赋值,它获取了排序数组 和一个数字,并返回数组中该数字的索引if 存在。
在您的方法中,您检查索引而不是值 - 您应该比较元素的值,而不是索引。
要编写递归函数来查找元素,您应该传递数组,元素要查找,启动索引和结束索引。开始索引和结束索引将用于查找数组的一部分。
您的方法将是这样的:
private static int GetIndex(int[] arr, int element, int startIndex, int endIndex)
{
if (startIndex > endIndex)
{
return -1; //not found
}
var middleIndex = (startIndex + endIndex) / 2;
if (element == arr[middleIndex])
{
return middleIndex;
}
if (element < arr[middleIndex])
{
return GetIndex(arr, element, startIndex, middleIndex - 1);
}
else
{
return GetIndex(arr, element, middleIndex + 1, endIndex);
}
}
并得到一些索引:
static void Main(String[] args)
{
var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var element = 5;
var index = GetIndex(arr, element , 0, arr.Length - 1);
}
答案 2 :(得分:1)
所以你现在遇到的问题是你没有将问题分解为重复步骤。它实际上应该是非常类似于没有所有变量的循环流。我想先做一些简单的事情。
void int find(int[] values, int at, int value) {
while (values.Length < at && at >= 0) {
if (values[at] == value) {
return at;
}
at = at + 1;
}
return -1;
}
这个函数每次只通过递归将一个索引向上移动一个,但我们也可以用循环做一些非常相似的事情。
void int find(int[] sortedValues, int start, int end, int value) {
var midIndex = (start + end) / 2;
var mid = sortedValues[midIndex];
if (start == end) {
return mid == value ? midIndex : -1;
} else if (mid > value) {
return find(sortedValues, mid, end, value);
} else if (mid < value) {
return find(sortedValues, start, mid, value);
} else {
return midIndex;
}
}
我们通常谈论递归的全部原因是它通常被使用,因此你没有&#34;变异&#34;州。每个值的变量和值都相同。你可以打破这个,但通常被认为是有益的。快速查看您的问题会产生类似
的内容GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> :t "#"
"#" :: [Char]
但是,这并不完美。它已经知道像边缘情况会导致崩溃的问题。绝对应该清理一下。如果你真的想要将你的脚趾浸入递归中,试试一种纯粹的功能性语言,你不能改变它,比如Haskell,Elm,或者像F#,Clojure或Scala那样有些不纯洁的东西。无论如何都很有趣。