C++程序设计基础:字符串知识点(一)

题目一: ISBN号码(匹配)

1. 题目说明

1.1 题目描述

每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如x-xxx-xxxxx-x,其中符号-就是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符-之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9再求和,即0×1+6×2+……+2×9=158,然后取158mod11的结果4作为识别码。
你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出Right;如果错误,则输出你认为是正确的ISBN号码。

1.2 输入输出

输入格式
一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。
输出格式
一行,假如输入的ISBN号码的识别码正确,那么输出Right,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符-)。
输入输出样例

输入 #1
0-670-82162-4

输出 #1
Right

输入 #2
0-670-82162-0

输出 #2
0-670-82162-4

2. 代码与解答

2.1 注意点

1、用字符串进行直接对比,省去换算成数字的过程。
2、头文件#include <stdio.h>,使用gets、puts操作char字符串。

2.2 题解

#include <iostream>
#include <stdio.h>
using namespace std;
int main() 
{
	char str[14],num[12]="0123456789X";//定义字符串
	gets(str);
	int  sum = 0;
	for(int i=0,k=1;i<12;i++)
	{
		if(str[i]=='-') continue;
		sum += (str[i]-'0') * k++;//采用字符ASCII码相减计算数值
	}
	if(num[sum%11]==str[12]) cout<<"Right";
	else 
	{
		str[12] = num[sum%11];
		puts(str);
	}
	return 0;
}

题目二:统计单词数(转换大小写)

1. 题目说明

1.1 题目描述

一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1 ),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2 )。

1.2 输入输出

输入格式
共2行。
第1行为一个字符串,其中只含字母,表示给定单词;
第2行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从0 开始);如果单词在文章中没有出现,则直接输出一个整数-1。
输入输出样例

扫描二维码关注公众号,回复: 9208991 查看本文章

输入 #1
To
to be or not to be is a question

输出 #1
2 0

输入 #2
to
Did the Ottoman Empire lose its power at that time

输出 #2
-1

1.3 说明

数据范围
1≤单词长度≤10。
1≤文章长度≤1,000,000。

2. 代码与解答

2.1注意点

警告!千万注意输入的顺序!千万注意输入的顺序!千万注意输入的顺序!

2.2解答代码

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string sent,word;
	int count=0,pos=0,lenword,lensent;
	//用string库,调用getline, 直接读入一整行,用法如下:getline(cin,变量名) 
	getline(cin,word);
	getline(cin,sent);
	lenword=word.size();   
    lensent=sent.size();
	for(int i=0;i<lensent;i++)
	{
        sent[i]=tolower(sent[i]);//toupper、tolower函数,字符全部转化为大/小写 
    }
    for(int j=0;j<lenword;j++)
	{
        word[j]=tolower(word[j]);
    }
    for(int i=0;i<=lensent-lenword;i++)
    {
    	int j;
    	for(j=0; j<lenword; j++)
    	{
    		if(sent[i+j]!=word[j]) break;
    		if(i>0&&sent[i-1]!=' ') break;
    	}
    	if(j==lenword&&(sent[j+i]==' '||j+i==lensent)) 
        {
            count++;
            if(count==1) pos=i;
        }
    }
    if(count==0) cout<<-1;
    else cout<<count<<" "<<pos;
    return 0;
} 


★题目三:数字反转(重点)※

1. 题目说明

1.1 题目描述

给定一个数,请将该数各个位上数字反转得到一个新数。
这次与NOIp2011普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为0(除非小数部分除了0没有别的数,那么只保留1个0);分数不约分,分子和分母都不是小数(约分滴童鞋抱歉了,不能过哦。输入数据保证分母不为0),本次没有负数。

1.2 输入输出

输入格式
一个数s
输出格式
一个数,即s的反转数
输入输出样例

输入 #1
5087462

输出 #1
2647805

输入 #2
600.084

输出 #2
6.48

输入 #3
700/27

输出 #3
7/72

输入 #4
8670%

输出 #4
768%

1.3 说明

所有数据:25%s是整数,不大于20位
25%s是小数,整数部分和小数部分均不大于10位
25%s是分数,分子和分母均不大于10位
25%s是百分数,分子不大于19位

2. 代码与解答

2.1注意点

重点,题目比较复杂,考虑的很多,细节很多
万能头文件:#include<bits/stdc++.h>
1、注意只去掉最边缘处的0
2、注意处理小数部分前后的零,比如:612.054;
3、同时要注意,小数部分最后有零时,保留一位0,比如6.000;
4、输入为0时,输出还为0

2.2解答代码

