• 最大子数组02


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

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

    程序设计思路:

        1.最大子数组2在最大子数组1的基础之上进行了迭代,从题目的要求中可以看出,本次的程序就是利用最大数组1的思想去求解一个循环数组中的最大子数组。

        2.程序设计的思路一:将用户输入的整形数组进行复制,形成一个长度为两倍输入长度的数组,既可以完成循环的去查找数组中的最大子数组,不过在此基础上要注意一个问题,那就是最后求得的子数组的长度不能超过用户输入的数组长度。

        3.通过设置循环条件,控制生成的最大子数组长度,利用最大子数组1的思想来查找最大子数组。

    源程序代码如下所示:

    #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
            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;
            }    
        }
        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;
    }

    运行结果截图:

    1.测试程序能否求出循环的最大子数组:

     

    2.测试程序能够求出连续的最大子数组:

    周活动记录日志:

    日期任务 听课/时 编写程序/时 查阅资料/时 日总计/时
    星期一 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

    调用函数时出错

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

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

    3月25日 2

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

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

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

     

    工作照片:

    团队开发合作成员(宋海林,贾兆款:博客园http://www.cnblogs.com/seven-seven/p/5326800.html))

  • 相关阅读:
    强连通分量填坑记
    Car的旅行路线
    油滴扩散
    【转】孔乙已
    [CQOI2007]余数求和
    树形dp入门两题
    一本通 3.1 例 1」黑暗城堡
    一点点有的没的和一年总结
    leetcode答案 有效的括号(python)
    leetcode数据库题目及答案汇总
  • 原文地址:https://www.cnblogs.com/hulidanxiang/p/5322705.html
Copyright © 2020-2023  润新知