• 二维数组学习笔记


    一、二维数组的定义

    当一维数组元素的类型也是一维数组时,便构成了“数组的数组”,即二维数组。
    二维数组定义的一般格式:

    数据类型 数组名[常量表达式][常量表达式]
    

    例如:

    int a[4][10]
    

    a数组实质上是一个有 (4) 行、 (10) 列的表格,表格中课存储 (40) 个元素。第 (1) 行第 (1) 列对应 (a) 数组的 (a[0][0]),第n行第m列对应数组元素 (a[n-1][m-1])

    说明:当定义的数组下表有多个时,我们称为多维数组,下标的个数并不局限在一个或两个,可以任意多个,如定义一个三维数组 (a) 和四维数组 (b)

    int a[5][3][10];
    int b[100][100][20][5];
    

    多维的数组引用赋值等操作与二维数组类似。

    二、二维数组元素的引用

    二维数组的数组元素引用于一位数组元素引用类似,区别在于二维数组元素的引用必须给出两个下标。
    引用的格式为:

    <数组名>[下标1][下标2]
    

    说明:显然,每个下标表达式取值不应超出下标所指定的范围,否则会导致致命的越界错误。
    例如,设有定义:

    int a[3][5];
    

    则表示 (a) 是二维数组(相当于一个 (3 imes 5) 的表格),共有 (3 imes 5 = 15) 个元素,它们是:

    a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]
    a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]
    a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]
    

    因此可以看成一个矩阵(表格),(a[2][3]) 即表示第 (3) 行第 (4) 列的元素。

    三、二维数组的初始化

    二维数组的初始化和一维数组类似。可以将每一行分开来写在各自的括号里,也可以把所有数据写在一个括号里。
    例如:

    int direct[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    int direct[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
    

    例1 对角线翻转

    题目描述

    给你一个 (n imes n) 的二维数组,你需要对其按照对角线进行翻转,并输出翻转后的二维数组。
    例如,下面左边是一个 (3 imes 3) 的二维数组,后边是它按照对角线进行翻转后的二维数组:

    1 2 3                   1 4 7 
    4 5 6                   2 5 8
    7 8 9                   3 6 9
    

    输入格式

    输入的第一行包含一个整数 (n(1 le n le 100))
    接下来 (n) 行,每行包含 (n) 个整数,用于表示二维数组中的每个元素(每个元素均为 (1000) 以内的正整数)。

    输出格式

    输出 (n) 行,每行包含 (n) 个整数,两两之间以一个空格分隔,用于表示按对角线翻转后的二维数组。

    样例输入

    3
    1 2 3
    4 5 6
    7 8 9
    

    样例输出

    1 4 7
    2 5 8
    3 6 9
    

    问题分析

    我们假设数组 (a[i][j]) 用于表示原二维数组中第 (i) 行第 (j) 列的元素,而沿对角线翻转后它的位置变到了第 (j) 行第 (i) 列。
    所以,输入的时候,我们开两层for循环,外层循环遍历行号 (i),内层循环遍历列号 (j) ,输入 (a[i][j])
    而输出的时候,我们开两层for循环,外层循环遍历列号 (j),内层循环遍历行号 (i),输出 (a[i][j]) 即可。

    示例代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[100][100];
    int main() {
        cin >> n;
        for (int i = 0; i < n; i ++)    // 输入的时候先遍历行号i,再遍历列号j
            for (int j = 0; j < n; j ++)
                cin >> a[i][j];     // 输入a[i][j]
        for (int j = 0; j < n; j ++) {  // 输出的时候先遍历列号j,在遍历行号i
            for (int i = 0; i < n; i ++) {
                if (i > 0) cout << " "; // 除了最前面那个元素以外的元素前先数一个空格,能保证两两之间以一个空格分隔
                cout << a[i][j];    // 输出a[i][j]
            }
            cout << endl;   // 内层循环结束记得加一个回车
        }
        return 0;
    }
    

    例2 对角线增加

    题目描述

    已知一个 (n imes n) 的矩阵(方阵),把所有处在矩阵的两条对角线上面的元素都加上 (10),然后输出这个新矩阵。

    输入格式

    输入的第一行包含一个整数 (n(1 le n le 100))
    接下来 (n) 行,每行包含 (n) 个整数,用于表示二维数组中的每个元素(每个元素均为 (1000) 以内的正整数)。

    输出格式

    输出 (n) 行,每行包含 (n) 个整数,两两之间以一个空格分隔,用于表示两条对角线上的元素都 (+10) 之后的矩阵。

    样例输入

    3
    1 1 1
    1 1 1
    1 1 1
    

    样例输出

    11 1 11
    1 11 1
    11 1 11 
    

    问题分析

    首先我们假设行号和列号都从 (0) 开始,即左上角的元素为 (a[0][0]),右下角的元素为 (a[n-1][n-1]),然后我们去遍历每一行(假设行号是 (i)),那么只有列号 (j) 满足条件 (j==i) 或者 (j == n-1-i) 的格子上的元素需要 (+10)
    当然我们要注意,当 (n) 为奇数时,中间的那个点 (a[n/2][n/2]) 同时处在了两条对角线上,但是只需要加一遍即可。
    示例代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[100][100];
    int main() {
        cin >> n;
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++)
                cin >> a[i][j];
        for (int i = 0; i < n; i ++) {
            if (i == n-1-i) // 说明第i行两条对角线上的点重叠了
                a[i][i] += 10;  // 所以只需要给这一个点+10即可
            else {          // 否则,需要给两个点依次+10
                a[i][i] += 10;
                a[i][n-1-i] += 10;
            }
        }
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < n; j ++) {
                if (j) cout << " ";
                cout << a[i][j];
            }
            cout << endl;
        }
        return 0;
    }
    

    例3 稀疏矩阵存储方案

    题目描述

    大部分元素是 (0) 的矩阵称为 稀疏矩阵 ,假设有 (k) 个非 (0) 元素,则可把稀疏矩阵用 (k imes 3) 的矩阵简记之,其中第一列是行号,第二列是列号,第三列是该行、该列下的非零元素的值。如:

    0 0 0 5             简记为:  1 4 5   // 第1行第4列有一个5
    0 2 0 0                     2 2 2   // 第2行第2列有一个2
    0 1 0 0                     3 2 1   // 第3行第2列有一个1
    

    试编程读入一稀疏矩阵,转换成简记形式,并输出。

    输入格式

    输入的第一行包含两个整数 (n,m(1 le n le 100)),分别表示矩阵的行数和列数。
    接下来 (n) 行,每行包含 (m) 个整数,用于表示二维数组中的每个元素(每个元素均为 (1000) 以内的正整数)。

    输出格式

    输出若干行,每行包含 (3) 个整数,以空格分隔,分别表示行号、列号和该非零元素的值。
    请按照行号从小到大,行号相同的列号从小到大输出这些数据。

    样例输入

    3 4
    0 0 0 5
    0 2 0 0
    0 1 0 0
    

    样例输出

    1 4 5
    2 2 2
    3 2 1
    

    问题分析

    本题中需要解决的主要问题是查找非零元素并记忆位置。将原始矩阵存于数组 (a)。转换后的矩阵存于数组 (b),当然 (b) 数组的行数可以控制在一个可控范围内。
    我们可以开一个变量 (k),一开始 (k=0),然后我们去遍历每一行每一列。
    如果第 (i) 行第 (j) 列的元素 (a[i][j] e 0),则执行如下操作:

    k ++;
    b[k][0] = i;
    b[k][1] = j;
    b[k][2] = a[i][j];
    

    这样,最终我们可以的数据将会保存在 (b) 数组中坐标从 (1)(k) 范围内。

    示例代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n, m, a[101][101], b[10010][3], k;
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= m; j ++) {
                cin >> a[i][j];
                if (a[i][j]) {  // 输入的同时就进行判断
                    k ++;
                    b[k][0] = i;    // 标记行号
                    b[k][1] = j;    // 标记列号
                    b[k][2] = a[i][j];  // 标记数值
                }
            }
        }
        for (int i = 1; i <= k; i ++)
            cout << b[i][0] << " " << b[i][1] << " " << b[i][2] << endl;
        return 0;
    }
    
  • 相关阅读:
    Java并发理论简介
    【SQL】- 基础知识梳理(八)
    【SQL】- 基础知识梳理(七)
    【SQL】- 基础知识梳理(六)
    【SQL】- 基础知识梳理(五)
    【SQL】- 基础知识梳理(四)
    【SQL】- 基础知识梳理(三)
    '{ }'在不同上下文中的作用
    模块化你的JS代码
    利用模板将HTML从JavaScript中抽离
  • 原文地址:https://www.cnblogs.com/quanjun/p/12762798.html
Copyright © 2020-2023  润新知