• [一,二维数组的声明与使用(1)] 从0开始的异世界编程 4


    Chapter 0:数组

    我们想想这样一个问题:
    我们要读入一些数字,再将他们倒着输出。整数的个数不超过200个。
    思路:
    我们首先一定是用循环来读入的吧,但是要把读入进来的数存在哪里呢?定义许多变量,每个变量存一个数字?想想肯定是行不通的。那怎么办?答案是:开一个数组来存。
    代码:

    #include 
     
    using namespace std;
    
    int a[10000];//*
    
    int main()
    {
    	int s;
    	int k=0;
    	
    	while(scanf("%d",&s)==1)//只要有输入就循环
    	{
    		a[k++]=s;//*
    	}
    	
    	for(int i=k-1;i>=0;i--)//逆序输出*
    	{
    		cout<<a[i]<<" ";//*
    	}
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    代码分析:

    我们看到第一处带有 * 的位置,和其他变量相同,数组也是需要定义的。int声明了该数组是整数类型,a[]声明了数组的名称,10000表示的是a数组的空间,即能存多少个数。注意,a[10000]中可以使用的有:a[0],a[1]...a[10000-1],这里是没有a[10000]的。因为数组的下标是从0开始的。当然,如果必须存到10000,可以把数组开大一点,也就是更改a[]中的常量

    第二处带有 * 的位置,这里要注意的是k++。k++表示的是将k+1。但是在这里,k不只是加了1。加号在k身后,a[k++]=s表示先将s存入a[k]中,再将k+1。与k++相对的是++k。a[++k]=s表示先将k+1,在将s存入a[k]中(这里的k表示+1后的k)。如果不理解,可以将a[k++]=s修改为a[k]=s,k++;。同理,还可以将a[++k]=s修改为k++,a[k]=s。是不是很简单?

    第三处带有 * 的位置,这里的i的初值是k-1,而不是k。这是因为我们是先将s存入a[k]中,再将k+1。直到while循环结束时,k多加了1,所以给i赋初值时k要-1。同理,i>=0是因为存放数字是是从最开始的a[k]开始,即a[0]开始的,所以要输出至a[0]而不是a[1]。

    第四处带有 * 的位置就很简单了。这里要提到的是数组的输出。和所有的变量一样,数组的输出也是需要cout<<或者printf()的。这里是cout<,a[i]是被输出的变量,i表示输出的这个变量在数组a中的位置(下标是0开始)。

    Chapter 1:一维数组

    STEP 1:声明与调用

    参见Chapter 0,一维数组的声明就是数组类型 数组名[数组空间];
    如何调用数组呢?最简单的就是数组名[调用的下标]。注意,调用的下标的范围:0<=数组下标<=该数组定义的空间

    STEP 2:例题与分析

    我们来看一道例题:

    题目描述

    线性代数、计算几何中,向量点积是一种十分重要的运算。

    给定两个 n n n 维向量 a = ( a 1 , a 2 , ⋯   , a n ) a=(a_1,a_2, \cdots ,a_n) a=(a1,a2,,an) b = ( b 1 , b 2 , ⋯   , b n ) b=(b_1,b_2, \cdots ,b_n) b=(b1,b2,,bn),求点积 a a a · b = a 1 b 1 + a 2 b 2 + ⋯ + a n b n b=a_1b_1+a_2b_2+ \cdots +a_nb_n b=a1b1+a2b2++anbn

    输入格式
    第一行是一个整数 n n n 1 ≤ n ≤ 1000 1 \le n \le 1000 1n1000
    第二行包含 n n n 个整数 a 1 , a 2 , ⋯   , a n a_1,a_2, \cdots ,a_n a1,a2,,an
    第三行包含 n n n 个整数 b 1 , b 2 , ⋯   , b n b_1,b_2, \cdots ,b_n b1,b2,,bn

    相邻整数之间用单个空格隔开。每个整数的绝对值都不超过 1000 1000 1000

    输出格式
    一个整数,即两个向量的点积结果。

    样例
    输入

    3
    1 4 6
    2 1 5
    
    • 1
    • 2
    • 3

    输出

    36
    
    • 1

    分析
    这道题让我们求a,b两个向量的点积结果。
    我们看看这里: a a a · b = a 1 b 1 + a 2 b 2 + ⋯ + a n b n b=a_1b_1+a_2b_2+ \cdots +a_nb_n b=a1b1+a2b2++anbn。是不是有思路了呢?我们可以定义a,b两个数组,分别存 a 1 , a 2 , ⋯   , a n a_1,a_2, \cdots ,a_n a1,a2,,an b 1 , b 2 , ⋯   , b n b_1,b_2, \cdots ,b_n b1,b2,,bn。再用一个循环将每个 a i b i a_ib_i aibi乘起来,累加到sum里面,最后输出sum就可以啦~

    代码

    #include
    
    using namespace std;
    
    long long a[1000000],n,b[1000000],sum;
    
    int main()
    {
    	cin>>n;
    	
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	
    	for(int i=1;i<=n;i++)
    	{
    		cin>>b[i];
    	}
    	
    	for(int i=1;i<=n;i++)
    	{
    		sum+=a[i]*b[i];
    	}
    	
    	cout<<sum;
    	
     	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    是不是轻松?

    STEP 3:习题

    1. 洛谷 P5731 【深基5.习6】蛇形方阵(切记不要打表!)
    2. 洛谷 B2092 开关灯(有不用数组的方法)
    3. 洛谷 B2098 整数去重(注意定义的数组类型)
    4. B3639 T2 点亮灯笼(有点难)

    Chapter 2:二维数组

    STEP 1:基本的概念与声明

    在这里插入图片描述
    一维数组就相当于与有一行抽屉,每个抽屉都能取出放入东西。而二维数组球相当于模型柜(也可以理解为一墙的柜子),每个格子也能取出放入东西。即一个面的柜子。
    如何声明二维数组
    因为二维数组和一位数组很像,所以他们的声明长得也很像。一维数组的声明:数组类型 数组名[数组空间]二维数组的声明:数组类型 数组名[数组空间][数组空间]。其中二维数组的前一个空间可以用来表示行,后一个空间表示列。(当然也可以反着)。我们举一个例子:如果前一个空间表示行,后一个空间表示列,那么第3行第5列的值就可以表示为:a[3][5]。当然,二维数组的输出与一维数组相似,只需改动后面的两个[]即可。

    STEP 2:例题与分析

    【深基5.习6】蛇形方阵

    题目描述

    给出一个不大于 9 9 9 的正整数 n n n,输出 n × n n\times n n×n
    的蛇形方阵。

    从左上角填上 1 1 1 开始,顺时针方向依次填入数字,如同样例所示。注意每个数字有都会占用 3 3 3 个字符,前面使用空格补齐。

    输入格式

    输入一个正整数 n n n,含义如题所述。

    输出格式

    输出符合题目要求的蛇形矩阵。

    样例

    输入

    4
    
    • 1

    输出

    1  2  3  4
    12 13 14  5
    11 16 15  6
    10  9  8  7
    
    • 1
    • 2
    • 3
    • 4

    分析
    从样例中我们可得知:蛇形方阵每次都走到头才转换方向,即在没有碰到数字或边界时,他是不会转弯的。那我们只需判断一下是否需要转弯即可。

    代码

    #include
    
    using namespace std;
    
    int a[20][20];
    
    int n,k=1;
    
    int x=1,y=0;
    
    int main()
    {
    	cin>>n;
    	
    	while(k<=n*n)//只要没走万=完就循环
    	{
    		//4个while循环,中y1,x>1判断边界;后面的判断当前位置是否有数字,即是否碰到数字
    
    		while(y<n&&!a[x][y+1])a[x][++y]=k++;//右边能走,向右走
    		
    		while(x<n&&!a[x+1][y])a[++x][y]=k++;//下边能走,向下走
    		
    		while(y>1&&!a[x][y-1])a[x][--y]=k++;//左边能走,向左走
    		
    		while(x>1&&!a[x-1][y])a[--x][y]=k++;//上边能走,向上走
    	}
    	
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=1;j<=n;j++)
    		{
    			cout<<a[i][j]<<" ";
    		}
    		
    		printf("\n");	
    	}	
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在上面的代码中,&&表示的是并且的意思。用在if语句中表示&&两边的判断必须同时满足才能执行。

    Chapter 3:注释与说明

    memset()
    memset表示将任意一个值k赋给数组x的所有空间,举例memset(a,0,sizeof(a))。第一个a表示被赋值的数组名,0表示赋的值,sizeof(a)表示赋值给数组a

    memcpy():
    memcpy与memset相似,都是将什么赋给什么。memcpy表示将数组x复制k个元素到数组y,举例memcpy(b,a,sizeof(int) * k)。b表示接受复制元素的数组,a表示被赋值元素的数组,int是两个数组了类型,k表示被复制元素的个数。当然,如果要将a数组全部复制给b数组,可以写成memcpy(b,a,sizeof(a))

  • 相关阅读:
    Touch命令使用指南:创建、更新和修改文件时间戳
    Gitlab部署
    记一次高校学生账户的“从无到有”
    背包九讲(部分)
    Python3-excel文档操作(二):利用openpyxl库处理excel表格:在excel表格中插入图片
    c++文件解析之换行(CRLF、LF、CR)
    Qt之自定义插件(单控件,Qt设计师中使用)
    刷题笔记day01-数组
    洛谷 P1135 奇怪的电梯 P1135 Java
    Word | 简单可操作的快捷公式编号、右对齐和引用方法
  • 原文地址:https://blog.csdn.net/m0_66603329/article/details/126567012