《算法笔记》胡凡——3.6字符串处理

做题列表

在这里插入图片描述

1006 换个格式输出整数 (15分)

在这里插入图片描述
水题:因为n<1000,即最多有三位数,个,十,百位分别表示出来,再按要求输出。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int b,s,g;
	b=n/100;
	s=(n%100)/10;
	g=n%10;
	for(int i=0;i<b;i++)
	{
		cout<<"B";
	}
	for(int i=0;i<s;i++)
	{
		cout<<"S";
	}
	for(int i=1;i<=g;i++)
	{
		cout<<i;
	}
	cout<<endl;
	return 0;
}

1021 个位数统计 (15分)

在这里插入图片描述
把0-9出现的次数用count数组记录,用字符数组存储输入数字,字符在计算机中以ASCLL码形式存储,要把它转换为数字,做-'0’处理即可。

这里gets(a)时,显示编译错误,但是换为cin>>a时,运行正确。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	char a[1010];
	int count[10]={0};
	cin>>a;
	int len=strlen(a);
	for(int i=0;i<len;i++)
	{
		count[a[i]-'0']++;
	}
	for(int i=0;i<10;i++)
	{
		if(count[i]!=0)
		{
			cout<<i<<":"<<count[i]<<endl;
		}
	}
	return 0;
}

1031 查验身份证 (15分)

在这里插入图片描述
把权值和检验码以数组形式存储,好对应。
如果最后一位得出的结果(前17位与相应的权重相乘,结果对11求余)与校验码中的数都不同,则该身份证不对。

#include <bits/stdc++.h>
using namespace std;
char m[11]={'1','0','X','9','8','7','6','5','4','3','2'};
int q[18]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
int main()
{
	int n;
	cin>>n;
	bool flag=true;
	char a[19];
	while(n--)
	{
		cin>>a;
		int sum=0;
		for(int i=0;i<17;i++)
		{
			sum+=(a[i]-'0')*q[i];
		}
		sum=sum%11;
		int b=m[sum];
		if(b!=a[17])
		{
			flag=false;
			for(int i=0;i<18;i++)
			{
				cout<<a[i];
			}
			cout<<endl;
		}
	}
	if(flag==true) cout<<"All passed"<<endl;
	return 0;
}

1002 写出这个数 (20分)

在这里插入图片描述
定义一个字符类型的二维数组,存储0-9对应的拼音,这里里边的拼音必须是用双引号引起来,我用单引号引起来时出错。害我在找逻辑错-_-。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	char str[110];
	char a[10][5]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	cin>>str;
	int len = strlen(str);
	int sum=0;
	int ans[10];
	for(int i=0;i<len;i++)
	{
		sum+=(str[i]-'0');
	}
	int j=0;
	while(sum!=0)
	{
		ans[j]=sum%10;
		j++;
		sum/=10;
	}
	for(int k=j-1;k>=0;k--)
	{
		printf("%s",a[ans[k]]);
		if(k!=0) cout<<" ";
		else cout<<endl;
	}
	return 0;
}

1009 说反话 (20分)

在这里插入图片描述
这里找到了pat不能编译通过gets()函数的解决办法,用cin.get()代替,也能读取空格。这里注意定义字符数组的初值,输入的是90个字符,必须对字符串进行初始化。
定义一个二维字符数组,用h表示单词个数,用l表示单词里边的字母个数。遇到空格后,单词个数加一,进行新单词的存储,单词个数变为0。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	char str[90]=" ";
	cin.get(str,90);
	int h=0,l=0;
	char ans[90][90];
	for(int i=0;i<90;i++)
	{
		if(str[i]!= ' ')
		{
			ans[h][l++]=str[i];
		}
		else 
		{
			ans[h][l]='\0';
			h++;
			l=0;	
		}
	}
	for(int i=h;i>=0;i--)
	{
		cout<<ans[i];
		if(i>0) cout<<" ";
	}
	return 0;
}

1014 福尔摩斯的约会 (20分)

在这里插入图片描述
注意:在寻找第二对相同的字符时,是在第一对相同的后边寻找。

#include <bits/stdc++.h>
using namespace std;
char week[8][5]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
int main()
{
	char a[60],b[60],c[60],d[60];
	cin>>a>>b>>c>>d;
	int x1,x2,x3,x4;
	x1=strlen(a);
	x2=strlen(b);
	x3=strlen(c);
	x4=strlen(d);
	int i;
	for(i=0;i<x1&& i<x2;i++)
	{
		if(a[i]==b[i] && a[i]>='A' && a[i]<='G')
		{
			cout<<week[a[i]-'A']<<" ";
			break;
		}
	}
	for(i=i+1;i<x1&&i<x2;i++)
	{
		if(a[i]==b[i])
		{
			if(a[i]>='0' && a[i] <='9')
			{
				printf("%02d:",a[i]-'0');
				break;
			}
			else if(a[i]>='A' && a[i]<='N')
			{
				printf("%02d:",a[i]-'A'+10);
				break;
			}
		}
	}
	for(i=0;i<x3&&i<x4;i++)
	{
		if(c[i]==d[i])
		{
			if((c[i]>='A' && d[i]<='Z')||(c[i]>='a' && d[i]<='z'))
			{
				printf("%02d",i);
				break;
			}
		}
	}
	return 0;
}

