上回我们的课后作业留了两道习题(详见爆笑详解c++中的string类型(一))
我们来先看看第一道题qwq(但愿你们是做了的)
课后作业第一题:
题目描述
给定一个字符串以及一串数,你可以将数列中所有相同的数改为任意一个字母,问能否将数列改变成给定的字符串。
我们先看代码:
#include <bits/stdc++.h>
using namespace std;
int t;
int main(){
cin>>t;
while(t--){
int n;
cin>>n;
int *a=new int[n];//1
for(int i=0;i<n;i++){
cin>>a[i];
}
string b;
cin>>b;
bool flag=1;//2
for (int i=0;i<n-1;i++){
for (int j=i+1;j<n;j++){
if(a[i]==a[j] && b[i]!=b[j]){//3
flag=0;
}
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<< endl;
}
}
这道题是在考察你对string
的基本运用
语法相对简单,除了几处我注释的地方,下面我会一一讲解
注释1
new
是一种用于申请空间的关键词,具体用法如下
变量类型 变量名(不指定大小)=new 变量类型(大小)
光看这一大堆估计也理解不了
下面我们来举几个例子:
比方说,你想要申请一个int
类型的数组m
,大小为N
一般你写的代码是这样:
int m[N];
是不是十分的简单快捷?
可是在正规大型的比赛中,这并非是官方所推荐的方式
官方偏要搞死你
官方所推荐的是new
所以刚才的代码要写成这样:
int *m=new int [N];
别告诉我你还没有看懂
注释2
也没啥可说的,这也是一种编程习惯
正常来讲这里是用int
可是经历过蓝桥杯的都知道
在main()
中写int
不赋值的话会默认赋为一个随机数(老泪纵横 )
所以个人建议如果只有两种状态还是用bool
保险
注释3
最重要的一条语法
意为数字串中任意两个相等且字符串中的这两个不相等
便说明不能将数字串不能转化成字符串
课后作业第二题:
你现在有一个由 n 个字符组成的字符数组 a
现在请你将他们分成正好两组(正好指每一个元素在且仅在一个组内)
使得 ∣sum1∣−∣sum2∣ 的值尽可能大,请你求出这个最大值。
这道题几乎不需要字符串的参与
代码甚至简单的不能再简单:
#include<iostream>
#include<cmath>
using namespace std;
#define long long long
long a[114514];
int main(){
long n;long m;
cin>>n;
while(n--){
cin>>m;
long cnt=0;
for(int i=0;i<m;i++){
cin>>a[i];
cnt+=a[i];
}
cout<<abs(cnt)<<endl;
}
}
看明白了吗?就是找规律
自己写点样例打打表就知道了
OK,开始进入正题
今天俺们又来整点string
的关键词
>=,==,<=,>,<
字符串是可以用字典序来比较的,注意是字典序!!!
我们可以这样写:
string str1="abc";
string str2="abc";
if(str1==str2) cout<<1<<endl;//会输出
str1="abcd";
if(str1<str2) cout<<1<<endl;//不会输出
str1="a1";
str2="b1";
if(str1>str2) cout<<1<<endl;//会输出
3.begin()
这是一个指针,指向字符串开头的地址
一般用于某些特定关键字
string str1="123";
int k=str1.begin();
4.end()
这是一个指针,指向字符串末尾的地址(和begin()
对应)
一般用于某些特定关键字
string str1="123";
int k=str1.begin();
5.erase(it1,it2)
删除[it1
,it2
)这个区间的元素必须用begin()
和end()
(注意是左闭右开)
注意这里的it1
,it2
必须用来表示
string s="abcefghij";指针
s.erase(s.begin()+3,s.begin()+6);//h是第六个位置,但是是开区间,不能删除
又是实践时间了
题目描述
给定一行句子,每个词之间用空格隔开,要么是全小写英文单词,要么是全大写英文单词,要么是自然数。
要求将这些单词倒序输出。而且对于每个单词,如果是小写词,应当转为大写;如果是大写词,应当转为小写;如果是自然数,应该倒转输出。
举一个例子:
we choose TO go 2 the 123 moon
程序应当输出:
MOON 321 THE 2 GO to CHOOSE WE
输入格式
仅一行,即需要反转的句子。
输出格式
仅一行,表示程序对句子的处理结果。
代码如下
#include<bits/stdc++.h>
using namespace std;
int n;
string s[1007];
int main() {
while(cin >> s[++n]); --n;
for(int i = n; i >= 1; i--) {
for(int j = 0; j < (int)s[i].size(); j++) {
if(s[i][j] >= 'a' && s[i][j] <= 'z') s[i][j] -= 'a' - 'A';
else if(s[i][j] >= 'A' && s[i][j] <= 'Z') s[i][j] -= 'A' - 'a';
}
if(s[i][0] >= '0' && s[i][0] <= '9')
for(int j = (int)s[i].size() - 1; j >= 0; j--) cout << s[i][j];
else cout << s[i];
if(i != 1) cout << " ";
}
}
这是标答,我们来分析一下
这道题运用了字符串的比较,ASCLL码值
其实也没有多大的水平含量
但是,注意
在作者在进行字符串的逆序输出时运用了十分巧妙的方法
while(cin >> s[++n]); --n;
非常的巧妙qwq
课后作业
第一题
题目描述
设某汉字由 N × N N \times N N×N 的 0 \texttt 0 0 和 1 \texttt 1 1 的点阵图案组成。
我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 0 \texttt 0 0,第二个数表示接下来连续有几个 1 \texttt 1 1,第三个数再接下来连续有几个 0 \texttt 0 0,第四个数接着连续几个 1 \texttt 1 1,以此类推……
例如: 以下汉字点阵图案:
0001000
0001000
0001111
0001000
0001000
0001000
1111111
对应的压缩码是: 7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 \texttt {7 3 1 6 1 6 4 3 1 6 1 6 1 3 7} 7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是 N N N ,其余各位表示交替表示0和1 的个数,压缩码保证 N × N = N \times N= N×N= 交替的各位数之和)
输入格式
数据输入一行,由空格隔开的若干个整数,表示压缩码。
其中,压缩码的第一个数字就是 N N N,表示这个点阵应当是 N × N N\times N N×N 的大小。
接下来的若干个数字,含义如题目描述所述。
输出格式
输出一个 N × N N\times N N×N 的 01 矩阵,表示最后的汉字点阵图(点阵符号之间不留空格)。
第二题
题目描述
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例 1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例 2)。
输入格式
共 2 2 2 行;
第 1 1 1 行为一个字符串,其中只含字母,表示给定单词;
第 2 2 2 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从 0 0 0 开始);如果单词在文章中没有出现,则直接输出一个整数 − 1 -1 −1。
注意:空格占一个字母位