数组
数组的初始化
(1)在main函数内部,未初始化的数组中的元素是随机的;在函数外定义的数据,未初始化的数组中的元素默认为0。
(2)在函数内部数据(局部变量)存放在数据栈中,一般的C++编辑器最多开辟1兆的空间;若不够用可放在函数外(作为全局变量),函数外的数据存放在堆中,空间更大,只受内存限制。
#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;
}
例题
(1)输入一个 n,再输入 𝑛个整数。将这个数组顺时针旋转 k(k≤n)次,最后将结果输出。旋转一次是指:将最左边的数放到最右边。
法一:常规做法(三次循环)
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int n,k,a[100];
cin >> n >> k;
for(int i=0;i<n;i++){
cin >> a[i];
}
for(int j=0;j<k;j++){
int t = a[n-1];
for(int i=n-1;i>0;i--){
a[i]=a[i-1];
}
a[0] = t;
}
for(int i=0;i<n;i++){
printf("%d ",a[i]);
}
return 0;
}
法二:利用reverse()反转(注意用algorithm库)。第一次将数组整个翻转;第二次翻转前半部分(a ~ a+k,翻转k次);第三次翻转后半部分(a+k ~ a+n)
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int n,k,a[10];
cin >> n >> k;
for(int i=0;i<n;i++){
cin >> a[i];
}
if(k>n) k=k%n; //可能会翻转一轮,即k>n
reverse(a,a+n); //翻转范围[a,a+n)
reverse(a,a+k); //即翻转[a,a+k)
reverse(a+k,a+n); //翻转[a+k,a+n)
for(int i=0;i<n;i++){
cout << a[i] << " ";
}
return 0;
}
法三:直接将数组拆成两部分,翻转部分和其他
#include <iostream>
using namespace std;
int main(){
int n,k,a[5],b[5];
cin >> n >> k;
if(k>n) k= k%n;
for(int i=0,j=0;i<n;i++){
if(i<n-k) cin >> a[i]; //b[]中有k个数,a[]中就有n-k个数,则下标 < n-k
else{
cin >> b[j];
j++;
}
}
for(int i=0,j=0;i<n;i++){
if(i<k) cout << b[i] << " "; //翻转k次,b[]中就有k个数
else{
cout << a[j] << " ";
j++;
}
}
return 0;
}
浮点数精度:浮点数在计算机中以科学技术法存放,故做乘除运算时可能精度不够造成误差。(float精度:小数点后6位;double精度:小数点后12位)可选做以下优化:
(1)比较两个浮点数,一般认为x-y的绝对值(fabs(x-y))小于eps(10^(-6)),就认为两数相等;x < y-eps,则认为y大于x
高精度运算(用数组存储运算数的每一位):一般用a[0]存储个位之后的位数以此类推,各位数做运算时既要得到本位数的结果,也要得到进位数。
计算 2 的𝑁 次方,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;
}
数组清空(即置0,memset())
memset(a,x,l)以字节为单位,即8位;a为要清空的数组,x为清空后所置值,l为要清空的数组长度。
#include <iostream>
#include <cstring>
int main(){
int a[4],b[4];
memset(a,0,16); // 一个int型变量占4字节,故清空a[4],就要清空16字节
//也可用memset(a,0,sizeof a)
}
注意:清空后置值也是字节为单位,例如:x=1,l=16则计算机存储时为00000001 00000001,十进制数为257。
一般的,会赋值为全0或全1,赋值为意识会写memset(a,-1,16),因为计算机存储数的补码,-1的补码为全1(32个1);
数组过长可用sizeof计算数组所占字节长度,如:memset(a,-1,sizeof a)。
在初始化较长数组时,memset更省时方便
数组复制(memcpy())
memcpy(b,a,sizeof a):把a复制给b