递归地查找数组中的最小值和最大值
Recursively find min and max value in array
我做了一个递归函数,从一个可以包含任意数量元素的数组中找到最大值和最小值。这样做的主要原因是为了从Dicom图像的像素数据中找到最小最大值。我将这个递归函数作为测试代码,其中我用0-1000范围内的随机数填充int
类型数组。我的代码如下。我给出了整个代码,你可以很容易地在Visual Studio中自己运行程序。
#include <stdio.h>
#include <string>
#include <iostream>
#include <math.h>
#include <time.h>
using namespace std;
void recursMax(int* a, int size, int* maxValue)
{
int half = size/2;
int* newMax = new int[half];
for(int i=0; i<half; i++)
{
newMax[i]=a[i]>a[size-i-1]?a[i]:a[size-i-1];
}
if(half>1)
{
recursMax(newMax, half, maxValue);
}
if(half == 1)
{
*maxValue = newMax[0];
delete [] newMax;
}
}
void recursMin(int* a, int size, int* minValue)
{
int half = size/2;
int* newMin = new int[half];
for(int i=0; i<half; i++)
{
newMin[i]=a[i]<a[size-i-1]?a[i]:a[size-i-1];
}
if(half>1)
{
recursMin(newMin, half, minValue);
}
if(half == 1)
{
*minValue = newMin[0];
delete [] newMin;
}
}
int main ()
{
int size = 100;
int* a = new int[size];
srand(time(NULL));
for(int i=0; i<size; i++)
{
a[i]=rand()%1000;
cout<<"Index : "<<i+1<<", "<<a[i]<<endl;
}
cout<<endl<<endl<<"Now we look to find the max!"<<endl;
int maxValue = 0;
int minValue = 0;
recursMax(a, size, &maxValue);
cout<<maxValue<<endl;
recursMin(a, size, &minValue);
cout<<"Now we look for the min value!"<<endl<<minValue<<endl;
cout<<"Checking the accuracy! First for Max value!"<<endl;
for(int i=0; i<size; i++)
{
cout<<"Index : "<<i+1<<", "<<maxValue-a[i]<<endl;
}
cout<<"Checking the accuracy! Now for min value!"<<endl;
for(int i=0; i<size; i++)
{
cout<<"Index : "<<i+1<<", "<<a[i]-minValue<<endl;
}
delete [] a;
return 0;
}
我的问题是,你认为我的算法工作正确吗?我有点怀疑。此外,我是否正确处理或维护内存?或者在代码中会有一些内存泄漏?
您应该将delete [] newMax;
从最后的if
语句中取出,否则您将永远无法释放内存。这样的:
if(half == 1)
{
*maxValue = newMax[0];
}
delete [] newMax;
对于recursMin函数也是如此。
你的算法似乎有效,但过度。使用递归和分配内存只是为了找到最小和最大不是一个好的风格。
对于最大值,我会这样做:
int ArrayMax(const int *begin, const int *end)
{
int maxSoFar = *begin; // Assume there's at least one item
++begin;
for(const int *it = begin; it!=end; ++it)
{
maxSoFar = std::max(maxSoFar, *it);
}
return maxSoFar
}
现在你可以说:
int main ()
{
int size = 100;
int* a = new int[size];
srand(time(NULL));
for(int i=0; i<size; i++)
{
a[i]=rand()%1000;
cout<<"Index : "<<i+1<<", "<<a[i]<<endl;
}
int theMax = ArrayMax(a, a+size);
}
不用说,您可以将ArrayMax
转换为任何类型的模板函数,并且ArrayMin
可以使用相同的模式轻松实现。
我建议这个代码查找最小值,最大值是类似的:
int min = std::numeric_limits<int>::max();
for(int i = 0; i < size ; i++) min = std::min(min,a[i]);
短得多,没有内存分配,容易循环,所以编译器可能会1)向量化它以获得最大速度2)使用正确的预取以获得更高的速度
只是部分答案,因为我还没有详细验证算法,但是您最好先复制数组,然后使用该副本破坏性地存储您的值。
它可能会使用更多的内存,但可以节省运行时间和内存管理上的bug追踪时间。
如果您冒着遇到导致深度递归的退化情况的风险,您可能会使用迭代实现而不是递归实现来改进。
使用STL中的算法:
-
从c++ 11开始,您可以使用
std::minmax_element
同时检索两者:https://ideone.com/rjFlZiconst int a[] = {0, 1, 42, -1, 4}; auto it = std::minmax_element(std::begin(a), std::end(a)); std::cout << *it.first << " " << *it.second << std::endl;
-
在c++ 03中,你可以使用
std::min_element
和std::max_element
这是一个寻找最小值和最大值的糟糕算法。您可以使用更简单、更短、更快速的解决方案:
const int maxInArray( const int* beg, const int* end) {
const int* it = std::max_element( beg, end);
if ( it == end)
{
std::cout << "There is no smallest element" << std::endl;
}
else
{
std::cout << "The smallest element is " << *it << std::endl;
}
return *it;
}
或遍历数组:
int maxInArray( const int* beg, const int* end) {
int max;
if ( end - beg < 1 ) return -1;
max = *beg
while ( beg++ != end) {
if ( *beg > max) max = *beg;
}
return max;
}
不支持boost:
#include <iostream>
#include <limits>
int main() {
int max = std::numeric_limits<int>::min();
int min = std::numeric_limits<int>::max();
int num;
while ( std::cin >> num) {
if (num > max) {
max = num;
}
if (num < min) {
min = num;
}
}
std::cout << "min: " << min << std::endl;
std::cout << "max: " << max << std::endl;
return 0;
}
或使用boost:
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
using namespace boost::accumulators;
int main() {
// Define an accumulator set for calculating the mean, max, and min
accumulator_set<double, features<tag::min, tag::max> > acc;
int num = -1;
bool empty = true;
while ( std::cin >> num && num >= 0) {
empty = false;
acc( num);
}
if ( ! empty) {
// Display the results ...
std::cout << "Min: " << min( acc) << std::endl;
std::cout << "Max: " << max( acc) << std::endl;
}
return 0;
}
基本上不建议通过递归在数组中查找max,因为它不是必需的。分治算法(递归)耗时更大。但即使你想用它,你也可以用我下面的算法。基本上,它将数组中最大的元素放在第一个位置,并且几乎具有线性运行时间。(这个算法只是一个递归的错觉!):
int getRecursiveMax(int arr[], int size){
if(size==1){
return arr[0];
}else{
if(arr[0]< arr[size-1]){
arr[0]=arr[size-1];
}
return(getRecursiveMax(arr,size-1));
}
}
- 查找矩阵C++中每一列和每一行的最小和最大元素
- 如何在数组中交换最小和最大的位置?
- 需要使用模板查找数组的第二个最小和最小值
- 使用 std::min_element、std::max_element 查找矢量中的最小和最大元素
- 为什么我不能使用最小和最大这两个词作为变量名称?
- 在运行时为随机分布类成员设置最小和最大边界?
- 如何使用气泡排序从最小到最大对 4 个数组进行排序? C++
- 如何拒绝 cin 中的字符输入并定义最小和最大整数值
- 类型 *阵列的最小或最大值的类功能 *
- C++ 100 万个变量名称的最小和最大变量名称长度是多少
- 想要以正弦曲线的形式在循环中连续将值从最小变为最大
- 数组内存地址总是按最小到最大的顺序排列吗
- 使用向量而不是数组从最小到最大对数字进行排序C++
- 在 c++ 中给出两个整数向量(大小和类型相同),我想从最小到最大元素对一个进行排序,并更改第二个向量的顺序
- 在用户定义结构的向量中查找最小和最大元素的索引
- 二进制搜索,用于查找排序数组中比给定值最小和最大的元素
- c++中的函数如何以最小的复制返回值或引用?
- 我如何确定我可以传递给编译器选项的最小和最大值
- 如何为每个光栅带设置最小和最大颜色值(使用GDAL)
- 在c++中最小化分支-如果值是非零则递增