P5015 [NOIP2018 普及组] 标题统计
在怎么读取数据输入的问题上纠结了很久。
- 本来想用
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】文字处理软件
在插入字符串部分反复出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