//解题思路:先把数字的符号抽取出来,然后“对症下药”,再分类操作前先把第一个数字输出;输出符号;再输出第二个数字。重点在于对去除零部分的细节,如分析所说。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    char p=0;//用来放符号
    int cnt=0;
    cin>>s;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]>='0'&&s[i]<='9') cnt++;//记录第一个数长度;循环后,cnt即为符号的位置 
        else    //遇到符号,记录,跳出
        {
            p=s[i];
            break;
        } 
    }
    int max = s.size()-1;//整个数的最后一位 
    int cnt2 = cnt;
    cnt--;//此使cnt表示第一个数的最后一位 
    while(s[cnt]=='0'&&cnt>0)
    	cnt--;//去除多余前导0;
    for(int i=cnt;i>=0;i--)
    	cout<<s[i];//输出第一个数 
    switch(p)//用switch根据标点符号进行分类,对符号后的数字进行判断操作 
    {
    	case 0:
    		break;
    	case '.':
		case '/':
			cout<<p;
			while(s[cnt2+1]=='0'&&cnt2+1<max)
			    cnt2++;//去除多余前导0;
			while(s[max]=='0'&&cnt2+1<max)
			    max--;//去除多余前导0;
    		for(int i=max;i>cnt2;i--)
    		{
    			cout<<s[i];
    		}
    		break;
    	case '%':
    		cout<<p;
    		break;
    }
    return 0; 
}

题目四:垂直柱状图(*画图)

1. 题目说明

1.1 题目描述

写一个程序从输入文件中去读取四行大写字母(全都是大写的,每行不超过100个字符),然后用柱状图输出每个字符在输入文件中出现的次数。严格地按照输出样例来安排你的输出格式。

1.2 输入输出

输入格式
四行字符,由大写字母组成,每行不超过100个字符
输出格式
由若干行组成,前几行由空格和星号组成,最后一行则是由空格和字母组成的。在任何一行末尾不要打印不需要的多余空格。不要打印任何空行。
输入输出样例

输入 #1
THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG.
THIS IS AN EXAMPLE TO TEST FOR YOUR
HISTOGRAM PROGRAM.
HELLO!

输出 #1
在这里插入图片描述

2. 代码与解答

2.1解答代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string a,b,c,d;
    int cnt[27]={},x1,x2,x3,x4,max=0;
    getline(cin,a);
    getline(cin,b);
    getline(cin,c);
    getline(cin,d);
    //用四次循环,统计次数
    for(int i=0;i<a.size();i++)
    {
    	x1 = a[i]-'A'+1;
    	cnt[x1]++;
    }
    for(int i=0;i<b.size();i++)
    {
    	int x2 = b[i]-'A'+1;
    	cnt[x2]++;
    }
    for(int i=0;i<c.size();i++)
    {
    	int x3 = c[i]-'A'+1;
    	cnt[x3]++;
    }
    for(int i=0;i<d.size();i++)
    {
    	int x4 = d[i]-'A'+1;
    	cnt[x4]++;
    }
    for(int i=0;i<26;i++)//计算最大次数值
	{
		max = max>cnt[i] ? max:cnt[i];
	}
    for(int i=max;i>0;i--)//倒序画图
    {
    	for(int j=1;j<=26;j++)
    	{
    		if(cnt[j]>=i)
			{
				cout<<"* ";
			}
			else cout<<"  ";
    	}
    	cout<<endl;
    }
    for(int i=0;i<26;i++)
    {
    	cout<<char('A'+i);
    	if(i<25) cout<<' ';
    }
    return 0; 
}

题目五:“蒟蒻”小书童——密码

1. 题目说明

1.1 题目描述

蒟蒻忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串(由不超过 50 个小写字母组成)中每个字母向后移动 nn 位形成的。z 的下一个字母是 a,如此循环。他现在找到了移动前的原文字符串及 nn,请你求出密码。

1.2 输入输出

输入格式
第一行:n。第二行:未移动前的一串字母
输出格式
一行,是此蒟蒻的密码
输入输出样例

输入 #1
1
qwe

输出 #1
rxf

1.3 注意点

字符串长度<=50

2. 代码与解答

2.1解答代码

#include <iostream>
using namespace std;
int main()
{
    string fir,sec;
    string fal = "abcdefghijklmnopqrstuvwxyz";
    int n;
    cin>>n;
	cin>>fir;
	for(int i=0;i<fir.size();i++)
	{
		int a = int((fir[i]-'a'+n)%26);//直接运算位置,取模找到
		sec[i] = fal[a];
		cout<<sec[i];
	}
    return 0; 
}
发布了27 篇原创文章 · 获赞 6 · 访问量 539

猜你喜欢

转载自blog.csdn.net/qq_43246110/article/details/104170964
今日推荐