最大子数组和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/

posted @ 2016-03-26 15:47  David~Wang  阅读(217)  评论(1编辑  收藏  举报