一.C风格的字符串
1.
char a[6] = { 'h','e','l','l','o','\0' };
printf("%s", a);//hello
#include<iostream>
#include<string>
using namespace std;
int main() {char a[6] = { 'h','e','l','l','o','\0' };char b[5]= { 'h','e','l','l','o'};//空间至少大一位留出'\0'位置char c[6]= { 'h','e','l','l','o' };char d[] = "hello";char e[6] = "hello";char f[5] = "hello";//errorint lena = strlen(a);int lenb = strlen(b);int lenc = strlen(c);int lend = strlen(d);int lene = strlen(e);printf("%d,%d,%d,%d,%d", lena, lenb,lenc,lend,lene);//5,37,5,5,5
}
int main() {char a[] = "hello";printf("%s", a);//helloprintf("%c", a[1]);//e
}
4.strcpy复制
int main() {char a[] = "hello";char b[] = "jack";strcpy(a, b);//b复制给a,a变为jack,b不变printf("%s", a);//jack
}
5.strcat连接
int main() {char a[10] = "hello";//注意连接时a缓冲区会不会溢出,幷留出'/0'位置char b[] = "jack";strcat(a, b);//b连接到a末尾printf("%s", a);//hellojack
}
6.strcmp(s1,s2),s1大返回大于0,s1小返回小于0。逐个比较第一个不相等字符的ASCII码,全相等返回0
int main() {char a[] = "hello";char b[] = "hoogle";cout<<strcmp(a, b);//e<o,结果小于0,输出:-1cout<<strcmp(b, a);//o>e,,结果大于0,输出:1char c[] = "hello";cout << strcmp(a, c);//0
}
7.strchr(s,ch)在字符串s中查找ch,返回ch第一次出现及其后面的字符
也可以通过指针接收,与字符串的差值是ch在字符串s中第一次出现的数组下标
int main() {char a[] = "hoogle";char* b = strchr(a, 'o');cout << b;//ooglecout << b - a;//1
}
8.输入
int main() {char a[10];scanf("%s", &a);//helloprintf("%s", a);//hellocout << a;//hello
}
二.C++的string类
1.输出
.c_str()
#include<iostream>
#include<string>
using namespace std;
int main() {char a[] = "hello";string b = "hello";printf("%s", a);//helloprintf("%s", b);//乱码printf("%s", b.c_str());//hellocout << b;//hello
}
2.拼接
确保字符串连接时等号两侧都要有string
to_string()将数字常量转换为字符串
#include<iostream>
#include<string>
using namespace std;
int main() {string a;//a = "qw" + 'w';//printf("%s", a.c_str());//乱码//确保字符串连接时等号两侧都要有stringa = a + "qw" + 'w';printf("%s", a.c_str());//qww//to_string()将数字常量转换为字符串int b = 3;a = a + to_string(b);printf("%s", a.c_str());//qww3
}
3.输入,不能直接使用scanf
#include<iostream>
#include<string>
using namespace std;
int main() {string a;scanf("%s", &a);//error//可使用其他多种方式完成输入,例如a.resize(10);scanf("%s", &a[0]);//helloprintf("%s", a.c_str());//helloprintf("%d", a.size());//10
}
4.复制,互不影响
#include<iostream>
#include<string>
using namespace std;
int main() {string a;string b;a = "hello";b = a;a = "jack";cout << a;//jackcout << b;//hello
}
[练习1] 有理数四则运算
编写程序,计算2个有理数的和、差、积、商。
输入描述:输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。
输出描述:分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。
输入例子:
5/3 0/6
输出例子:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
代码长度限制 16 KB
时间限制 200 ms
内存限制 64 MB
[解]
#include<iostream>
#include<string>
using namespace std;
int gcd(int a, int b) {//求最大公因数return b == 0 ? a : gcd(b, a % b);
}
void simplify(int& a, int& b) {//分数化简if (b < 0) {//负号挪到分子上a = -a;b = -b;}int d = abs(gcd(a, b));a = a / d;b = b / d;
}
string f(int a, int b) {//转化成几又几分之几string s;simplify(a, b);if (a == 0 && b != 0) {s = '0';return s;}if (b == 1) {if (a < 0) {s = '(' + to_string(a) + ')';}elses = to_string(a);return s;}if (abs(a) < abs(b)) {if (a < 0) {s = "(" + to_string(a) + '/' + to_string(b) + ')';}elses = to_string(a) + '/' + to_string(b);}if (abs(a) == abs(b)) {if (a < 0) {s = '(-1)';}elses = '1';}if (abs(a) > abs(b)) {int k1 = abs(a / b);int k2 = abs(a % b);if (a < 0) {s = "(-" + to_string(k1) + ' ' + to_string(k2) + '/' + to_string(b) + ')';}elses = to_string(k1) + ' ' + to_string(k2) + '/' + to_string(b);}return s;
}
int main() {int a1, b1, a2, b2;scanf("%d/%d %d/%d", &a1, &b1, &a2, &b2);printf("%s + %s = %s\n", f(a1, b1).c_str(), f(a2, b2).c_str(), f(a1 * b2 + a2 * b1, b1 * b2).c_str());printf("%s - %s = %s\n", f(a1, b1).c_str(), f(a2, b2).c_str(), f(a1 * b2 - a2 * b1, b1 * b2).c_str());printf("%s * %s = %s\n", f(a1, b1).c_str(), f(a2, b2).c_str(), f(a1 * a2, b1 * b2).c_str());if (a2 == 0) {printf("%s / 0 = Inf\n", f(a1, b1).c_str());}elseprintf("%s / %s = %s\n", f(a1, b1).c_str(), f(a2, b2).c_str(), f(a1 * b2, a2 * b1).c_str());return 0;
}
[练习2]
央视新闻发了一条微博,指出 2020 年有个罕见的“对称日”,即 2020 年 2 月 2 日,按照 年年年年月月日日 格式组成的字符串 20200202 是完全对称的。
给定任意一个日期,本题就请你写程序判断一下,这是不是一个对称日?
输入格式:输入首先在第一行给出正整数 N(1<N≤10)。随后 N 行,每行给出一个日期,却是按英文习惯的格式:Month Day, Year。其中 Month 是月份的缩写,对应如下:
一月:Jan
二月:Feb
三月:Mar
四月:Apr
五月:May
六月:Jun
七月:Jul
八月:Aug
九月:Sep
十月:Oct
十一月:Nov
十二月:Dec
Day 是月份中的日期,为 [1, 31] 区间内的整数;Year 是年份,为 [1, 9999] 区间内的整数。
输出格式:对每一个给定的日期,在一行中先输出 Y 如果这是一个对称日,否则输出 N;随后空一格,输出日期对应的 年年年年月月日日 格式组成的字符串。
输入样例:
5
Feb 2, 2020
Mar 7, 2020
Oct 10, 101
Nov 21, 1211
Dec 29, 1229
输出样例:
Y 20200202
N 20200307
Y 01011010
Y 12111121
N 12291229
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
[解]
#include<iostream>
#include<algorithm> //reverse头
using namespace std;
bool panduan(string a) {string b = a;reverse(b.begin(), b.end());if (b == a)return true;elsereturn false;
}
struct pro {string year;string month;string day;
}a[15];
int main() {int n;cin >> n;for(int i=0;i<n;i++){cin >> a[i].month>> a[i].day>> a[i].year;if (a[i].month == "Jan")a[i].month = "01";else if (a[i].month == "Feb")a[i].month = "02";else if (a[i].month == "Mar")a[i].month = "03";else if (a[i].month == "Apr")a[i].month = "04";else if (a[i].month == "May")a[i].month = "05";else if (a[i].month == "Jun")a[i].month = "06";else if (a[i].month == "Jul")a[i].month = "07";else if (a[i].month == "Aug")a[i].month = "08";else if (a[i].month == "Sep")a[i].month = "09";else if (a[i].month == "Oct")a[i].month = "10";else if (a[i].month == "Nov")a[i].month = "11";elsea[i].month = "12";if (a[i].day.size() != 3)//还有个逗号a[i].day = '0' + a[i].day;if (a[i].year.size() == 3)a[i].year = '0' + a[i].year;if (a[i].year.size() == 2)a[i].year = "00" + a[i].year;if (a[i].year.size() == 1)a[i].year = "000" + a[i].year;}for (int i = 0; i < n; i++) {string temp = a[i].year + a[i].month + a[i].day[0] + a[i].day[1];if (panduan(temp))cout << "Y" << " " << temp << endl;elsecout << "N" << " " << temp << endl;}return 0;
}
[练习3] 钱串子的加法
人类习惯用 10 进制,可能因为大多数人类有 10 根手指头,可以用于计数。这个世界上有一种叫“钱串子”(学名“蚰蜒”)的生物,有 30 只细长的手/脚,在它们的世界里,数字应该是 30 进制的。本题就请你实现钱串子世界里的加法运算。
输入格式:
输入在一行中给出两个钱串子世界里的非负整数,其间以空格分隔。所谓“钱串子世界里的整数”是一个 30 进制的数字,其数字 0 到 9 跟人类世界的整数一致,数字 10 到 29 用小写英文字母 a 到 t 顺次表示。输入给出的两个整数都不超过 105 位。
输出格式:
在一行中输出两个整数的和。注意结果数字不得有前导零。
输入样例:
2g50ttaq 0st9hk381
输出样例:
11feik2ir
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
[解]
#include<iostream>
#include<algorithm>
using namespace std;
int change(char x) {if (x >= '0' && x <= '9')return x - 48;elsereturn x - 97 + 10;
}
int main() {string num1, num2, sum;string all = "0123456789abcdefghijklmnopqrst";int jinwei = 0;cin >> num1 >> num2;reverse(num1.begin(), num1.end());reverse(num2.begin(), num2.end());if (num1.length() < num2.length())//num1长swap(num1, num2);num2.append(num1.length() - num2.length(), '0');for (int i = 0; i < num1.length(); i++) {int n = change(num1[i]) + change(num2[i]) + jinwei;//sum = sum + all[n % 30];//超时sum += all[n % 30];//正常if (n >= 30) {jinwei = 1;}elsejinwei = 0;}if (jinwei == 1)cout << 1;//最后一个进位reverse(sum.begin(), sum.end());int i = 0;for (; i < sum.length(); i++) {if (sum[i] != '0') {break;}}if (i == sum.length()) {printf("0");//全为0}else {for (; i < sum.length(); i++) {cout << sum[i];}}return 0;
}
[练习4] ChatGPT
ChatGPT(全名:Chat Generative Pre-trained Transformer)近期成为网络讨论的热点话题之一。本题就请你根据某社交网络中发帖的情况,统计每个人帖子中含有 ChatGPT(不区分大小写)的数量(简称“含茶量”),找出最热衷于讨论这个话题的人,即含茶量最高的人。
输入格式:
输入在第一行中给出正整数:N(≤1000),为参加统计的帖子数量。
随后给出 N 条帖子的信息,每条格式为:第一行给出发帖人 ID,是一个长度为 4 位的非空数字串;第二行给出非空的帖子的内容,由不超过 140 个英文字母、数字、空格、标点(只包括 ?、, 和 .)组成,以回车结束(回车不算在 140 字内)。
输出格式:
在一行中输出含茶量最高的 ID,及其含茶量。数字间以 1 个空格分隔,行首尾不得有多余空格。
题目保证输出唯一。
输入样例:
4
1010
I am not interested in ChatGPT.
2333
I am gonna talk about chatgpt, and Chatgpt, and CHATGPT
2333
they are all ChatGPT
0002
So what are you talking about, chatPPT?
输出样例:
2333 4
代码长度限制 16 KB
Java (javac)
时间限制 600 ms
内存限制 256 MB
其他编译器
时间限制 400 ms
内存限制 64 MB
[解] (未在评测系统测试)
#include<iostream>
#include <string>
using namespace std;
int main() {int n;cin >> n;int count[100005]={0};for (int i = 0; i < n; i++) {int id;cin >> id;getchar();string s;getline(cin, s);//获取一行数据,存入sint len = s.length();for (int j = 0; j < len; j++) {s[j] = tolower(s[j]);//把字母字符转换成小写,非字母字符不做出处理}for (int j = 0; j < len-6; j++) {if (s[j] == 'c' && s[j + 1] == 'h' && s[j + 2] == 'a' && s[j + 3] == 't' && s[j + 4] == 'g' && s[j + 5] == 'p' && s[j + 6] == 't') {count[id]++;j = j + 6;}}}int max = -1;int maxpos=0;for (int i = 0; i < 10000; i++) {if (max <= count[i]) {max = count[i];maxpos = i;}}printf("%04d %d", maxpos, max);
}