C++基础语法(中)
文章目录
- C++基础语法(中)
- 01数组
- 一维数组
- 数组初始化
- 注意
- 访问
- 练习1
- 练习2
- 练习3
- 普通做法:
- 优化
- reverse函数
- 练习4
- 多维数组
- 清空数组
- memset
- memcpy
- 数组的部分
- 由上到下,按规律
- 蛇形矩阵
- 技巧
- 02 字符串
- ASCLL码
- 字符数组
- 读入字符串
- 函数
- strlen
- strcmp
- strcpy
- 遍历
- 只出现一次的字符
- 替换字符
- 标准库类型 string
- 定义和初始化
- empty、size操作
- String的比较
- 处理string中的字符
- 练习
- streamstring
- 理解KMP的前提
01数组
程序 = 逻辑 + 数据
数组是存储数据的强而有力的手段
一维数组
#include<iostream>using namespace std;
int main()
{int a[100], b[100];float c[101];double d[11];char e[13];string g[100];return 0;
}
数组初始化
在函数内部,未初始化的数组中的元素是随机的
#include<iostream>
using namespace std;int main()
{int a[3] = {0,1,2};int b[5] = {1,2,3};//定义了一个长度为5的数组,没有给出的值,默认是0int c[121] = {0};//定义一个元素为0的数组return 0;
}
注意
如果函数内部要定义一个很长的数组一定要小心,可以直接在全局变量中去定义~
一旦定义全局,元素全部都是0
访问
数组下标一定从0开始
练习1
实现斐波那契数列
#include<iostream>
using namespace std;
int main()
{int f[100];f[0] = 0, f[1] = 1;int n;cin >> n;for(int i =2; i <= n; i++){f[i] = f[i - 1] + f[i - 2];}cout << f[n] << endl;return 0;
}
练习2
#include<iostream>using namespace std;
int main()
{int a[100];int n;cin >> n;for(int i = 0; i < n; i++) cin >> a[i];for(int i = n - 1; i >= 0; i--) cout << a[i] << ' ';cout << endl;return 0;
}
练习3
输入一个n,再输入n个整数。将这个数组顺时针旋转k(k<=n)次,最
后将结果输出。
普通做法:
#include<iostream>using namespace std;
int main()
{int a[100];int n, k;cin >> n >> k;for(int i = 0; i < n; i++) cin >> a[i];while(k--){int t = a[n - 1];for(int i = n - 2; i >= 0; i--)a[i + 1] = a[i];a[0] = t;}for(int i = 0; i < n; i++)cout >> a[i] >> ' ';return 0;
}
优化
- 翻转
a[]
- 翻转前半部分
- 翻转后半部分
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{int a[100];int n, k;cin >> n >> k;for(int i = 0; i < n; i++) cin >> a[i];reverse(a, a + n);reverse(a, a + k);reverse(a + k, a + n);for(int i = 0; i < n; i++)cout >> a[i] >> ' ';return 0;
}
reverse函数
reverse
函数通常用于反转容器(如数组、字符串、向量等)中的元素的顺序。它是C++标准库中的一个函数,可用于各种STL
容器和C++标准数组。reverse
函数的工作原理是将容器中的元素顺序颠倒,将第一个元素与最后一个元素互换,第二个元素与倒数第二个元素互换,以此类推,直到所有元素的顺序都被颠倒。
下面是一个使用reverse
函数的示例,演示如何反转一个整数数组:
#include <iostream>
#include <algorithm> // 包含reverse函数int main() {int arr[] = {1, 2, 3, 4, 5};int length = sizeof(arr) / sizeof(arr[0]);// 使用reverse函数反转整数数组std::reverse(arr, arr + length);// 输出反转后的数组for (int i = 0; i < length; i++) {std::cout << arr[i] << " ";}return 0;
}
在这个示例中,std::reverse
函数接受两个迭代器作为参数,这些迭代器定义了反转的范围。在这种情况下,我们反转了整个数组,所以第一个迭代器是arr
,第二个迭代器是arr + length
,其中length
是数组的长度。执行此操作后,数组中的元素顺序将被反转。
reverse
函数在C++中是一个强大的工具,可用于快速颠倒容器中元素的顺序,无论是数组还是其他STL
容器。它是C++标准库的一部分,因此无需手动实现反转操作。
练习4
计算2的n次方 n <= 10000
高精度运算
#include<iostream>using namespace std;
const int N = 10010;
int main()
{int a[N] = {1};int n;cin >> n;int m = 1; for(int i = 0; i < n; i++){int t = 0;for(int j = 0; j < m; j++){t += a[j] * 2;a[j] = t % 10;t /= 10;}if(t) a[m++] = 1;}for(int i = m; i >= 0; i--)cout << a[i];cout << endl;return 0;
}
多维数组
示例代码:
#include<iostream>
#include<cmath>using namespace std;
int main()
{int a[3][4];for(int i = 0; i < 3; i++){for(int j = 0; j < 4; j++)a[i][j] = i + j;}for(int i = 0; i < 3l; i++){for(int j = 0; j< 4; j++)cout << a[i][j] << ' ';cout << endl;}return 0;
}
清空数组
memset
#include<iostream>
#include<cmath>
#include<cstring>using namespace std;
int main()
{int a[10], b[10];memset(a, 0, 40);memset(b, 0, sizeoe b);for(int i = 0; i < 10; i++) cout << a[i] << ' ';for(int i = 0; i < 10; i++) cout << b[i] << ' ';return 0;
}
memcpy
#include<iostream>
#include<cmath>
#include<cstring>using namespace std;
int main()
{int a[10], b[10];for(int i = 0; i < 10; i++) a[i] = i;memcpy(b, a , sizeof a);for(int i = 0; i < 10; i++) b[i] = i;return 0;
}
数组的部分
745. 数组的右上半部分 - AcWing题库
由上到下,按规律
#include<bits/stdc++.h>using namespace std;
int main()
{double M[12][12];char c;cin >> c;for(int i = 0; i < 12; i++)for(int j = 0; j < 12; j++)cin >> M[i][j];double s = 0;int count = 0;for(int i = 0; i < 12; i++)for(int j = i + 1; j < 12; j++){count++;s += M[i][j];}printf("%.1lf\n",c == 'S' ? s : s / count); return 0;
}
747. 数组的左上半部分 - AcWing题库
#include<bits/stdc++.h>using namespace std;
int main()
{double a[12][12];char t;cin >> t;for(int i = 0; i < 12; i++)for(int j = 0; j < 12; j++)cin >> a[i][j];double s = 0;int c = 0;for(int i = 0; i < 12; i++)for(int j = 0; j <= 10 - i; j++){c ++;s += a[i][j];}printf("%.1lf", t == 'S' ? s : s / c );return 0;
}
749. 数组的上方区域 - AcWing题库
#include<bits/stdc++.h>using namespace std;
int main()
{double a[12][12];char t;cin >> t;for(int i = 0 ; i < 12 ; i ++)for(int j = 0; j < 12 ; j++)cin >> a[i][j];int c = 0;double s = 0;for(int i = 0; i < 5; i++)for(int j = i + 1; j <= 10 - i; j ++){c += 1;s += a[i][j];}printf("%.1lf\n", t == 'S' ? s : s / c);return 0;
}
751. 数组的左方区域 - AcWing题库
#include<bits/stdc++.h>using namespace std;
int main()
{double a[12][12];char t;cin >> t;for(int i = 0; i < 12; i++)for(int j = 0; j < 12; j++)cin >> a[i][j];int c = 0; double s = 0;for( int i = 1 ; i <= 5; i++)for(int j = 0 ; j <= i-1; j++){c++;s += a[i][j];}for(int i = 6; i <= 10; i++)for(int j = 0; j <= 10 - i; j++){c++;s += a[i][j];}printf("%.1lf\n", t == 'S' ? s : s / c);return 0;
}
753. 平方矩阵 I - AcWing题库
给(i,j)
个点,然后看其上下左右四条边距离的最小值~
#include<bits/stdc++.h>using namespace std;int main()
{int n; while(cin >> n,n){for(int i = 1; i <= n; i++){for(int j = 1 ; j <= n; j++){int up = i, down = n - i + 1, left = j, right = n - j + 1;cout << min(min(up,down),min(left,right)) << ' ';}cout << endl;}cout << endl;}return 0;
}
741. 斐波那契数列 - AcWing题库
这道题想提醒的主要就是关于long long
,还有他的输出方式是%lld
#include<bits/stdc++.h>using namespace std;
int main()
{long long f[61];f[0] = 0, f[1] = 1;for(int i = 2; i <= 60; i++) f[i] = f[i - 1] + f[i - 2];int n;cin >> n;while(n--){int x;cin >> x;printf("Fib(%d) = %lld\n", x, f[x]);}return 0;
}
754. 平方矩阵 II - AcWing题库
#include<bits/stdc++.h>using namespace std;int q[100][100];int main()
{int n; while(cin >> n, n){for(int i = 0; i < n ; i ++) {q[i][i] = 1;for(int j = i + 1, k = 2; j < n ; j++, k++) q[i][j] = k;for(int j = i + 1, k = 2; j < n ; j++, k++) q[j][i] = k;}for(int i = 0; i < n; i++){for(int j = 0; j < n ; j++) cout << q[i][j] << ' ';cout << endl;}cout << endl;}return 0;
}
蛇形矩阵
输入两个整数 n 和 m,输出一个 n 行 m 列的矩阵,将数字 11 到 n×m 按照回字蛇形填充至矩阵中。
具体矩阵形式可参考样例。
输入格式
输入共一行,包含两个整数 n 和 m。
输出格式
输出满足要求的矩阵。
矩阵占 n 行,每行包含 m 个空格隔开的整数。
数据范围
1≤n,m≤100
输入样例
3 3
输出样例
1 2 3
8 9 4
7 6 5
技巧
偏移量
#include <iostream>using namespace std;int res[100][100];int main()
{int n, m;cin >> n >> m;int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};for (int x = 0, y = 0, d = 0, k = 1; k <= n * m; k ++ ){res[x][y] = k;int a = x + dx[d], b = y + dy[d];if (a < 0 || a >= n || b < 0 || b >= m || res[a][b]){d = (d + 1) % 4;a = x + dx[d], b = y + dy[d];}x = a, y = b;}for (int i = 0; i < n; i ++ ){for (int j = 0; j < m; j ++ ) cout << res[i][j] << ' ';cout << endl;}return 0;
}
02 字符串
字符串是计算机和人类沟通的重要手段~
ASCLL码
字符串和整数的联系
每个常用字符都对应一个 -128~127的数字,两者之间做转化
#include<iostream>
using namespace std;int main()
{char c = 'a';cout << (int) c << endl;cout << (char) 97 << endl;for(int = i = 1; i < 128; i++) printf("&d: %c\n", i, char(i));
}
练习:输入一行字符,统计其中数字字符的个数,以及字母字符的个数
#include<iostream>
#include<cstdio>using namespace std;int main()
{char c;int nums = 0, chars = 0;while(cin >> c){if(c >= '0' && c <= '9') nums++;else if(c >= 'A' || c <= 'Z' || z >= 'a' || c >= 'z') chars++;}printf("nums : %d\n chars :%d\n", nums .chars);return 0;
}
常见ASCll值:‘A’~'Z’是 65~90,‘a’ ~ ‘z’是 97~122. 0~9 是48 ~ 57
字符数组
字符串就是字符数组加上结束符\0
可以使用字符串来初始化字符数组,但此时要注意,每个字符串会暗含一个\0
字符,因此字符数组的长度至少要比字符串长度多1
#include<iostream>using namespace std;int main()
{char a[] = {'c','+','+'}; //列表初始化,没有空字符char b[] = {'c','+','+','\0'}; //列表初始化,含有显示的空字符char c[] = "c++"; //自动添加表示字符串结尾的空字符char d[6] = "Daniel"; //会报错,没有空间可以存放空字符return 0;
}
读入字符串
#include<bits/stdc++.h>
using namesapce std;int main()
{char s[100];scanf("%s", s);//治理注意一下嗷,不用&return 0;
}
// 遇到空格、回车、结束符号就结束读入了
读入一行
#include<iostream>
#include<cstdio>using namespace std;
int main()
{cgar s[100];fgets(s, 100, stdin);// 原来的get函数已经被删除咯cout << s << endl;return 0;
}
函数
应该引入的头文件:#include<string.h>
strlen(str)
:求字符串长度strcmp(a, b)
比较两个字符串长度大小返回:-1、0、1strcpy(a, b)
将字符串b复制给从a开始i的数组
strlen
不包含\0
元素
#incldue<iosteam>
#inlcude<cstring>
#include<cstdio>using namespace std;
int main()
{char s[100];scanf("%s",s);cout << strlen(s) << endl;return 0;
}
#incldue<iosteam>
#inlcude<cstring>
#include<cstdio>
using namespace std;int main()
{char s1[100], s2[200];scanf("%s", s1);int len = 0;for(int i =0; s1[i]; i++) len ++;cout << len << endl;return 0;}
strcmp
#include<cstdio>
#include<cstring>
#include<iostream>using namespace std;
int main()
{char s1[100], s2[200];scanf("%s&s", s1, s2);cout << strcmp(s1, s2) << endl;return 0;}
strcpy
#include<cstdio>
#include<cstring>
#include<iostream>using namespace std;
int main()
{char s1[100], s2[200];scanf("%s&s", s1, s2);cout << strcmp(s1, s2) << endl;return 0;
}
遍历
省时~
#include<iosteam>
#include<cstring>
#include<cstdio>
using namespace std;int main()
{char s1[100], s2[200];scanf("%s", s1);for(int i =0, len = strlen(s1); i < len; i++) cout << s1[i] << endl;return 0;
}
只出现一次的字符
#include<bits/stdc++.h>
using namespace std;char str[100010];
int cnt[26];int main()
{cin >> str;for(int i = 0; i < strlen(str); i++) cnt[str[i] - 'a'] ++ ;for(int i = 0; i < strlen(str); i++)if(cnt[str[i] - 'a'] == 1){cout << str[i] << endl;return 0;}puts("no");return 0;
}
不过这样写是有点毛病
这个运行时间有点离谱
那我们改进一下代码看看
#include<bits/stdc++.h>
using namespace std;char str[100010];
int cnt[26];int main()
{cin >> str;for(int i = 0, len = strlen(str); i < len; i++) cnt[str[i] - 'a'] ++ ;for(int i = 0, len = strlen(str); i < len; i++)if(cnt[str[i] - 'a'] == 1){cout << str[i] << endl;return 0;}puts("no");return 0;
}
#include<bits/stdc++.h>
using namespace std;char str[100010];
int cnt[26];int main()
{cin >> str;for(int i = 0; str[i]; i++) cnt[str[i] - 'a'] ++ ;for(int i = 0; str[i]; i++)if(cnt[str[i] - 'a'] == 1){cout << str[i] << endl;return 0;}puts("no");return 0;
}
替换字符
#include<bits/stdc++.h>using namespace std;int main()
{char str[31];scanf("%s", str);char c;scanf("\n%c", &c);for(int i = 0; str[i]; i++){if(str[i] == c)str[i] = '#';}puts(str);return 0;
}
标准库类型 string
可变长的字符序列,比字符数组更好用,需要头文件#include<string>
定义和初始化
//string的初始化
#include<cstdio>
#include<cstring>
#include<iostream>using namespace std;int main()
{string s1;// 默认的空字符串string s2 = s1; // s2 是 s1 的一个副本string s3 = "ikun"; // s3 是该字符串的字面值的一个副本string s4(10, 'c'); // s4 的内容是 ccccccccccreturn 0;
}
不可以用
scanf("%s", &s);
去读入,会报错哦~
但是输出可以使用printf
printf("%s\n", s.c_str());
empty、size操作
size
是无符号整数,因此s.size()<=-1
一定成立
#include<cstdio>
#include<cstring>
#include<iostream>using namespace std;int main()
{string s1, s2 = "abc";cout << s1.empty() << endl; // 1cout << s2.empty() << endl; // 0 cout << s2.size() << endl; // 3return 0;
}
这里强调的是:s.size()
它的时间复杂度是O(1)
同时,s.length() s.size()
是等价的
String的比较
和正常的数字比较一样的,还支持相加,就是将两个字符串拼到一块去
- 做加法运算时,字面值和字符都会被转化成string对象,因此直接相加就是将这些字面值串联起来
- 当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string
#include<cstdio>
#include<cstring>
#include<iostream>using namespace std;int main()
{string s1, s2, s3, s4, s5, s6, s7;s1 = "hello", s2 = "world";s3 = s1 + " " + s2 + "!";cout << s3 << endl;cout << endl;s4 = s1 + " "; // 正确:把一个 string 对象 和一个有字面值的相加s5 = "hello" + " ";// 错误,这里编译器也报错了,两个对象都不是 strings6 = s1 + " " + "world";s7 = "hello" + " " + s2;// 错误,不能把字面值直接相加,运算是从左到右进行的return 0;
}
处理string中的字符
-
第一种处理方式
#include<cstdio> #include<cstring> #include<iostream>using namespace std;int main() {string s = "Hello World";for (int i = 0; i < s.size(); i++){cout << s[i] << endl;}return 0; }
-
第二种处理方式
#include<cstdio> #include<cstring> #include<iostream>using namespace std;int main() {string s = "Hello World";for (char c : s) cout << c << endl;return 0; }
-
练习
-
密码翻译,输入一个只包含小写字母的字符串,将其中的每个字母替换成它的后继字母,如果是z,则替换为a
#include<bits/stdc++.h>using namespace std;int main() {string s;getline(cin, s);for(auto &c : s)if(c >= 'a' && c <= 'z') c = (c - 'a' + 1) % 26 + 'a';else if(c >= 'A' && c <= 'Z') c= (c - 'A' + 1) % 26 + 'A';cout << s << endl;return 0; }
-
求字符串长度
#include<bits/stdc++.h>using namespace std;int main() {char str[101];fgets(str, 101, stdin);int len = 0; for(int i = 0; str[i] && str[i] != '\n'; i++) len ++;cout << len << endl;return 0; }
fgets函数及其用法
-
石头剪刀布
这里把
Hunter、Bear、Gun
当作是石头剪刀布~#include<iostream> #include<cstdio>using namespace std;int main() {int n;cin >> n;while(n--){string a, b;cin >> a >> b;int x, y;if(a == "Hunter") x = 0;else if(a == "Bear") x = 1;else x = 2;if(b == "Hunter") y = 0;else if(b == "Bear") y = 1;else y = 2;if(x == y) puts("Tie");else if(x == (y + 1) % 3) puts("Player1");else puts("Player2");}return 0; }
这道题的妙处就是在于另外定义了
x y
用数字去代替字符串 -
字符串加空格
#include<iostream>using namespace std;int main() {string a;getline(cin, a);string b;for(auto c: a) b = b + c + ' ';b.pop_back(); //把最后一个空格字符删掉cout << b << endl;return 0; }
-
字符串插入
介绍一下substr
substr
是 C++ 标准库中的一个字符串处理函数,用于获取原字符串中的子字符串。它通常被用于std::string
类型的字符串对象中,但也可以用于 C 风格的字符串(字符数组)。substr
的一般形式是:string substr(size_t pos, size_t len) const;
pos
:要提取的子字符串的起始位置(索引),从 0 开始计数。len
:要提取的子字符串的长度。
这个函数会返回一个包含原始字符串中指定子字符串的副本。
例如:
#include <iostream> #include <string>int main() {std::string str = "Hello, World!";std::string sub = str.substr(7, 5); // 从索引 7 开始,提取长度为 5 的子字符串std::cout << sub << std::endl; // 输出 "World"return 0; }
在这个示例中,
str.substr(7, 5)
从字符串 “Hello, World!” 中提取了从索引 7 开始的 5 个字符,结果是 “World”。
-
#include<bits/stdc++.h>using namespace std;int main()
{string a, b;while(cin >> a >> b){int p = 0;for(int i = 1; i <= a.size(); i++)if(a[i] > a[p]) p = i;cout << a.substr(0, p + 1) + b + a.substr(p + 1) << endl;}return 0;
}
- 忽略大小写比较字符串大小
#include<bits/stdc++.h>using namespace std;int main()
{char a[100], b[100];fgets(a, 100, stdin);fgets(b, 100, stdin);if(a[strlen(a) - 1] == '\n') a[strlen(a) - 1] = 0;//去掉末尾回车if(b[strlen(b) - 1] == '\n') b[strlen(b) - 1] = 0;for(int i = 0; a[i]; i++)if(a[i] >= 'A' && a[i] <= 'Z')a[i] += 32;for(int i = 0; b[i]; i++)if(b[i] >= 'A' && b[i] <= 'Z')b[i] += 32;int t = strcmp(a, b);if(t == 0) puts("=");else if(t < 0) puts("<");else puts(">");return 0;
}
去掉多余的空格
cin做法
//利用cin的特性不会读入空格
#include<bits/stdc++.h>
using namespace std;int main()
{string s;while(cin >> s){cout << s << ' ';}return 0;
}
双指针做法
#include<bits/stdc++.h>
using namespace std;int main()
{string s;getline(cin, s);string r;for(int i = 0; i < s.size(); i++)if(s[i] != ' ') r += s[i];else{r += ' ';int j = i;while(j < s.size() && s[j] ==' ') j++;i = j - 1;}cout << r << endl;return 0;
}
判断局部性
#include<bits/stdc++.h>using namespace std;int main()
{string s;getline(cin, s);string r;for(int i = 0; i < s.size(); i++){if(s[i] != ' ') r += s[i];else{if(!i || s[i-1] != ' ') r += ' '; }}cout << r << endl;return 0;
}
-
764. 输出字符串
#include<bits/stdc++.h>using namespace std;int main() {string a, b;getline(cin, a);for(int i = 0 ; i < a.size(); i++) b += (char)(a[i] + a[(i + 1) % a.size()]);cout << b << endl;return 0; }
a[(i + 1) % a.size()]
是一个取模运算的操作,它确保在i
达到字符串末尾时循环回到字符串的开头。i + 1
是下一个字符的索引,而% a.size()
会返回i + 1
除以字符串a
的长度后的余数,这确保了索引始终在字符串的有效范围内。- -
770. 单词替换
#include<bits/stdc++.h> #include<sstream> using namespace std;int main() {string s, a, b;getline(cin, s);cin >> a >> b;stringstream ssin(s);string str;while(ssin >> str)if(str == a) cout << b << ' ';else cout << str << ' ';return 0; }
streamstring
关于streamstring
:
#include<iostream>
#include<sstream>using namespace std;int main()
{string s;getline(cin ,s);stringstream ssin(s);int a, b;string str;double c;ssin >> a >> str >> b >> c;cout << a << endl << str << endl << b << endl << c << endl;return 0;
}
sscanf函数使用详解
sscanf
是 C/C++ 标准库函数之一,用于从一个字符串中按照指定的格式解析数据并将其存储到指定的变量中。它的基本格式如下:int sscanf(const char *str, const char *format, ...);
str
:要解析的输入字符串。format
:定义了解析格式的字符串。这个格式字符串可以包含普通字符和格式指示符,格式指示符以百分号%
开始。...
:可变数量的参数,用于接收从字符串中解析的数据。这些参数应该与format
字符串中的格式指示符匹配。
sscanf
函数会按照format
字符串中的格式指示符,从输入字符串str
中提取相应类型的数据,并将这些数据存储到参数中。通常,你需要确保提供的参数类型与format
字符串中的格式指示符匹配,以便正确解析和存储数据。以下是一个示例,演示如何使用
sscanf
函数从字符串中解析整数和浮点数:#include <stdio.h>int main() {char input[] = "42 3.14159";int intValue;double doubleValue;sscanf(input, "%d %lf", &intValue, &doubleValue);printf("Integer: %d\n", intValue);printf("Double: %lf\n", doubleValue);return 0; }
在这个示例中,我们使用
sscanf
函数从字符串 “42 3.14159” 中解析一个整数和一个双精度浮点数,并将它们存储到intValue
和doubleValue
变量中。格式字符串"%d %lf"
包含两个格式指示符,分别对应整数和双精度浮点数。注意,我们使用&
运算符获取变量的地址,以便sscanf
函数能够将数据正确存储到这些变量中。
#include<cstdio>
#include<iostream>
#include<sstream>using namespace std;int main()
{char s[1000];fgets(s, 1000, stdin);int a , b;char str[1000];double c;sscanf(s, "%d%s%d%lf", &a, str, &b, &c);printf("%d\n%s\n%d\n%lf", a ,str , b , c);return 0;
}
sscanf
也是可以有一样的效果哦~
但是推荐stringstream
~
771. 字符串中最长的连续出现的字符
#include<bits/stdc++.h>using namespace std;int main()
{int n ;cin >> n;while(n--){string str; cin >> str;int cnt = 0;char c; for(int i = 0 ; i < str.size(); i++){int j = i;while(j < str.size() && str[j] == str[i]) j++;if(j - i > cnt) cnt = j - i, c = str[i];i = j - 1;}cout << c << ' ' << cnt << endl;}return 0;
}
774. 最长单词
#include<bits/stdc++.h>using namespace std;int main()
{string res, str;while(cin >> str){if(str.back() == '.') str.pop_back();if(str.size() > res.size()) res = str;}cout << res << endl;return 0;
}
775. 倒排单词
法一:
#include<bits/stdc++.h>using namespace std;int main()
{string a, b;while(cin >> a) b = a + ' ' + b;cout << b;return 0;
}
法二:
定义一个字符串数组,然后把字符串读入,接着倒着输出出来即可~
#include<bits/stdc++.h>using namespace std;int main()
{string str[100];int n = 0;while(cin >> str[n]) n ++;for(int i = n - 1 ; i >= 0; i--) cout << str[i] << ' ';cout << endl;return 0;
}
字符串移位包含问题
理解KMP的前提
#include<bits/stdc++.h>
using namespace std;int main()
{string a, b;cin >> a >> b;if(a.size() < b.size()) swap(a, b);for(int i = 0; i < a.size(); i++){a = a.substr(1) + a[0];for(int j = 0; j + b.size() <= a.size(); j++){int k = 0;for(; k < b.size(); k++)if(a[j + k] != b[k])break;if(k == b.size()) {puts("true");return 0;}}}puts("false");return 0;
}
777. 字符串乘方 - AcWing题库
#include<bits/stdc++.h>using namespace std;int main()
{string str;while(cin >> str, str !="."){int len = str.size();for(int n = len; n; n--){if(len % n == 0){int m = len / n;string s = str.substr(0, m);string r;for(int i = 0 ; i < n ; i ++) r += s;if(r == str){cout << n << endl;break;}}}}return 0;
}
778. 字符串最大跨距 - AcWing题库
#include<bits/stdc++.h>using namespace std;int main()
{string s, s1, s2;char c;while(cin >> c, c != ',') s += c;while(cin >> c, c != ',') s1 += c;while(cin >> c) s2 += c;if(s.size() < s1.size() || s.size() < s2.size()) puts("-1");else{int l = 0;while(l + s1.size() <= s.size()){int k = 0;while(k < s1.size()){if(s[l + k] != s1[k]) break;k++;}if(k == s1.size()) break;l++;}int r = s.size() - s2.size();while(r >= 0 ){int k = 0;while(k < s2.size()){if(s[r + k] != s2[k]) break;k++;}if(k == s2.size()) break;r--;}l += s1.size() - 1;if( l >= r) puts("-1");elsecout << r - l - 1 << endl;}return 0;
}
779. 最长公共字符串后缀 - AcWing题库
#include <iostream>using namespace std;const int N = 200;int n;
string str[N];int main()
{while (cin >> n, n){int len = 1000;for (int i = 0; i < n; i ++ ){cin >> str[i];if (len > str[i].size()) len = str[i].size();}while (len){bool success = true;for (int i = 1; i < n; i ++ ){bool is_same = true;for (int j = 1; j <= len; j ++ )if (str[0][str[0].size() - j] != str[i][str[i].size() - j]){is_same = false;break;}if (!is_same){success = false;break;}}if (success) break;len -- ;}cout << str[0].substr(str[0].size() - len) << endl;}return 0;
}