10min快速回顾C++语法(四)数组专题
C++的语法基础(四)数组专题
⭐写在前面的话:本系列文章旨在短时间内回顾C/C++语法中的重点与易错点,巩固算法竞赛与写题过程中常用的语法知识,精准地解决学过但有遗忘的情况,为算法刷题打下坚实的基础。
七、数组
7.1 一维数组
7.1.1 数组的定义
数组的定义方式和变量类似。
这里需要注意的一点是:
- main函数内部定义的数组会放在栈空间内,而(本地编译器)栈空间默认为1M,因此如果数组开的过大后,超过栈空间的容量,会报错TLE。
- 为了避免这种现象,需要将数组定义在全局(main函数外部),这样是保存在堆空间内。基本没有限制。
栈通常是用来运行指令的,堆用来存储数据。
#include <iostream> #include <algorithm> using namespace std; int main() { int a[10], b[10];//数组长度 float f[33]; double d[123]; char c[21]; return 0; }
7.1.2 数组的初始化
- 在main函数内部,未初始化的数组中的元素是随机的。
- 而main函数外部,未初始化的数组中的元素全是0。
堆中的空间不会真的开辟出来,申请数组之后,用的时候用一块内存开一块,会提前标记为0,形成零页,使用时再进行赋值。
#include <iostream> #include <algorithm> using namespace std; int main() { int a[3] = {0, 1, 2}; // 含有3个元素的数组,元素分别是0, 1, 2 int b[] = {0, 1, 1}; // 维度是3的数组 int c[5] = {0, 1, 2}; // 等价于c[] = {0, 1, 2, 0, 0} char d[3] = {'a', 'b', 'c'}; // 字符数组的初始化,注意单引号''。 return 0; }
7.1.3 访问数组元素
通过下标访问数组。
- 数组下标从0开始。
- 注意数组访问最好不要越界,越界就有可能报错"Segmentation Fault"。
#include <iostream> #include <algorithm> using namespace std; int main() { int a[3] = {0, 1, 2}; // 数组下标从0开始 cout << a[0] << ' ' << a[1] << ' ' << a[2] << endl; a[0] = 5; cout << a[0] << endl; return 0; }
7.2 程序练习
练习题1: 使用数组实现求斐波那契数列的第 N 项。
#include <iostream> #include <algorithm> using namespace std; int main() { int n; int f[100]; cin >> n; f[0] = 0, f[1] = 1; for (int i = 2; i <= n; i ++ ) f[i] = f[i - 1] + f[i - 2]; cout << f[n] << endl; return 0; }
练习题2:输入一个 n,再输入 n 个整数。将这 n 个整数逆序输出。
#include <iostream> #include <algorithm> using namespace std; int main() { int n; int a[100]; 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> #include <algorithm> using namespace std; int main() { int n, k; int a[100]; cin >> n >> k; fot(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; }
方法二:
巧妙做法:
eg:0123456|789
首先翻转整个数组
987|6543210
再翻转前半部分
789|6543210
最后翻转后半部分
789|0123456
或者先旋转两个半部分,再旋转整个数组即可。
#include <iostream> #include <algorithm>//包含reverse函数 using namespace std; int main() { int n, k; int a[100]; cin >> n >> k; for (int i = 0; i < n; i ++ ) cin >> a[i]; reverse(a, a + k); reverse(a + k, a + n); reverse(a, a + n); for (int i = 0; i < n; i ++ ) cout << a[i] << ' '; cout << endl; return 0; }
练习题4:输入 n 个数,将这 n 个数按从小到大的顺序输出。
#include <iostream> #include <algorithm> using namespace std; int main() { int n; int a[100]; cin >> n; for (int i = 0; i < n; i ++ ) cin >> a[i]; for (int i = 0; i < n; i ++ ) for (int j = i + 1; j < n; j ++ ) if (a[i] > a[j]) swap(a[i], a[j]); for (int i = 0; i < n; i ++ ) cout << a[i] << ' '; cout << endl; return 0; }
高精度运算
练习题5:计算 2 的 N 次方。N≤10000
#include <iostream> #include <algorithm> using namespace std; int main() { int a[10000], size = 1, n; a[0] = 1; cin >> n; while (n -- ) { int t = 0; for (int i = 0; i < size; i ++ ) { t += a[i] * 2; a[i] = t % 10; t /= 10; } if (t) a[size ++ ] = t; } for (int i = size - 1; i >= 0; i -- ) cout << a[i]; cout << endl; return 0; }
7.3 多维数组
多维数组就是数组的数组。
7.3.1 多维数组的初始化
int a[3][4]; // 大小为3的数组,每个元素是含有4个整数的数组。 int arr[10][20][30] = {0}; // 将所有元素初始化为0 // 大小为10的数组,它的每个元素是含有20个数组的数组 // 这些数组的元素是含有30个整数的数组 #include <iostream> #include <algorithm> using namespace std; int main() { int b[3][4] = { // 三个元素,每个元素都是大小为4的数组 {0, 1, 2, 3}, // 第1行的初始值 {4, 5, 6, 7}, // 第2行的初始值 {8, 9, 10, 11} // 第3行的初始值 }; return 0; }
7.3.2 memset
- 注意memset的单位是字节Byte,一个int变量是32bit,即4 Bytes。
- 在cstring库中
- memset(数组名,数组中每个字节赋的值,一共bytes数)
- 注意是字节赋值的,一般赋为0or-1,其中-1储存的是全1。其他赋值有变化,例如5是00000101,多个bytes组成一个数,可能会非常奇怪的数。
#include<iostream> #include<cstring> using namespace std; int main() { int a[10]; memset(a,0,sizeof a); return 0; }
7.3.3 memcpy
memcpy(b,a,sizeof a);
- 第一个参数为目标数组
- 第二个为复制的源数组
- 第三个为复制的长度。
7.4 程序练习
输入一个 n 行 m 列的矩阵,从左上角开始将其按回字形的顺序顺时针打印出来。
#include <iostream> #include <algorithm> using namespace std; int main() { int n, m; int arr[50][50]; cin >> n >> m; for (int i = 0; i < n; i ++ ) for (int j = 0; j < m; j ++ ) cin >> arr[i][j]; bool st[50][50] = {false}; int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; int d = 1, x = 0, y = 0; for (int i = 0; i < n * m; i ++ ) { int a = x + dx[d], b = y + dy[d]; if (a < 0 || a >= n || b < 0 || b >= m || st[a][b]) { d = (d + 1) % 4; a = x + dx[d], b = y + dy[d]; } cout << arr[x][y] << ' '; st[x][y] = true; x = a, y = b; } cout << endl; return 0; }
7.5 特殊补充浮点数比较
浮点数的比较。由于浮点数存储的并非精确值,因此在比较浮点数时可以设置一个容忍误差。如下
#include <bits/stdc++.h> using namespace std; const double eps = 1e-6; int main() { int a,b; cin>>a>>b; if(fabs(a - b)<=eps) puts("相等"); else if(a<b-eps)puts("小于"); else puts("大于"); return 0; }
不相等举例:
int a = 3; if(sqrt(3) * sqrt(3) <3)puts("不相等?")#C/C++##算法学习#