C/C++语法:(一)数组

1.memset

位于<cstring>库中,用于批量修改数组值,如:

memset(a, 0, a.length); //用0初始化数组a,初始化的长度为a.length

但是注意该函数是按字节赋值的,例如:

int a[10]; //10个int即40个B
memset(a, 1, 40);

表示从初始位置开始的\(40\)\(B\)(字节),对于每个int,即\(4\)\(B\),全部复制为二进制的1,

即:00000001 00000001 00000001 00000001,转换为10进制即,\(16843009\),因此数组a中的所有值均为\(16843009\).

显然想要用这个函数以任意值初始化数组是及其不方便的,因此我们常用这个函数给数组全部赋值为\(0\),或者全部赋值为-1(根据补码相关知识),只有这两个值. 而对于其他的字节上不连续的值,只能通过循环遍历数组来初始化.

除此之外,第三个参数为总字节数,显然手动计算是十分不方便的,一般填入sizeof a,sizeof之后可加可不加括号.

2.memcpy

用于将一个数组复制到另一个数组中:

memcpy(b, a, sizeof a); //最后一个参数表示复制多长

例1.利用数组计算高精度的\(2^N\)

模拟乘法计算过程,将数的每一位存在一个数组\(a\)里。为了进位方便,将大数的最低位存放于\(a[0]\)中。

遍历数组,用2乘数组的每一位,若得到数\(>=10\),则在数组的下一个位置\(+1\)

#include <iostream>
#include <cmath>

using namespace std;

const int N = 3010;

int main()
{
    int a[N] = {1}; //第1位设为1
    int m = 1;
    int n; //2^n
    cin >> n;
    
    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; //表示数多了一位,例如8->16
    }
    
    for (int i = m - 1; i >= 0 ; i --){
        cout << a[i];
    }
    return 0;
}

这样就可以精确地表示\(2^N\)了!

例2.数组的右上半部分

如下图所示,求二维数组右上部分(不包括对角线)的或者是均值

#include <cstdio>
#include <iostream>
using namespace std;

double a[12][12];

int main(){
    char t;
    scanf("%c", &t);
    
    for (int i = 0; i < 12; i ++)
        for (int j = 0; j < 12; j ++)
            scanf("%lf", &a[i][j]);
            
    int cnt; //记录右上半部分的小方格个数 用以计算平均值
    double sum = 0;
    
    for (int i = 0; i < 12; i ++)
        for (int j = i + 1; j < 12; j ++){
            cnt ++;
            sum += a[i][j];
        }
    
    if (t == 'M') printf("%.1f", sum / cnt);
    else printf("%.1f", sum);
    
    return 0;
}

本文算法思想源于Acwing,特此注明。

posted @ 2020-09-23 20:03  AIchemistar  阅读(277)  评论(0)    收藏  举报