C++ 求数值数组的绝对增大子数组的最大长度

这道题是网络中心某题。虽然简单但是有点点小心机,就是处理指针溢出的部分。
算法思想如下:
1 长度为n的数组要找到绝对增大的子数组要经过n-1次比较。
2 设置三个指针,一个记录子数组起始地址,一个记录终止地址,一个为比较数值的指针(总是在终止指针的下一个位置或者重合)
3 不断比较指针所指地址的值,若a[i]>=a[+1],则分是否为最后一次比较移动终止地址指针或者比较指针。不是最后一次,就三个都动;是最后一次,就三个都不动。
若a[i]<a[i+1],也分是否最后一次比较,若是,则移动终止指针,其他两个不动;若不是,则移动终止指针和比较指针。
4 用终止指针减去起始指针即子数组长度

分是否最后一次比较来移动指针,可以防止指针位置溢出
写算法加代码加不断调试竟然花了我快半小时QAQ,所以本代码可输入正整数、负整数。检测50组数内(自己可以改)数组的绝对增大子数组的长度。

#include<iostream>
#include<stdio.h>
using namespace std;

//找最大绝对连续增大的子数组的长度
int len=0;  //数组长度初始为0,全局变量
int sublen=0;//子数组长度
int findlen(int a[], int* p)
{   /*需要三个指针,一个指针为记录绝对增大子数组的起始位置,一个指针为进行数值比较,一个指针记录子数组的末尾位置
    长度为n的数组需要进行n-1次数值比较,同时最后一次比较需要特殊处理,否则指针会溢出存储区*/
    int *j=p; //子数组末尾指针初始指向头指针
    int *cmp=p+1; //比较指针初始位置为头结点的下一位
    for(int i=1;i<len;i++)    //只进行len-1次比较
    {
        if(*j>=*cmp)    //没有自增
           {
               if(i==(len-1))  //最后一次比较还是无自增,则指针都不动否则会溢出
               {}
               else         //不是最后一次则移动所有指针
               {
                   cmp+=1;
                   j+=1;
                   p+=1;
               }
           }
        else           //有自增
            {
                if(i==(len-1))  //若是最后一次比较
                {
                    j+=1;   //只移动末尾指针
                }
                else
                {
                    j+=1;  //移动末尾指针
                    cmp+=1; //移动比较指针
                }
            }

    }

            sublen=j-p;   //计算子数组长度
            if(sublen!=0)  sublen+=1;
            return 0;
}
int main()
{
    int str1[50]; //数组和普通的局部变量有区别
    int *p=str1;  //头结点指针
    char c;
    while(len<50)    //输入不超过50个数字
    {
        c=getchar();  //获取输入字符
        if((c>='0'&&c<='9')||c=='-')  //输入正整数、负整数
		{
			ungetc(c,stdin);
			cin>> str1[len++];
		}
		if(c=='\n')  break;   //换行则结束则结束输入
    }
    findlen(str1,p);
    cout<<"the length is:"<<sublen<<endl;
    return 0;
}

算法可能还有误差,但是大致思想应该没错。仅供参考。写到这里我发现确实有点问题,少考虑了情况,后面可能需要把所有增大子数组长度记录并选出最大。。。忘记考虑了。。。下次有时间写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值