C++ 如何修复这个求最大值和最小值的递归(分治)过程?
为了在递归和分治方法中找到最大值和最小值,我使用伪代码进行编码。但是这段代码有一个问题,我找不到最大值和最小值。此处最大值和最小值的结果不正确C++ 如何修复这个求最大值和最小值的递归(分治)过程?,c++,algorithm,recursion,max,min,C++,Algorithm,Recursion,Max,Min,为了在递归和分治方法中找到最大值和最小值,我使用伪代码进行编码。但是这段代码有一个问题,我找不到最大值和最小值。此处最大值和最小值的结果不正确 #include <bits/stdc++.h> using namespace std; int num[50000], max1 = 0, min1 = 0, max2 = 0, min2 = 0; void maxmin(int i, int j, int &max1, int &min2) { if(i =
#include <bits/stdc++.h>
using namespace std;
int num[50000], max1 = 0, min1 = 0, max2 = 0, min2 = 0;
void maxmin(int i, int j, int &max1, int &min2)
{
if(i == j)
max1 = min1 = num[i];
else if(i == j - 1)
{
if(num[i] < num[j])
{
max1 = num[j];
min1 = num[i];
}
else
{
max1 = num[i];
min1 = num[j];
}
}
else
{
int mid = (i + j) / 2;
maxmin(i, mid, max1, min1);
maxmin(mid+1, j, max2, min2);
if(max1 < max2)
max1 = max2;
if(min1 > min2)
min1 = min2;
}
}
main()
{
int n, i, minValue, maxValue;
cout<<"No. of Data: ";
cin>>n;
cout<<"\nRange(min, max): ";
cin>>minValue>>maxValue;
for(i=0; i<n; i++)
{
num[i] = minValue+(rand()%(int)(maxValue-minValue+1));
}
maxmin(0, n-1, max1, min1);
cout<<"\nMax: "<<max1<<"\tMin: "<<min1<<endl;
}
maxmin0,n-1,max1,min1中的伪代码/代码有什么问题;,是否希望通过引用传递max1和max2?如果是,您需要将函数签名修改为:
void maxmin(int i, int j, int & max1, int & min2)
好的,在下面你们会发现两个函数,当被调用时。将查找数组中最大和最小的元素。如果你想使用它们,你将不得不改变你的主代码来让它们工作 你的主机可能看起来像这样
#include <iostream>
#include <stdlib.h>
using namespace std;
int findSmallest(int tempArray[], int a_Size);
int findLargest(int tempArray[], int a_Size);
int main()
{
int myArray[101];
int array_Size = 101;
for (int i = 0; i < 101; i++)
{
myArray[i] = rand() % 100 + 1;
}
cout << "The largest value in the array is: " << findLargest(myArray, array_Size) << endl;
cout << "The Smallest value in the array is: " << findSmallest(myArray, array_Size) << endl;
return 0;
}
int findSmallest(int tempArray[], int a_Size)
{
int Smallest = tempArray[0];
for (int i = 0; i < a_Size; i++)
{
if (tempArray[i] < Smallest)
{
Smallest = tempArray[i];
}
}
return Smallest;
}
对这个函数进行原型化并测试,它将在数组中找到最小的数字
int findLargest(int tempArray[], int a_Size)
{
int maxValue = 0;
for (int i = 0; i < a_Size; i++)
{
if (tempArray[i] > maxValue)
{
maxValue = tempArray[i];
}
}
return maxValue;
}
如果您对其进行原型化和测试,它将在您的数组中找到larges元素
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
void BasicRecurisonExample();
void getLargest(int tempArray[], int a_Size);
void getSmallest(int tempArray[], int a_Size);
int main()
{
BasicRecurisonExample();
return 0;
}
void BasicRecurisonExample()
{
string input;
int myArray[101];
int array_Size = 101;
for (int i = 0; i < 101; i++)
{
myArray[i] = rand() % 100 + 1;
}
getLargest(myArray, array_Size);
cout << "\n\n";
getSmallest(myArray, array_Size);
cout << "\n\nDo you want to do another, if so type yes: ";
getline(cin, input);
if (input == "yes")
{
BasicRecurisonExample();
}
}
void getSmallest(int tempArray[], int a_Size)
{
int Smallest = tempArray[0];
for (int i = 0; i < a_Size; i++)
{
if (tempArray[i] < Smallest)
{
Smallest = tempArray[i];
}
}
cout << "The smallest Element is: " << Smallest;
}
void getLargest(int tempArray[], int a_Size)
{
int maxValue = 0;
for (int i = 0; i < a_Size; i++)
{
if (tempArray[i] > maxValue)
{
maxValue = tempArray[i];
}
}
cout << "The largest element is: " << maxValue;
}
你在处理数组和循环,这意味着你需要有逻辑来防止它是无限的,因为你可以通过删除一个if语句来无限地调用它自己。。。这是递归阶段,故事的结尾,主要的void函数直接调用它的self,这是它最基本的递归
没有理由使某些事情过于复杂,例如,使用函数调用返回将是尾部递归。。他们不需要这个。。。你所要做的就是键入yes,它将再次调用它的self。分治递归算法的工作原理是将工作划分为最简单的情况,通常是一个元素,通过递归调用一个较小的问题本身,然后合并这些调用的结果。Mergesort是分而治之的一个很好的例子 分治算法如下所示: 检查终止条件start==stop,并为此数组值设置最小和最大引用参数最简单的情况是一个数组元素。在这种情况下,该元素是一个元素的最小值和最大值。 将数组分成左右两半,并使用这两半进行递归调用,保存到单独的变量中。然后通过查找左右调用的最小值和最大值来组合调用结果。 实现此算法的代码:
#include <iostream>
#include <limits>
void maxmin_divide_and_conquer(int arr[], int start, int stop, int &min, int & max)
{
if (start == stop)
{
min = max = arr[start];
}
else
{
int midpoint = (start + stop) / 2;
int leftMin;
int leftMax;
int rightMin;
int rightMax;
maxmin_divide_and_conquer(arr, start, midpoint, leftMin, leftMax);
maxmin_divide_and_conquer(arr, midpoint + 1, stop, rightMin, rightMax);
if (leftMin < rightMin)
min = leftMin;
else
min = rightMin;
if (leftMax > rightMax)
max = leftMax;
else
max = rightMax;
}
}
int main()
{
const int size = 10;
int arr[size] = { 99, 34, 15, 17, 19, 26, 18, 783, 14, -6 };
int min;
int max;
maxmin_divide_and_conquer(arr, 0, size - 1, min, max);
std::cout << "Divide and Conquer recursive --- " << '\n';
std::cout << "Minimum is: " << min << '\n' << "Maximum is: " << max << "\n\n";
return 0;
}
这里与您的代码的不同之处在于,我没有使用任何全局变量,您的min1和max2被用作函数中的全局变量,这将是您问题的一大部分。递归通常应使用参数和/或局部变量,以防止外部信息影响调用。换句话说,递归算法通常是自包含的,避免了作为参数传递的数据之外的数据,也避免了设置参数或返回值以外的数据的副作用
我也不认为有必要增加I==j-1的情况,因为这只是复制了一些代码来组合结果。我认为您的伪代码有问题。为什么这里使用max1变量有两个目的?查看您版本的我的代码
#include<bits/stdc++.h>
using namespace std;
int Max(int x,int y){ //genarate the max number between to number
return x>y?x:y;
}
int Min(int x,int y){ //genarate the min number between to number
return x<y?x:y;
}
void maxmin(int x, int y, int *number, int &max, int &min);
int main(){
//*/
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
//*/
int nCase,nInput,number[10000],max,min;
/*
* nCase denotes the number of test case
* nInput<10000 number of element in each test case
* number[10000] number array to find max-min
* max-min stores the max and min number
* x, y function arguments
*/
scanf("%d",&nCase);
for(int k=1; k<=nCase;k++){ //taking number of test cases
scanf("%d",&nInput); //number of input
for(int i=0;i<nInput;i++){ //taking input numbers for each case
scanf("%d",&number[i]);
}
maxmin(0,nInput-1,number,max,min); //array as pointer
printf("Case: %d\n",k);
printf("The max number is %d\n",max);
printf("The min number is %d\n",min);
}
return 0;
}
void maxmin(int x, int y, int *number, int &max, int &min){
if(y-x<=1){
max=Max(number[x],number[y]);
min=Min(number[x],number[y]);
}else{
int mid=(x+y)/2,max1,max2,min1,min2;
/*
* mid midle index
* max1 , max2, min1, min2 temp variables
*/
maxmin(x,mid,number,max1,min1);
maxmin(mid+1,y,number,max2,min2);
max=Max(max1,max2);
min=Min(min1,min2);
}
}
输出:
Minimum is: -6
Maximum is: 783
Case: 1
The max number is 5
The min number is 1
Case: 2
The max number is 6
The min number is 4
是的,我尝试通过引用来传递它,但它不起作用。@JahidulIslam在您的问题正文中,您建议您尝试修改函数调用。但是您需要修改函数签名,而不是调用。尽管这取决于代码的逻辑是否正确。我尝试使用void maxminint I、int j、int&max1和min1通过引用传递max1和min1,请提供您正在遵循的伪代码。您应该自己在代码中找到错误。使用调试器。谢谢,但这不是一个递归过程。递归是当一个函数调用它自己时,正如我说的,你可以根据自己的需要操作它。这是一个基本示例,向你展示了如何操作数组来定位最小和或最大的元素。我在这个解决方案中没有看到任何递归。我看到了for循环的迭代。递归是当一个函数直接或间接地调用它自己时,它是一个基本的概念,目前是,而且几乎总是完全过于复杂。如果您想递归地执行此操作,请弄清楚为什么或如何强制函数直接或间接地调用其自身。递归可以是像1这样简单的东西。在空中创建数组。2.创建两个函数以查找返回值的最小值和最大值3。创建一个空白来显示输出,然后用它来调用你想要递归的初始函数。迭代=循环,递归=调用self,你的代码=迭代,提问=递归。是的,谢谢。但我想我无法表达我的问题。因为我不仅需要递归,还需要分治方法。啊,分治将是这里的关键信息。我会看看是否能在稍后更新我的答案。@JahidulIslam我已经用分而治之的方法更新了我的答案
l算法和注释,说明这与您的尝试有何不同。@JahidulIslam如果此答案有用,请不要忘记您可以将其标记为已接受的答案。
Case: 1
The max number is 5
The min number is 1
Case: 2
The max number is 6
The min number is 4