NOI0107字符串最大跨距

NOI 0107 26:字符串最大跨距

这里是一个究极瓜皮,十个小时才做出来…
这里是题干@http://noi.openjudge.cn/ch0107/26/
一道很明显的模拟题,一般都只要按照题干的流程就AC了

最最开始的代码(WA)

#include<bits/stdc++.h>
using namespace std;
int main(){
    char a1[330],a[310],b[20],c[20],z[20];
    int temp,flag=0,s=0,t1,t2,t3,t;
    cin>>a1;
    temp=strlen(a1);
    for(int i=0;i<temp;i++){
        if(a1[i]!=','){
            if(flag==0){
                a[s]=a1[i];
                s++;
            }
            if(flag==1){
                b[s]=a1[i];
                s++;
            }
            if(flag==2){
                c[s]=a1[i];
                s++;
            }
        }
        else{
            flag++;
            s=0;
        }
    }
    if(strstr(a,b)!=NULL&&strstr(a,c)!=NULL){
        t=strlen(a);
        t1=strlen(strstr(a,b));
        t3=strlen(c);
        t2=strlen(strstr(a,c));
        for(int i=0;i<t2-t3;i++){
            z[i]=a[t+i-t2+2];
        }
        z[t2-t3]='\0';
        while(strstr(z,c)!=NULL){
            t2=strlen(strstr(z,c));
            for(int i=0;i<t2-t3;i++){
                z[i]=a[t+i-t2+2];
            }
            z[t2-t3]='\0';
        }
        cout<<t1-t2-t3;
    }
    else cout<<"-1";
    return 0;
}

然后在经过了很久很久之后找出来的问题:

1、strstr的找位置的用法

代码里是用了strstr和strlen通过strstr输出的是从第一个找到的字符到数组结尾的字符串,然后用strlen来判断。**但是!!**这个方式是错的(应该)(具体的错误原因还在找希望大佬解答)
然后是正确用法:
strstr()-数组参数
例子:

char a[100],b[10];
int n=strstr(a,b)-a;//在a当中寻找第一个b字符串并输出位置

strstr的返回值为指针,然后a也是一个指针并指向a[0],然后相减就可以得到在a中的位置了
千万要记住!输出的位置是a[]的位置,可能是0的那种
PS:strstr()在找不到的时候会返回NULL;

2、一个非常非常低级的读题失误

在题干中可以看到要求s1,s2不能交叉
看看上面那段代码,就可以发现没有编写关于这个要求的代码
这个没什么好说的,直接加进去就可以了

3、关于数组初始化的问题

很明显在这里没有对数组进行任何初始化操作,不过这题里没有问题
于是打算放到下一次里凑字数

——————————————————————————————————————————————

然后是改了好久的之后的代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
int main(){
    char a1[330],a[310],ad[310],b[20],c[20],c1[20];
    memset(a,0,sizeof(a));//将a[]全部赋值为0
    memset(ad,0,sizeof(ad));
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    int temp,flag=0,s=0,t1,t2,t3,t;
    gets(a1);
    temp=strlen(a1);
    for(int i=0;i<temp;i++){
        if(a1[i]!=','){
            if(flag==0){
                a[s]=a1[i];
                s++;
            }
            if(flag==1){
                b[s]=a1[i];
                s++;
            }
            if(flag==2){
                c[s]=a1[i];
                s++;
            }
        }
        else{
            if(flag==0)a[s]='\0';
            //将a数组的最后一个字符串之后加\0,也是strstr、strlen等函数的终止字符
            else if(flag==1)b[s]='\0';
            else if(flag==2)c[s]='\0';
            flag++;
            s=0;
        }
    }
    if(!strstr(a,b)||!strstr(a,c)){
        cout<<"-1"<<endl;
        return 0;
    }
    t=strlen(a);
    t1=strstr(a,b)-a;
    for(int i=0;i<t;i++){
            ad[i]=a[t-i-1];
    }
    ad[t]='\0';
    t3=strlen(c);
    for(int i=0;i<t3;i++){
            c1[i]=c[t3-i-1];
    }
    c1[t3]='\0';
    t2=strstr(ad,c1)-ad;
    if(t>=t1+t2+t3+strlen(b))cout<<t-t1-t2-t3-strlen(b)<<endl;
    else cout<<"-1"<<endl;
    return 0;
}

这一段代码就是上一段代码把前面的问题改掉,然后再加了一点点小小的变动

接着是找了一个大佬的代码

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char s[310],s1[20],s2[20],y[310],ss2[20];
int flag=0,l,r,len1,len2,res;
void f(){
    int len=strlen(s),k=0;
    for(int i=len-1;i>=0;i--){
        y[k++]=s[i];
    }
    y[k]='\0';
    len=strlen(s2),k=0;
    for(int i=len-1;i>=0;i--){
        ss2[k++]=s2[i];
    }
    ss2[k]='\0';
}
int main(){
    cin.getline(s,400,',');
    cin.getline(s1,20,',');
    cin.getline(s2,20);
    if(!strstr(s,s1)||!strstr(s,s2)){
        cout<<"-1"<<endl;
        return 0;
    }
    len1=strlen(s1);len2=strlen(s2);
    l=strstr(s,s1)-s;r=strstr(s,s2)-s;
    if(l+len1-1>=r){
        cout<<"-1"<<endl;
        return 0;
    }
    f();//把s翻转方便求s2最右边起始点
    r=strstr(y,ss2)-y;
    res=strlen(s)-l-len1-len2-r;
    cout<<res<<endl;
}

大佬和我不同的地方:

1、cin.getline

用cin会有一些的难受的地方,比如这题当中的要用,隔开两个输入量
就会变得很麻烦(具体多麻烦参考上面本菜鸡的代码)
但是!!这是一种全新的体验,只要三分钟你就能爱上这种感觉 cin.getline就可以完美解决这个问题
对于cin.getline的输入格式
cin.getline(保存的数组/参数,输入的个数,一个字符/数字/无)
PS:输入的个数最好为最大值,不然会出现一些因缺思厅的问题
当遇到这个字符/数字的时候cin.getline结束(不读入这个字符/数字并且在下次读入时也不会有这个字符/数字)当然无的话就可以当作一个cin(限制输入个数的)来用

2、函数

当在做一个模拟题的时候会发现自己会用到很多很多相同的代码或者把一坨放在main里面很难受
这时候运用函数就会舒服很多了(虽然在本质上没有区别,代码也不会变少)
同时这也可以更好地理解代码(只要在调用函数的地方来一个标注就ok了也不用上下翻看main)
PS:调用函数的时候会存在形参和实参的问题,解决的办法一种是指针,另一种就是这种粗暴的直接定义全局参数,这样在函数和main都可以使用了(指针…本着能不用就不用)

实在编不下去了并开始了结尾

emmmm第一次写博客,而且还是一个菜鸡,所以可能会存在各种学术问题或者逻辑表达问题
麻烦各位大佬多多指正,最后关注和谐,谋求发展 (来自于一个b站up主)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值