计蒜客练题 普及T1 第二天

计蒜客练题 普及T1 第二天

T1112 加密的病历单

开始判断是大写字母还是小写字母时,因为用的是俩个if,结果在第一次转换以后再次进行判断,又转换了回来,没找到错误,进行调试后发现了错误所在,
以前一直觉得明明用多个if进行判断就行,else貌似没用,这题让我知道了,原来else的作用是防止多同一个地方多次进行改变,保证在修改以后不会触碰到其他的判断条件的范围。

#include<iostream>
#include<string.h>
using namespace std;
int main()
{
	char str[51];
	cin>>str;
	int len=strlen(str);
	for(int i=0;i<len;i++)
	{
		if(str[i]>='a'&&str[i]<='z')
		{
			str[i]-=32;//是a与A的ASCII中间相差的大小
		}
		else if(str[i]>='A'&&str[i]<='Z')
		{
			str[i]+=32;
		}
	}
	for(int i=0;i<len;i++)
	{
		if(str[i]>='x'&&str[i]<='z')//应该是a,b,c,所以减23
		{
			str[i]-=23;
		}
		else if(str[i]>='X'&&str[i]<='Z')
		{
			str[i]-=23;
		}
		else str[i]+=3;
		
	} 
	for(int i=len-1;i>=0;i--)
	{
		cout<<str[i];
	}
	return 0;
}

T1113 整理药名
感觉和上一个题差不多,自然得考虑不同的做法,要不然练题就没啥意义了,所以用了string字符串类型,感觉挺简单的

#include <iostream>
#include <string>
using namespace std;
int main() 
{
	int n;
	string str[100];
	cin>>n;
	for(int i=0;i<n;i++)
	cin>>str[i];
	for(int i=0;i<n;i++)
	{
		int len=str[i].length();
		if(str[i][0]>='a'&&str[i][0]<='z')
		str[i][0]-=32;
		for(int j=1;j<len;j++)
		{
			if(str[i][j]>='A'&&str[i][j]<='Z')
			str[i][j]+=32;
		}
	}
	for(int i=0;i<n;i++)
	cout<<str[i]<<endl;
	return 0;
}

T1114 忽略大小写的字符串比较
全部化成小写字母就行。。。
但这里有一个点,就是用正常的输入字符串是以空格为结尾的,以前我一直是用while(ch!=’\n’)来操作的,今晚因为一开始用了string类型,写到最后才发现了需要以回车为结束符,懒得修改,就上网查找相关资料,得知了使用
string str;
getline(cin,str);

也可以实现以回车为结尾,而且要方便的多,不需要经过那么多的判断。

如果用char str[101];
可以使用 cin.getline(str,100);
c语言的话gets(str);

#include <iostream>
#include<string>
using namespace std;
int main() 
{
	string str[2];
	getline(cin,str[0]);
	getline(cin,str[1]);

	int len1=str[0].length(),len2=str[1].length();
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<str[i].length();j++)
		{
			if(str[i][j]>='A'&&str[i][j]<='Z')
			str[i][j]+=32;
		}
	}
	for(int j=0;j<len1&&j<len2;j++)
	{
		if(str[0][j]==str[1][j])//相等,那么执行下一次循环
		continue;
		else if(str[0][j]>str[1][j])
		{
			cout<<'>';
			exit(0);//直接退出程序
		}
		else 
		{
			cout<<'<';
			exit(0);
		}
	}
	//说明判断到了其中一个字符串的末尾,那么字符串长度大的自然大
	if(len1>len2)
	cout<<'>';
	else if(len1<len2)
	cout<<'<';
	else cout<<'=';
	return 0;
}

T1115 字符串判等
看似和上一个题目相同,只有稍微一个变化就是空格应该抛弃,我这里由于是直接复制的上面一题,只做了一点改动,就是如果是空格,则earse()掉,但他有3个重载,第一次错在了用错了重载;第二次是由于忽视了每次earse之后指针就会自动后移一位,再加上for循环的自加,只要遇见空格就会自加两次,导致空格后面一个字符不会被处理。

erase( );//删除所有字符
erase( pos );//删除pos位置以后所有的字符
erase( pos,num );//删除pos位置以后的num个字符。
//pos是逻辑位置

#include <iostream>
#include<string>
using namespace std;
int main() 
{
	string str[2];
	getline(cin,str[0]);
	getline(cin,str[1]);

	
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<str[i].length();j++)
		{
			if(str[i][j]>='A'&&str[i][j]<='Z')
			str[i][j]+=32;
			if(str[i][j]==' ')
			{
				str[i].erase(j,1);
				j--;//修正位置
			}
			
		}
	}
		int len1=str[0].length(),len2=str[1].length();
	for(int j=0;j<len1&&j<len2;j++)
	{
		if(str[0][j]==str[1][j])
		continue;
		else 
		{
			cout<<"NO";
			exit(0);
		}
	}
	
	if(len1!=len2)
	cout<<"NO";
	else cout<<"YES";
	return 0;
}

T1116 验证子串

这个题主要是子串和子序列的区分
子串是连续字符串
子序列是有序的,但可以不连续的字符组成的字符串

因此子串一定长度小于等于母串

实际操作起来发现难道其实还是挺大的。
思路和上面一样,还是string字符串进行操作,为了简便,直接用swap函数把子串放到前面,因此只需要判断第一个是不是第二个的子串即可。
这里用了两个变量,flag用来标识此次判断之前的一次是不是相等,如果不是,说明在在找第一个相同的字符。q是用来保存第一个字符判断相等以后在母串中的下一个位置,以此来作为没有找到子串以后应该从这个位置开始重新比较第一个相等字符。

#include <iostream>
#include<string>
using namespace std;
int main() 
{
	int p=0,q=0,flag=0;//p用来标识应该从母串的哪一个位置开始判断
	string str[2];
	getline(cin,str[0]);
	getline(cin,str[1]);

	int len1=str[0].length(),len2=str[1].length();
	
	if(len1>len2)
	str[0].swap(str[1]);
	len1=str[0].length(),len2=str[1].length();
	for(int i=0;i<len1;i++)
	{
		for(int j=p;j<len2;j++)
		{
			if(str[0][i]!=str[1][j])
			{
				if(flag==0)
				continue;
				if(flag==1)
				{
					flag=0;
					i=-1;//从子串重新开始判断
					p=q;
					break;
				}
				
			}
			
			else 
			{
				if(i==len1-1)
				{
					cout<<str[0]<<" is substring of "<<str[1];
					exit(0);
				}
				else
				{
					if(flag==0)
					{
						flag=1;
						q=j+1;//保存下一个字符位置
						break;
					}
					else 
					{
						flag=1;
						p=j+1;//判断下一个字符
						break;
					}
					
				} 
			}
		
		}
		
	}
	cout<<"No substring";
	
	return 0;
}

经过一段时间学习,发现自己思路不够清晰,关于这个题目,新解法如下:

#include <iostream>
#include<string>
using namespace std;
int main() 
{
	string str[2];
	cin>>str[0]>>str[1];
	int len1=str[0].length(),len2=str[1].length();	
	if(len1>len2)
	{
		str[0].swap(str[1]);
		len1=str[0].length();
		len2=len2=str[1].length();
	}
	int i=0,j=0;
	while(1)
	{
		if(i==len2)
			break;
		if(str[0][j]==str[1][i])
		{
			i++;
			j++;
			if(j==len1)
			{
				cout<<str[0]<<" is substring of "<<str[1];
				exit(0);
			}
		}
		else
		{
			i=i-j+1;
			j=0;
		}	
	} 
	cout<<"No substring";
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值