zoukankan      html  css  js  c++  java
  • 求最大子数组的思想和代码

            对于数组ai,最大子数组定义为:ai的和最大的非空连续子数组,很明显,这个概念只对既有正元素,又有负元素的数组有意义,例如,对于ai[16] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7},最大子数组为{18, 20, -7, 12},此时的和为43,求解一个数组的最大子数组的算法依然是使用分治思想,把一个数组一分为二,最大子数组要么在左边,要么在右边,要么在中间,在中间则肯定包含中点,此时便可以从中点的左边和右边分别求出最大子数组的边界,合起来便是最大子数组,然后递归的调用此方法,便可求出原数组的最大子数组。

         代码如下:

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    
    int* find_max_crossing_subarray ( vector<int> &ci, unsigned low, unsigned mid, unsigned high); //函数返回数组的指针
    int* find_maximum_subarray (vector<int> &ci, unsigned low,  unsigned high);
    
    //函数返回数组的指针
    //函数的功能为寻找横跨中点的最大子数组的小标和和,并组成一个数组返回
    int* find_max_crossing_subarray ( vector<int> &ci, unsigned low, unsigned mid, unsigned high)  
    {
    	int *temp = new int[3];   //为防止局部变量内存被释放掉,采用动态分配内存
    	int left_sum = -1000;
    	int right_sum = -1000;
    	int sum = 0;
    	unsigned max_left = 0;
    	unsigned max_right = 0;
    	for (int i = mid; i >= 0 && i >= low ; --i)
    	{
    	     sum =  sum + ci[i];
    		 if(sum > left_sum )
    		 {
    		     left_sum = sum;
    			 max_left = i;
    		 }
    	}
    	sum = 0;
    	
    	for (unsigned j = mid + 1; j <= high; ++j)
    	{
    	     sum =  sum + ci[j];
    		 if(sum > right_sum )
    		 {
    		     right_sum = sum;
    			 max_right = j;
    		 }
    	}
    	
    	temp[0] =  max_left;
    	temp[1] =  max_right;
    	temp[2] =  left_sum + right_sum;
    	return temp;
    
     }
    
    //函数返回数组的指针
    //函数的功能为寻找一个数组的最大子数组的下标和和
    int* find_maximum_subarray (vector<int> &ci, unsigned low,  unsigned high)
    {
    	int *temp_1 = new int[3];   //为防止局部变量内存被释放掉,采用动态分配内存
    	if (low ==  high)
    	{
    	    temp_1[0] =  low;
    		temp_1[1] =  high;
    		temp_1[2] =  ci[low];
    		return temp_1;
    	}
    	else
    	{
    		 int mid = (low + high) / 2;
    		int *temp_left = new int[3];
    		int *temp_right = new int[3];
    		int *temp_cross = new int[3];
    	    temp_left= find_maximum_subarray(ci, low,mid);
    		temp_right= find_maximum_subarray(ci, mid+1,high);
    		temp_cross= find_max_crossing_subarray ( ci, low,mid,high) ;
    		if (temp_left[2] > temp_right[2] && temp_left[2] > temp_cross[2] )
    		{
    		return temp_left;
    		}
    		else
    		{
    		    if ( temp_right [2] > temp_left[2]  && temp_right[2] > temp_cross[2] )
    			{
    			     return temp_right;
    			}
    			else 
    			{
    			    return temp_cross;
    			}
    		}
    
    	}
    }
    
    int main ()
    {
       vector<int> ai;
        int num = 0;
        cout << "please enter the numbers that need to find the maximum subarray:" << endl;
        while (cin >> num )
            ai.push_back(num);
    
    	int* maximum_subarray = find_maximum_subarray(ai,0,ai.size () - 1);
    	cout << maximum_subarray[0] << "	"
    		    << maximum_subarray[1] << "	"
    			<< maximum_subarray[2] << "	"
    			<< endl;
    	delete[] maximum_subarray;
    
      return 0;
    }
    

      运行结果为:

       上述结果表示为最大子数组为ai[7]到ai[10],此时和为43。

        上述代码可能存在内存分配的问题,C++的学习进度还没到这一块,因此还没解决这个问题。

         不得不说算法的力量是无穷的,或者说思想的力量是伟大的。

        夜深了,你在干嘛呢?

  • 相关阅读:
    hanoi(老汉诺塔问题新思维)
    ABP文档
    ABP文档
    ABP文档
    ABP文档
    ABP文档
    ABP文档
    ABP文档
    ABP文档
    ABP框架
  • 原文地址:https://www.cnblogs.com/1242118789lr/p/6691144.html
Copyright © 2011-2022 走看看