1024 科学计数法 (20分)

在这里插入图片描述
主要是定位E的位置,和E后边的数字大小exp与 小数点和E之间的数字相比。

  • exp为负数则在输入字符串前边加零,个数与exp相同,包括小数点前的0;
  • exp为正数,分两种情况:
    (1)是exp小于小数点到E之间字符的个数,比如3.1415926E+05,exp=5,小数点到E之间的个数为7,则小数点往后移5位,即在exp+2(+2是因为3.)的地方输出小数点(字符数组下标从0开始)。
    注意: 当exp=pos-3时,不需要输出小数点。即小数点移到最后一位,可以省略。
    (2)是exp大于小数点到E之间字符的个数,则需输出exp-(pos-3)个0。pos-3是小数点后到E之间的字符个数。
#include <bits/stdc++.h>
using namespace std;
int main()
{
	char str[10010];
	cin>>str;
	int len=strlen(str);
	int pos=0,exp=0;
	while(str[pos]!='E')//定位E的位置
	{
		pos++;
	}
	if(str[0]=='-')//输入为负数,先输出负号
	{
		cout<<"-";
	}
	for(int i=pos+2;i<len;i++)//E后指数的数
	{
		exp=exp*10+str[i]-'0';
	}
	if(str[pos+1]=='-')//指数为负数
	{
		cout<<"0.";
		for(int i=0;i<exp-1;i++)//需要输出的0的个数
		{
			cout<<"0";
		}
		for(int i=1;i<pos;i++)//原字符串中的数,除去小数点,从一开始是因为有正负号
		{
			if(str[i]=='.') continue;
			cout<<str[i];
		}
	}
	else //指数为正数
	{
		for(int i=1;i<pos;i++)
		{
			if(str[i]=='.') continue;
			cout<<str[i];  //先输出原有字符,除去小数点。
			if(i==exp+2 && pos-3!=exp)  //确定小数点输出位置
			{
				cout<<".";
			}
		}
		for(int i=0;i<exp-(pos-3);i++)//多余0的个数
		{
			cout<<"0";
		}
	}
	return 0;
}

1048 数字加密 (20分)

在这里插入图片描述

  • 要求个位数为第一位,所以对于输入的字符先反转,最后的结果也许要反转。
  • 注意当两个数字的长度不一样时,短的字符串要补零
  • 在判断奇数偶数时,i是从1开始的,注意和数组下标的对应
  • 注意字符与数字之间的转换
#include <bits/stdc++.h>
using namespace std;
int main()
{
	string a,b;
	char ans[101];
	cin>>a>>b;
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());
	int len1=a.length();
	int len2=b.length();
	int len;
	if(len1>len2) b+=string(len1-len2,'0');
	else a+=string(len2-len1,'0');
	len=a.length();
	for(int i=1;i<=len;i++)
	{
		if(i%2==0)
		{
			int k=b[i-1]-a[i-1];
		    if(k<0) ans[i-1]=k+10+'0';
		    else ans[i-1]=k+'0';
		}
		else 
		{
			int j=(a[i-1]+b[i-1]-'0'-'0')%13;
		    if(j==10) ans[i-1]='J';
		    else if(j==11) ans[i-1]='Q';
		    else if(j==12) ans[i-1]='K';
		    else ans[i-1]=j+'0';
		}
	}
	
	for(int i=len-1;i>=0;i--)
	{
		cout<<ans[i];
	}
	cout<<endl;
	return 0;
}

1001 A+B Format (20分)

在这里插入图片描述
先算出a+b之和sum,如果sum是负数,先输出负号,再把sum的每一位存储在数组中,每三位输出一个逗号,最后一组不输出。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int a,b;
	cin>>a>>b;
	int sum;
	sum=a+b;
	if(sum < 0) 
	{
		cout<<"-";
		sum = -sum;
	}
	int c[30];
	int i=0;
	if(sum==0) c[i++]=0;
	while(sum!=0)
	{
		c[i++]=sum%10;
		sum/=10;
	}
	for(int j=i-1;j>=0;j--)
	{
		cout<<c[j];
		if(j%3==0 && j>0) cout<<",";
	}
	return 0;
}

1005 Spell It Right (20分)

在这里插入图片描述
对输入的字符的每一位相加,其和的每一位用英语表示。
注意sum为零的情况。

#include <bits/stdc++.h>
using namespace std;
char b[10][7]={"zero","one","two","three","four","five","six","seven","eight","nine"};
int main()
{
	char a[10001];
	cin>>a;
	int len=strlen(a);
	int sum=0;
	for(int i=0;i<len;i++)
	{
		sum+=(a[i]-'0');
	}
	int c[10001],k=0;
	if(sum==0) cout<<b[0]<<endl;
	else 
	{
		while(sum!=0)
		{
			c[k++]=sum%10;
			sum/=10;
		}
		for(int j=k-1;j>=0;j--)
		{
			cout<<b[c[j]];
			if(j>0) cout<<" ";	
		}
		cout<<endl;
	}
	return 0;
}

