zoukankan      html  css  js  c++  java
  • 求数组中的最大子数组2

    题目:  返回一个整数数组中最大子数组的和。

    要求:
          (1) 输入一个整形数组,数组里有正数也有负数。
          (2)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
         (3)如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1],A[0]……A[j-1]之和最大。
         (4)同时返回最大子数组的位置。
         (5)求所有子数组的和的最大值。

    设计思路:

          (1)此题和第一次求数组的最大子数组相比,是把第一次求得数组首尾相接形成环,求此环的最大子数组。

          (2)要正确理解题意,求得的子数组的个数不能超过这个环形数组中的数的个数。由题意可设计如下方法:将原始输入的数组复制一份,将复制的数组放在初始数组的后边,并限定最大子数组的个数不能超过初始数组的个数(例:初始输入数组为{1 2 -4 5 6},则变换后的数组为{1 2 -4 5 6 ,1 2 -4 5 6})。

          (3)这样,就将一个循环数组转换为一个顺序数组,求得此变换后的顺序数组的最大子数组(个数不超过初始数组的个数),求得的最大子数组即为形成的环形数组的最大子数组。

    //本程序实现的功能是:将一个数组首尾相接连成环,寻找环中的最大子数组
    //2016.3.26
    #include<iostream>
    #include<string>
    #define MAX 200
    using namespace std;
    
    void InPutArray(int intArray[],int &intNum)
    {
        cout << "请输入一个整数数组(数组个数不超过100):" << endl;
        for (int i = 0; i < 100; i++)
        {
            if (cin.peek() == 10)
            {
                cin.clear();
                break;
            }
            cin >> intArray[i];
            intNum++;
        }
    }
    
    void GetMaxSonArray(int intArray[],int &intPre,int &intAfter,int intDblNum)
    {
        int intSum = -65535;
        int intCurSum=0;
        int intSegment;
        int intResult[MAX][MAX];
        int intX;
        int intY;
        intX = 0;
        intY = 0;
        intSegment = 0;
    
        intPre = 0;            //初始化最大子数组的第一个数的位置为0
        int intDistance=0;       //最大子数组第一个数和最后一个数的距离
        int intSignalNum;
        intSignalNum = intDblNum / 2;
        for (int i = 0; i < intDblNum; i++)
        {
            intCurSum = intCurSum + intArray[i];
            intDistance = intAfter - intPre + 2;           //此处应该为加2,不能加1
            cout << "intDistance=" << intDistance <<" "<< "intSignalNum=" << intSignalNum << endl;
            if (intDistance == intSignalNum)
            {
                intResult[intX][intY] = intPre;
                intResult[intX][intY + 1] = intAfter;
                intResult[intX][intY + 2] = intSum;
                intX = intX + 1;
    
                intCurSum = intCurSum - intArray[intPre];
                intPre = intPre + 1;
            }
    
            if (intCurSum>intSum)
            {
                intSum = intCurSum;
                intAfter = i;
            }
            if (intCurSum < 0)
            {
                intResult[intX][intY] = intPre;
                intResult[intX][intY + 1] = intAfter;
                intResult[intX][intY + 2] = intSum;
                intX = intX + 1;
                intSegment = intSegment + 1;
                intSum = 0;
                intCurSum = 0;
                intPre = i + 1;
                intAfter = 0;
            }    
    
            cout << "intPre=" << intPre << " " << "intAfter=" << intAfter << endl;
            cout << "intSum=" << intSum << " " << "intCurSum=" << intCurSum << endl;
        }
        intResult[intX][intY] = intPre;
        intResult[intX][intY + 1] = intAfter;
        intResult[intX][intY + 2] = intSum;
        intSegment = intSegment + 1;
    
        int intLocation = 0;                       //记录最大子数组的位置
        int max;
        max = intResult[0][2];
        for (int i = 0; i < intSegment; i++)
        {
            if (intResult[i][2]>max)
            {
                max = intResult[i][2];
                intLocation = i;
            }
        }
    
        intPre = intResult[intLocation][0];
        intAfter = intResult[intLocation][1];
    }
    
    int main()
    {
        int intNum=0;                   //此处开始没有初始化,导致调用函数时出错,不能返回数组
        int intArray[MAX];
        int intPre=0;
        int intAfter=0;
        int intSum=0;
    
        InPutArray(intArray, intNum);
    
        //扩展数组。方法:复制输入的数组,将其放在输入的数组的后边,这样就可以看成是一个环形数组了
        int intDblNum = 2 * intNum;
        int j = 0;
        for (int i = intNum; i < intDblNum; i++)        
        {
            intArray[i] = intArray[j];
            j = j + 1;
        }
    
        GetMaxSonArray(intArray, intPre, intAfter, intDblNum);
    
        cout << "最大的子数组为:" << endl;
        for (int i = intPre; i <= intAfter; i++)
        {
            cout << intArray[i] << " ";
            intSum = intSum + intArray[i];
        }
        cout << endl;
        cout << "最大的子数组的和为:" << intSum << endl;
        return 0;
    }

    实验截图:

         测试是否能够判断最大子数组的个数不能超过初始输入数组的个数。

         测试是否能够成环进行求解

         判断最大

    工作图片:

    周活动记录日志:

    日期任务 听课/时 编写程序/时 查阅资料/时 日总计/时
    星期一 2 2   4
    星期二   2   2
    星期三   2 2 4
    星期四 2   1 3
    星期五   4   4
    星期六        
    星期日    1    1
    周总计 4 11 3

    18

    时间记录日志:

    日期 开始时间 结束时间 中断时间 净时间/分 活动 备注
    3/21 14:00 15:50 10 100 听课 软件工程上课
      19:00 21:00   60 编写程序 课堂练习作业
    3/22 19:00 21:30  20 120 自习  
    3/23  14:30  18:00  15   自习  
       19:00  22::00   180   编写程序  作业
    3/24 14:00 15:50  10 100 上课 软件工程上课
      20:00 22:10  10 120 查资料,分析程序 课堂练习作业
    3/25 16:20 18:30  10 120 编程  
      19:10 21:45   145 查阅资料+编程  

    缺陷日志:

    日期 编号 缺陷内容 引入阶段 排除阶段 修复时间 修复缺陷
    3月21日 1

    调用函数时出错,不能返回参数

    执行阶段 将功能加入到主函数中进行对比分析,调试时发现错误 10+

    变量未初始化,导致调用函数时无法返回参数,所以初始化变量

    3月25日 2

    计算循环数组的最大子数组时,最大子数组个数超出初始数组的个数

    执行阶段 通过设置相关参数的输出,进行分析判断 20+

    判断时的条件出错,导致此功能未实现,修改完善判断条件

    合作者:贾兆款、宋海林(http://www.cnblogs.com/hulidanxiang/p/5322705.html

  • 相关阅读:
    Python超级篇-机器学习
    python高给篇-爬虫
    机器学习之-sklearn
    luogu3384 【模板】树链剖分
    bzoj3884 上帝与集合的正确用法
    luogu2765 魔术球问题
    poj2976 Dropping tests 01分数规划
    luogu2764 最小路径覆盖问题
    luogu2763 试题库问题
    luogu2762 太空飞行计划问题
  • 原文地址:https://www.cnblogs.com/seven-seven/p/5326800.html
Copyright © 2011-2022 走看看