[英]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 min = std::numeric_limits<int>::max();
for(int i = 0; i < size ; i++) min = std::min(min,a[i]);
短得多,沒有內存分配,容易循環,因此編譯器可能會1)將其向量化以達到最大速度2)使用正確的預取以提高速度。
對於最大值,我將使用類似以下的方法:
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
可以使用相同的模式輕松實現。
只是部分答案,因為我尚未詳細驗證算法,但是最好先復制數組,然后破壞性地使用該副本存儲您的值。
它可能會使用更多的內存,但是可以節省內存管理的運行時和錯誤追蹤時間。
如果您冒着陷入難以解決的情況而導致太深的遞歸的風險,則可以通過迭代實現而不是遞歸實現來改進。
這是找到最小值和最大值的可怕算法。 您可以使用更簡單,更短和更快的解決方案:
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;
}
沒有增強支持:
#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;
}
使用STL中的算法:
從C ++ 11開始:您可以使用std::minmax_element
一次檢索兩者: https std::minmax_element
const 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
。
基本上,遞歸建議不要在數組中找到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));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.