• 最大子数组和02


    1、题目要求:

      (1)输入一个整形数组,数组里有正数也有负数;

      (2)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和;

      (3)如果数组A[0]……A[j-1]首位相邻,允许A[i-1],……A[n-1],A[0]……A[i-1]之和最大;

      (4)同时返回最大子数组的位置。

    2、实现思路:

      (1)先要输入一组整形数,直到输入回车结束;

      (2)分离出每一个数,按顺序存放到整形数组里;

      (3)每一个、相连续两个、三个……都是子数组,分别求出子数组的和,把最大的和输出。

    3、思路整理(实现步骤):

      (1)输入数组元素,用空格分开,输入的是字符,转化为整形数,连续的0~9字符,按所在数位进行放大求和,得出输入的整形数;

      (2)若输入的字符是空格,则将空格前的数存放入整形数组中;

      (3)按回车,输入结束,开始计算;

      (4)计算过程:

          把数组复制一遍,按顺序存放到原数组的后面,生成一个新的数组,长度为原数组的两倍,前后两部分相同;

          以下加操作全部只循环n次,以免加到重复的数;

                    从第一个数开始,依次比较大小,最大的数单独存放在num1;

          第一个数,开始,求arr[1]+arr[2]+……+arr[n],将所有和的最大值与num1 比较,最大值存入num1;

          再求arr[i]+arr[i+1]+……+arr[k],将所有和的最大值与num1 比较,最大值存入num1;

          直到arr[i] 为最后一个数为止,num1 即为子数组最大的和。

    4、源代码:

    #include <iostream>
    using namespace std;
    
    char arr[1000];//接收数据,并以字符串形式保存
    int arr1[100];//保存转换来的整数
    int arr2[200];//保存扩大两倍后的数组
    
    int k=0;//计数标志
    void chtoin()//将字符形式的数组转为整型
    {
        int i=0;
        int j=10;
    
        int num1=0;//保存每一位数字
        int num2=0;//保存数字整体
        bool flag=0;//作为正负标志
        char ch[]="#";
    
        cout<<"请输入数组(中间以空格隔开):"<<endl;
        gets(arr);
    
        strcat(arr,ch);//将#存在字符数组后,作为结束标志。
    
        for (;;)
        {
    
    
            if(arr[i]=='#')//遇到#结束,并将#前的数存入整型数组
            {
                if (flag==0)//flag为0,说明读入的数为正数
                {
                    arr1[k]=num2;
                    k++;
                }
                else//flag为1,说明读入的数为负数
                {
                    arr1[k]=0-num2;
                    k++;
                }
                break;
            }
            else
            {
                if (arr[i]==' ')//遇到空格,将空格前一个数存入整型数组
                {
                    if (flag==0)
                    {
                        i++;
                        arr1[k]=num2;
                        num2=0;
                        k++;
                    }
                    else
                    {
                        i++;
                        arr1[k]=0-num2;
                        num2=0;
                        flag=0;
                        k++;
                    }
    
                }
                else if (arr[i]=='-')//遇到-,判断为负数,将flag置位1
                {
                    i++;
                    flag=1;
                }
                else
                {
                    num1=arr[i]-'0';
                    num2=num1+num2*j;
                    i++;
                }
            }
        }
    }
    void arr1toarr2()//数组扩展函数,将数组扩展到原来的两倍
    {
        int i=0;
        for(i;i<k;i++)
        {
            arr2[i]=arr1[i];
        }
        for (;i<2*k;i++)
        {
            arr2[i]=arr1[i-k];
        }
    }
    void main()
    {
        int j=0;//作为每一轮,从第几位开始求和
        int i;//作为数组下标
        int x=0;//作为移位标志
        int y1,y2=0,y3,y4;//y1表示最大数组的首位,y2计算最大数组个数,y3保存中间过程中最大数组长度,y4保存最终长度。
        chtoin();
        arr1toarr2();
        int num1=arr2[0],num2=0,num3=0;//num1保存每一轮的最大值,num2求和,num3保存最终的最大值
        for (;;)
        {
            i=x;//已经移位到x,i作为数组下标
            for(;;)
            {
    
                num2+=arr2[i];
                y2++;
                if (num2>=num1)
                {
                    y3=y2;
                    
                    num1=num2;
                }
                if (j==k+x)
                {
                    break;
                }
                else
                {
                    if (i==k+x-1)
                    {
                        
                        num2=0;
                        j++;
                        i=j-1;
                    }
                }
                i++;
            }
            x++;
            y2=0;
            if (num3<=num1)
            {
    
                y1=x-1;
                y4=y3;
                num3=num1;
                num2=0;
                num1=0;
            }
            else
            {
                num1=0;
                num2=0;
            }
            if (x==k)
            {
                break;
            }
    
        }
        cout<<"最大子数组为:"<<endl;
        for (int h=y1;h<y1+y4;h++)
        {
            cout<<arr2[h]<<" ";
        }
        cout<<endl;
        cout<<"最大子数组和为:"<<endl;
        cout<<num3<<endl;
    }

    5、运行结果:

     6、总结分析:

           在这次的题目中,我们并没有费很多的时间,当老师提出这个问题的时候,我就想到了将原数组长度增长一倍,并复制两遍,进行计算

       遇到的问题:开始没有想到,要控制计算求和的长度,以至于把同一个数计算了两遍。。。。终于想到,数组长度变了,但求和时长度要控制在原数组的一倍长度以内。

      项目计划日志(单位:h):

      听课 编写程序 阅读相关书籍 网上查找资料   日总计
    周一 2 0 1 0.5 3.5
    周二 0 1 0.5  0 1.5
    周三  0 2 0  0 2
    周四 2 1.5  0 1.5 5
    周五  0 2 0.5 0 2.5
    周六  0 3 0  0 3
    周日          
    周总计 4 9.5 2 2 17.5

                             时间记录日志(单位:min):

    日期 开始时间 结束时间 中断时间 净时间 活动 备注
    星期一 14:00 15:50 10(课间) 100 听课 软件工程上课
      19:30 21:30 30 90 阅读、上网查资料  
    星期二 19:30 21:30 30 90 编程、阅读  
    星期三 14:00  15:00 0  60 编程 数组最大子数组之和
      19:00 20:30 30 120 编程
    星期四 14:00 15:50 10(课间) 100 听课 软件工程上课
      16:20 17:30 0 70 编程、上网查资料 数组最大子数组之和2的程序
      19:30 21:00 30 60 编程 数组最大子数组之和2的程序
    星期五 14:00 17:00 60 120 编程 数组最大子数组之和2的程序
    星期六 8:00 11:30 30(洗漱) 180 修改,调试,发布 数组最大子数组之和程序进行修改、调试、写博客并发布

    队友地址:http://www.cnblogs.com/mengyinianhua/

  • 相关阅读:
    redis quick start
    Distributed processing
    DocFetcher 本机文件搜索工具
    ZeroTier One
    windows下搭建voip服务器
    在公司上wifi
    屏幕录制软件
    openresty vs golang vs nodejs
    DISC测试
    How to implement a windbg plugin
  • 原文地址:https://www.cnblogs.com/wangyw/p/5316319.html
Copyright © 2020-2023  润新知