环状一维数组

结对伙伴:郭婷 朱慧敏

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.总结

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

 

转载于:https://www.cnblogs.com/gting/p/4430302.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
#include <stdio.h> //头文件 #include <string.h> #define _CRT_SECURE_NO_WARNINGS #define YES 1 #define NO 0 //全局变量部分 char V[20]; //病毒DNA字符串 char D[20]; //人的DNA字符串 //主要功能函数的具体实现及说明 //模式匹配函数(BF) int BF(char *D, char *V) { //用BF算法进行模式匹配 int i=0,j=0; while (i<strlen(D) && j<strlen(V)) { if (D[i]==V[j]) { i++; j++; }else{ i = i-j+1; j = 0; } } if (j>=strlen(V)) { return YES; }else { return NO; } } //循环展开函数(BFjudge) int BFjudge(char *D, char *V) { int flag = 0; int i,j,m; char temp[20]; m = strlen(V); for(i=m,j=0;j<m;j++) V[i++]=V[j]; V[2*m] = '\0'; //将字符串长度为m的病毒DNA扩展为长度为2m的字符串 for(i=0; ;i++) { for(j=0;j<m;j++) temp[j] = V[i+j]; temp[m] = '\0'; //循环展开环状病毒DNA flag = BF(D,temp); //调用BF模块进行模式匹配 if (flag) break; else if (i>=m) return NO; //所有展开字符串均匹配失败 else continue; } return YES; } // 程序使用一维数组存储,在输入完一组数据后存储在缓存区内, // 然后将判断结果存入数组s中,最后根据数组s统一输出判断结果。 int PRINThand() { int i=0,k=0; int s[20]; while(1) { printf("\n请输入病毒DNA以0结束:"); scanf("%c", &V[i]); printf("\n请输入人的DNA以0结束:\n"); scanf("%c", &D[i]); if(V[i]=='0' && D[i]=='0') break; if(BFjudge(D, V)==1) { s[k]=1; }else{ s[k]=0; } k++; i++; } printf("病毒感染检测输出结果:\n"); for(k=0;s[k]<2;k++) { if(s[k]==1){ printf("YES\n"); }else{ printf("NO\n"); } } return 0; } //主函数 int main() { int key = 0, Num; while(1) { printf("欢迎使用病毒感染检测系统\n"); PRINThand(); printf("是否继续(1表示是,0表示否):"); scanf("%d", &key); if (key == 0) { break; } } }\
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值