文章目录
- P5015 [NOIP2018 普及组] 标题统计
- P5734 【深基6.例6】文字处理软件
P5015 [NOIP2018 普及组] 标题统计
NOIP2018 普及组] 标题统计 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
在怎么读取数据输入的问题上纠结了很久。
- 本来想用
cin>>x
的形式一个字符一个字符地读,但发现不知道什么时候停止读取。 - 改用
scanf("%s",&s)
,但发现不能读取中间有空格的字符串(会被认为是两个字符串)。 - 最终使用
cin.getline(str, len)
,直接读取一行。
通过代码
#include<iostream>
using namespace std;
int main()
{int count=0;//标题中的字符数int LEN=20;char s[LEN]={};cin.getline(s, LEN);for(int i=0;i<LEN;i++)if((s[i]!='\0')&&(s[i]!=' ')&&(s[i]!='\n'))count++;cout<<count;return 0;
}
P5734 【深基6.例6】文字处理软件
P5734 【深基6.例6】文字处理软件 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
在插入字符串部分反复出bug。
3 a str
:插入片段,在文档中第a个字符前面插入字符串str,并输出文档的字符串。
思路是先腾出空位然后,然后填进要插入的字符串没错。但我想要在一个循环中完成,腾一个就填一个。后来发现思路是混乱了的,需要移动的字符串与需要填入的字符串长度并不一致。
如原字符串为
abc
,操作为3 0 d
,我需要将三个字符各后移一位,但只需要填入一个字符d。
后来又遇到循环条件控制的问题,腾出空位时需要访问原字符串,我使用的代码如下。然而实际上随着字符串的后移,第一个\0
的位置其实是在变化的,已经不是原来的字符串结尾了。而且我居然忘记了我是使用了一个int e;
来指示字符串s
的尾部的。
for(int i=0;s[i]!='\0';i++)s[e-1-i+len]=s[e-1-i]; //腾出空位
我将这一行代码修改如下,就通过了洛谷的测试。可能细心的读者已经发现了问题,“你怎么把整个字符串都后移了?”没错,虽然我成功过了洛谷的测试,但实际上使用的是一段有bug的代码。
for(int i=0;i<e;i++)s[e-1-i+len]=s[e-1-i]; //腾出空位
这段含bug的完整代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
void show(char s[], int e)//打印字符串 --> right
{for(int i=0;i<e;i++)printf("%c",s[i]);printf("\n");
}
void insert_end(char s[], int& e)//1 后接插入
{char str[100]={};scanf("%s",str);for(int i=0;str[i]!='\0';i++)s[e++]=str[i];show(s,e);
}
void get_part(char s[], int& e)//2 截取文档部分
{int a,b;//截取从a起的b个字符cin>>a>>b;for(int i=0;i<b;i++)s[i]=s[a+i];e=b;show(s,e);
}
void insert_front(char s[], int& e)//3 插入片段
{int a;char str[100]={};int len=0; // 插入字符串str的长度cin>>a;scanf("%s",str);for(int i=0;str[i]!='\0';i++)len++; //得到str长度for(int i=0;i<e;i++)s[e-1-i+len]=s[e-1-i]; //腾出空位for(int i=0;i<len;i++)s[a+i]=str[i]; // 插入字符e=e+len;show(s,e);
}
void find(char s[], int& e)
{char str[100]={};scanf("%s",str);for(int i=0;i<e;i++){int flag=1;for(int j=0;str[j]!='\0';j++)if(s[j+i]!=str[j])flag=0;if(flag){cout<<i<<endl;return;}}cout<<-1<<endl;
}
int main()
{char s[1000]={};//文档字符串int e=0;//s最后一个字符的下一个char str[100]={};//临时字符串int q=0;//操作次数int op=0;//操作类型cin>>q;scanf("%s",str);//输入初始文档for(int i=0;str[i]!='\0';i++)s[e++]=str[i];for(int i=0;i<q;i++)//q次操作{cin>>op;if(op==1)insert_end(s,e);else if(op==2)get_part(s,e);else if(op==3)insert_front(s,e);else if(op==4)find(s,e);else cout<<"error"<<endl;}return 0;
}
它在下面的测试中就发生了错误:
1
abcde
3 4 TT
ababTTe
只需要将腾出空位的代码修改如下,即可排除该bug。
for(int i=0;i<e-a;i++)s[e-1-i+len]=s[e-1-i]; //腾出空位
1
abcde
3 4 TT
abcdTTe