一.C风格的字符串
1.
char a[6] = { 'h','e','l','l','o','\0' };
printf("%s", a);//hello
#include
#include
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";//error
int 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);//hello
printf("%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
cout<<strcmp(b, a);//o>e,,结果大于0,输出:1
char 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;//oogle
cout << b - a;//1
}
8.输入
int main() {
char a[10];
scanf("%s", &a);//hello
printf("%s", a);//hello
cout << a;//hello
}
二.C++的string类
1.输出
.c_str()
#include
#include
using namespace std;
int main() {
char a[] = "hello";
string b = "hello";
printf("%s", a);//hello
printf("%s", b);//乱码
printf("%s", b.c_str());//hello
cout << b;//hello
}
2.拼接
确保字符串连接时等号两侧都要有string
to_string()将数字常量转换为字符串
#include
#include
using namespace std;
int main() {
string a;
//a = "qw" + 'w';
//printf("%s", a.c_str());//乱码
//确保字符串连接时等号两侧都要有string
a = 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
#include
using namespace std;
int main() {
string a;
scanf("%s", &a);//error
//可使用其他多种方式完成输入,例如
a.resize(10);
scanf("%s", &a[0]);//hello
printf("%s", a.c_str());//hello
printf("%d", a.size());//10
}
4.复制,互不影响
#include
#include
using namespace std;
int main() {
string a;
string b;
a = "hello";
b = a;
a = "jack";
cout << a;//jack
cout << 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
#include
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) + ')';
}
else
s = to_string(a);
return s;
}
if (abs(a) < abs(b)) {
if (a < 0) {
s = "(" + to_string(a) + '/' + to_string(b) + ')';
}
else
s = to_string(a) + '/' + to_string(b);
}
if (abs(a) == abs(b)) {
if (a < 0) {
s = '(-1)';
}
else
s = '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) + ')';
}
else
s = 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());
}
else
printf("%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
二月: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
#include //reverse头
using namespace std;
bool panduan(string a) {
string b = a;
reverse(b.begin(), b.end());
if (b == a)
return true;
else
return 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";
else
a[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;
else
cout << "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
#include
using namespace std;
int change(char x) {
if (x >= '0' && x <= '9')
return x - 48;
else
return 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;
}
else
jinwei = 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
#include
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);//获取一行数据,存入s
int 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);
}