1035 Password (20分)

在这里插入图片描述
注意当没有要修改的情况,输出单词的单复数。
定义一个结构体,对于输入的每一个密码进行判断,若需要修改则modify为true,修改的个数加一,否则为false,最后遍历整个输入数组,modify为true的输出。

#include <bits/stdc++.h>
using namespace std;

struct node
{
	char name[11];
	char password[11];
	bool modify;
}T[1001];

void change(node& t, int& count1)
{
	int len=strlen(t.password);
	for(int i=0;i<len;i++)
	{
		if(t.password[i]=='1')
		{
			t.password[i]='@';
			t.modify=true;
		}
		else if(t.password[i]=='0')
		{
			t.password[i]='%';
			t.modify=true;
		}
		else if(t.password[i]=='l')
		{
			t.password[i]='L';
			t.modify=true;
		}
		else if(t.password[i]=='O')
		{
			t.password[i]='o';
			t.modify=true;
		}
	}
	if(t.modify) count1++;
}
int main()
{
	int n,count=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>T[i].name>>T[i].password;
		T[i].modify=false;
    }
    for(int i=0;i<n;i++)
    {
    	change(T[i],count);
    }
    if(count==0)
    {
    	if(n==1) 
    	{
    		cout<<"There is 1 account and no account is modified"<<endl;
    	}
    	else cout<<"There are "<<n<<" accounts and no account is modified"<<endl;
    }
    else 
    {
    	cout<<count<<endl;
    	for(int i=0;i<n;i++)
    	{
    		if(T[i].modify)
    		{
    			cout<<T[i].name<<" "<<T[i].password<<endl;
    		}
    	}
    }
	return 0;
}

1077 Kuchiguse (20分)

在这里插入图片描述
用getchar接收输入n后的回车。用getline接收输入,可以接收空格。
求字符串的最长相等后缀,可以把字符串翻转,从前到后对比。
输入字符的最短字符作为循环长度,逐个对比前面的字符,直到有不等的为止,退出循环。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	string s[256];
	int n,minLen=256,ans=0;
	cin>>n;
	getchar();
	for(int i=0;i<n;i++)
	{
		getline(cin,s[i]);
		int len=s[i].size();
		if(len<minLen) minLen=len;
		reverse(s[i].begin(),s[i].end());
	}
	for(int i=0;i<minLen;i++)
	{
		char c=s[0][i]; //从第一个字符开始逐个对比
		bool same=true;
		for(int j=1;j<n;j++)
		{
			if(c!=s[j][i])//j表示输入的第几个字符串,i表示字符串中的第i个字符
			{
				same=false;
				break;
			}
		}
		if(same) ans++;
		else break;
	}
	if(ans!=0)
	{
		for(int k=ans-1;k>=0;k--)//后缀,所以要把反转后的字符串再反转输出
		{
			cout<<s[0][k];
		}
		cout<<endl;
	}
	else cout<<"nai"<<endl;
	return 0;
}

1082 Read Number in Chinese (25分)

在这里插入图片描述
千百十个,四个为一组,然后再一组后边加 亿或者万。

定义一个布尔变量isZero表示当前位是否为0,为0则设为true,一个布尔变量isPrint表示一组中是否有输出过,若至少有一位输出了,就设为true,比如1000,0000,1000。中间“万组”没有输出过任何一位,全是0,所以在之后的输出中会以isPrint为条件判断是否会输出万或者亿。

注意空格的输出。

定义left和right表示字符串最左边和最右边,让right左移4位进行分组,每组内进行输出,输出完一组后,再输出万或者亿。

#include <bits/stdc++.h>
using namespace std;
char num[10][5]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
char wei[5][5]={"Shi","Bai","Qian","Wan","Yi"};
int main()
{
	char str[15];
	cin>>str;
	int len=strlen(str);
	int left=0,right=len-1;
	if(str[0]=='-')
	{
		cout<<"Fu";
		left++;
	}
	while(left+4<=right)//把right移到最左边的一组
	{
		right-=4;
	}
	while(left<len)
	{
		bool isZero=false;
		bool isPrint=false;
		while(left<=right) //每组组内进行输出
		{
			if(left>0 && str[left]=='0') isZero=true; //当前位为0
			else  //当前位不为0
			{
				if(isZero==true) //判断在当前位的数字前有没有0,有则输出ling
				{
					cout<<" ling";
					isZero=false;
				}
				if(left>0) cout<<" ";  //只要不是首位,就输出空格
				cout<<num[str[left]-'0'];//输出当前位
				isPrint=true; //只要
				if(left!=right)//只要不是个位
				{
					cout<<" "<<wei[right-left-1]; //输出千百十
				}
		    }
		    left++;
		}
		if(isPrint==true && right!=len-1)//isPrint必须是true,才能输出万或者亿
		{
			cout<<" "<<wei[(len-1-right)/4+2];
		}
		right+=4;	
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值