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

Chapter 0:数组

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

#include <bits/stdc++.h>
 
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;
}

代码分析:

我们看到第一处带有 * 的位置,和其他变量相同,数组也是需要定义的。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],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

输出

36

分析
这道题让我们求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<bits/stdc++.h>

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;
}

是不是轻松?

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  2  3  4
12 13 14  5
11 16 15  6
10  9  8  7

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

代码

#include<bits/stdc++.h>

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循环,中y<n,x<n,y>1,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;
}

在上面的代码中,&&表示的是并且的意思。用在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))

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

harmis_yz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值