zoukankan      html  css  js  c++  java
  • 环状一维数组

    结对伙伴:郭婷 朱慧敏

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

    要求:

    输入一个整形数组,数组里有正数也有负数。

    数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

    如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。

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

    求所有子数组的和的最大值。要求时间复杂度为O(n)。

    2.设计思路

    开始我们是想在原来程序的基础上将数组进行扩展,对于一个n的一维数组,如果成环可以将数组长度扩展为2*n-1的。

    3.源代码

    #include<iostream>
    #include<cmath>
    using namespace std;
    #define N 1000
    #define max(a,b)(a>b?a:b)
    
    int MaxSum_base(int arr[], int n)
    {
        int i, sum = 0;
        int max = arr[0];
        for (i = 0; i<n; i++)
        {
            if (sum <= 0)
            {
                sum = arr[i];
            }
            else
            {
                sum = sum + arr[i];
            }
            if (sum>max)
            {
                max = sum;
            }
        }
        return max;
    
    }
    
    int MaxSum_linked(int arr[], int n)
    {
        int c = arr[0];
        int ans = c;
        bool h = false;
        for (int i = 1; i < n * 2 - 1; i++)
        {
            if (i < n&&arr[i] < 0)
                h = true;
            c = max(c + arr[i%n], arr[i%n]);
            ans = max(ans, c);
            if (i == n - 1 && !h)
                return ans;
        }
        return ans;
    }
    
    void MaxSum_location(int * arr, int n, int & start,int &end)
    {
        int maxSum = -N;
        int sum = 0;
        int cstart = start = 0;  //cstart记录每次当前起始位置 
        for (int i = 0; i < n; ++i)
        {
            if (sum < 0)
            {
                sum = arr[i];
                cstart = i;     // 记录当前的起始位置
            }
            else
            {
                sum += arr[i];
            }
            if (sum > maxSum)
            {
                maxSum = sum;
                start = cstart; // 记录并更新最大子数组起始位置
                end = i;
            }
        }
    }
    
    
    int main()
    {
        int i=0, n, a[100],s,e;
        cout << "输入数组个数:";
        cin >> n;
        cout << "请输入数组:";
        for (i = 0; i < n; i++)
        {
           cin >> a[i];
        }
        int x = MaxSum_base(a, n);
        cout << ">>线性最大子数组的和为:" << x << endl;
        int sum = MaxSum_linked(a, n);
        cout << ">>环形最大子数组的和为:" <<sum<< endl;
        MaxSum_location(a,n,s,e);
        cout << "最大子数组的位置是:" <<""<< s+1<<"个到第"<< e << "" <<endl;
    
    }

    4.程序截图

    5.总结

    在程序实现后,我们以为完成了,可是后来发现有些结果不对。有些数组成环后子数组的长度会超过数组本身的长度,这就不对了,于是我们有进一步修改了程序。这次的程序我们发现原来程序本身也会隐藏一些错误,需要我们对每一种情况进行分析,解决。

  • 相关阅读:
    《做衣服:破坏时尚》总结
    《程序员的思维修炼》总结
    纸玫瑰和鲜玫瑰,选择哪个?
    《古怪的身体:时尚是什么》总结
    《世界尽头的咖啡馆》总结
    《软技能:代码之外的生存指南》总结
    构造无限级树的框架套路,附上python/golang/php/js实现
    《Dior的时尚笔记》总结
    《编写可读代码的艺术》总结
    《费曼学习法》总结
  • 原文地址:https://www.cnblogs.com/gting/p/4430302.html
Copyright © 2011-2022 走看看