@[TOC]
100000580 《算法笔记》3.6小节——入门模拟->字符串处理
来自 http://codeup.cn/contest.php?page=6
讲解
例题
Codeup 5901见习题
PAT B 1009 说反话 (20 分)
来自
https://pintia.cn/problem-sets/994805260223102976/problems/994805314941992960
题析:主要是输入时候用二维字符数组接收一行字符串,需要注意
PAT单点测试不需要用gets()
还有法二见:
https://blog.csdn.net/xsj_blog/article/details/51992540
//1009说反话
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char str[85][85];
int count=0;
while(scanf("%s",str[count]) != EOF)
{
count++;
}
for(int i=count-1;i>=0;i--)
{
printf("%s",str[i]);
if(i>0) printf(" ");//注意空格条件,最后一个但此后面没有空格,否则出错
}
printf("\n");
return 0;
}
/*
注意:在黑框中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾“,
因此需要用< Ctrl + Z >组合键,
然后按< Enter >键的方式来告诉系统已经到了 EOF,这样系统才会结束 while
*/
练习题:
1785 Problem A 字符串连接
来自 http://codeup.cn/contest.php?cid=100000580
//1785ProblemA字符串连接
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char str1[105];
char str2[105];
char str[315];
while(scanf("%s%s",str1, str2)!=EOF)
{
int len1=strlen(str1);
int len2=strlen(str2);
int count=0;
//略简洁
for(int i=0;i<len1+len2;i++)
{
if(i<len1)
str[i]=str1[i];
else
str[i]=str2[i-len1];
}
//略繁琐
/*
for(int i=0;i<len1;i++)
{
str[count++] = str1[i];
}
for(int j=0;j<len2;j++)
{
str[count++] = str2[j];
}
for(int k=0;k<count;k++)
{
printf("%c",str[k]);
}
*/
str[len1+len2]='\0';//字符串结尾需加结束符号,否则报错50%
printf("%s\n",str);
// printf("\n");
}
return 0;
}
1805 Problem B 首字母大写
来自 http://codeup.cn/contest.php?cid=100000580
题析:
通用解法,多点测试用一维字符数组,然后转存二位字符数组,用row/column行列指针来控制下标,相应改变字符串即可。
附大佬解法:
https://blog.csdn.net/qq_40073459/article/details/86559451
//1805ProblemB首字母大写
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char str[105];
while(gets(str) != NULL)
{
int lens = strlen(str);
char string[105][105]={};//若不初始化为空则会影响到下一组测试
int row=0,column=0;
for(int i=0;i<lens;i++)//str转移到二维字符数组string中
{
if(str[i] != ' '&&str[i]!='\t'&&str[i]!='\r'&&str[i]!='\n')
{
string[row][column++] = str[i];
}
else
{
string[row++][column]='\0';
column=0;
}
}
for(int i=0;i<=row;i++)
{
if(string[i][0]>='a' && string[i][0]<='z')
{
string[i][0] -= 32;//相差32
// string[i][0] = string[i][0]-'a'+'A'; //该语句导致错误50%,虽然不知道为啥
}
}
for(int i=0;i<=row;i++)
{
if(i<row)
printf("%s ",string[i]);
else
printf("%s",string[i]);
}
printf("\n");
// getchar();
}
return 0;
}
1808 Problem C 字符串的查找删除
来自 http://codeup.cn/contest.php?cid=100000580
题析:题目有些绕,注意:
Gets()的用法
母串子串比较过程的模拟(特别是指针的动态变化),详见注释
//1808ProblemC字符串的查找删除
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool compare(char a,char b)//将大小写相同的情况都包括进去的字符比较
{//简单粗暴的吧子串和母串的字符进行比较,而不必改变各自的值
if(a>='A'&&a<='Z')
{
a=a-'A'+'a';
}
if(b>='A'&&b<='Z')
{
b=b-'A'+'a';
}
if(a==b)
return 1;
else
return 0;
}
char substr[1005];//子串字符数组,注意申请足够大
char str[1005];
int main()
{
int i,j;
gets(substr);
int sublen = strlen(substr);
/*//转换为compare()函数更高效
for(i=0;i<sublen;i++)//待删除字符串一律变成小写,tolower
{
if(substr[i]>='A'&&substr[i]<='Z')
substr[i] = substr[i] - 'A' + 'a';
}
*/
while(gets(str) != NULL)//输入母字符串
{
int len = strlen(str);
//字符串比较
i=0;j=0;
while(i<sublen&&j<len)
{
if(compare(substr[i],str[j]))//若当前指针字符相等,则指针后移
{
i++;
j++;
//子串遍历完,说明母串中有一个匹配的,则除了移动指针,子串指针应重置
if(i==sublen)
i=0;
}
else//字符串不匹配,则打印母字符串不匹配部分,并且指针重新计数
{
j = j-i+1;//不匹配的话,母串指针跳过匹配段向后
if(str[j-1] != ' ')//打印前一项
printf("%c",str[j-1]);
i=0;//子串指针重置
}
}
if(j==len) //一行结束换行
printf("\n");
}
return 0;
}
1962 Problem D 单词替换
来自 http://codeup.cn/contest.php?cid=100000580
//1962ProblemD单词替换
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char s[1010];
char str[105][105];
char a[105],b[105];
while(gets(s) != NULL)
{
int lens,lena,lenb;
int i=0,j,row=0,column=0;
lens=strlen(s);
for(i=0;i<=lens;i++)//将输入母串转换为二维数组存储
{
if(s[i]!=' '||i==lens)
{
str[row][column++]=s[i];
}
if(s[i]==' ')
{
str[row++][column]='\0';
column=0;
}
}
// scanf("%s",a);
// scanf("%s",b);
gets(a);
gets(b);
for(i=0;i<=row;i++)
{
if(strcmp(str[i],a) == 0)//母串中匹配到子串a,用b替换
{
printf("%s",b);
// strcpy(str[i],b);
}
else
printf("%s",str[i]);
if(i<row)
printf(" ");
else
printf("\n");
}
}
getchar();
return 0;
}
1963 Problem E 字符串去特定字符
来自 http://codeup.cn/contest.php?cid=100000580
题析:见解析
//1963ProblemE字符串去特定字符
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char s[100005],c;
// while(scanf("%s %c",s,&c))//单点,不合题意
while(gets(s) != NULL)//多点测试
{
c=getchar();//输入 字符 两种方法均可
//scanf("%c",&c);
int len = strlen(s);
for(int i=0;i<len;i++)
{
if(s[i]!=c)//不匹配到删除字符则打印输出
printf("%c",s[i]);
}
printf("\n");
getchar();//不加getchar()出错%50,?? 大概影响下一次gets(),毕竟是换行符
}
return 0;
}
1967 Problem F 数组逆置
来自 http://codeup.cn/contest.php?cid=100000580
题析:真 水题
注意输入的字符串可能会有空格 get() gets() 与 scanf()区别
//1967ProblemF数组逆置
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char str[205];
while(gets(str) != NULL)//注意输入的字符串可能会有空格
{
int len = strlen(str);
for(int i=len-1;i>=0;i--)
{
printf("%c",str[i]);
}
printf("\n");
}
return 0;
}
2025 Problem G 比较字符串
来自 http://codeup.cn/contest.php?cid=100000580
题析:简单题,注意cstring头文件和strlen与char str[]的配合应用
//2025ProblemG比较字符串
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char str1[55],str2[55];
int len1,len2;
int m;
scanf("%d",&m);
while(m--)//多点测试
{
scanf("%s%s",str1,str2);
len1 = strlen(str1);
len2 = strlen(str2);
if(len1 == len2)
{
printf("%s is equal long to %s\n",str1,str2);
}
else if(len1>len2)
{
printf("%s is longer than %s\n",str1,str2);
}
else
printf("%s is shorter than %s\n",str1,str2);
}
return 0;
}
2064 Problem H 编排字符串
来自 http://codeup.cn/contest.php?cid=100000580
题析:
数组下标的处理比较繁琐,具体见注释
将字符串计数与输出指针分割开来,并将字符数4作为分界条件
//2064ProblemH编排字符串
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int m;
scanf("%d",&m);
char str[4][25];
int i,j,count=0;
while(m--)//多点测试
{
scanf("%s",str[count%4]);//输入字符串并存入数组,多出4个则覆盖
i=count;//i用来控制输出下标
if(count<4)//字符串少于4个时,上限用count表示
{
for(j=1;j<=count+1;j++)
{
printf("%d=%s",j,str[i--]);
if(j==count+1)
printf("\n");
else
printf(" ");
}
}
else//字符串多于4个时,上限不用count表示
{
for(j=1;j<5;j++)
{
printf("%d=%s",j,str[(i--)%4]);//注意取余
if(j==4)
printf("\n");
else
printf(" ");
}
}
count++;//输入字符串计数
}
return 0;
}
5901 Problem I 【字符串】回文串
来自 http://codeup.cn/contest.php?cid=100000580
题析:很简单,两头往中间跑,但是scanf()输入时输出超限什么鬼??已解决觉,没加!=EOF,具体机制还是不清楚???
scanf 和 gets 读取字符串
来自 http://www.cnblogs.com/qinjunni/archive/2012/03/03/2378323.html
//5901ProblemI【字符串】回文串
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool Judge(char str[])
{
int len = strlen(str);
for(int i=0;i<len/2;i++)
{
if(str[i]==str[len-i-1])
{
continue;
}
else
return 0;
}
return 1;
}
int main()
{
char str[260];
//while(scanf("%s",str))//输出超限????
//while(gets(str))
while(scanf("%s",str)!=EOF)//已解决觉,没加!=EOF,具体机制还是不清楚???
{
if(Judge(str))
{
printf("YES\n");
}
else
printf("NO\n");
// printf("\n");
}
return 0;
}