第5单元 数组

第五单元 数组

之前学习了顺序结构,分支结构和循环结构,可以解决很多的复杂的问题。

但当数据较多时循环结构的循环重数会大大增多,这时会使写的程序非常繁琐,

并且有可能出现一些超时的问题。此时就能够突出学习数组的意义。

它能够解决很多繁琐的问题使数据存在一个数组中,

要用的时候就从中提取,可以大大减少程序的长度,

从而优化程序。

但是随之而来的问题是学习的数组难度大大升高。

第一课  一维数组的定义

①定义一维数组的格式为

类型标识符 数组名[常量表达式];

(类型标识符可以是任何基本数据类型,

也可以是结构体等构造类型,相同类型的数组可以一起定义)

②在使用一维数组时需注意:

下标是从零开始的,所以要额外注意下标越界的问题。

如:int a[5]   其中int基类型

意为定义了一个有五个int型元素的数组

int a[5]={11 12 13 14 15};

意为这五个元素分别赋值为括号中的数。

int a[ ]={11 12 13 14 15};

给了几个初值就有几个元素。

③如果要求一个数组所占的内存空间可以用sizeof函数

第二课 一维数组的输入与输出

主要是要掌握一维数组的输入与输出操作

并且学会应用一维数组解决一些实际的问题。

①一维数组的输入均是由循环语句实现,将批量的数据一次性输入到数组中

如:int h[100];

for(i=0;i<100;i++) cin>>h[i];

也可以直接赋值

②还提供了两个函数给数组整体赋值

⑴memset函数

一般都是用在char数组中

如果是int类型的数组,一般赋值为0和-1

使用前需要包含头文件:#include<cstring>

⑵fill函数

“按元素”进行赋值,使用前需要包含头文件:#include<algorithm>

例如:

校门外的树

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入

第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

对于20%的数据,区域之间没有重合的部分;
对于其它的数据,区域之间有重合的情况。

输出

包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

样例输入

500 3
150 300
100 200
470 471

样例输出

298
#include<cstdio>
using namespace std;
int a[10001],n,m,x,y,s=0;//要保证下标绝对不会越界
int main()
{
	scanf("%d%d",&n,&m);//n代表马路长度,m代表区域数目
	for(int i=0;i<=n;i++) 
	a[i]=1;           //输入了一个数组中元素均为1的数组
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);

		for(int j=x;j<=y;j++) 
		a[j]=0;//为了算移去了多少树,所以重新建立了一个数组
	}
	for(int i=0;i<=n;i++)
	{
	if(a[i]==1) 
	s++;	//s是个计数变量
	}
	printf("%d",s);
	return 0;
}

此题的难点在于区域之间可能有重合的部分,

第三课   一维数组的插入删除

学会数组元素的插入和删除操作并解决一些实际问题

要额外注意要把数组下标定义的足够大

 

【题目描述】
有 n 个人(每个人有一个唯一的编号,用 1~n 之间的整数表示)在一个水龙头前排队准备接水,现在第 n 个人有特殊情况,经过协商,大家允许他插队到第 x 个位置。输出第 n 个人插队后的排队情况。

【输入】
第一行 1 个正整数 n,表示有 n 个人,2<n≤100。
第二行包含 n 个正整数,之间用一个空格隔开,表示排在队伍中的第 1~ 第 n 个人的编号。
第三行包含 1 个正整数 x,表示第 n 个人插队的位置,1≤x<n。

【输出】
一行包含 n 个正整数,之间用一个空格隔开,表示第 n 个人插队后的排队情况。

【输入样例】
7
7 2 3 4 5 6 1
3

【输出样例】
7 2 1 3 4 5 6

代码

#include<cstdio>

using namespace std;

int a[101],n,x,t;

int main() {

scanf("%d",&n);

for(int i=1;i<=n;i++)

scanf("%d",&a[i]);//a[i]表示排在第i位上的人

scanf("%d",&x);

t=a[n];

for(int j=n;j>=x+1;j--)

a[j]=a[j-1]; //重复执行了a[j]=a[j-1];

a[x]=t;

for(int i=1;i<=n;i++)

printf("%d ",a[i]);

return 0; }

第四课 一维数组的查找统计

主要学会使用二分查找,如果用顺序查找工程量太大且容易超时,

使用二分查找比较次数少,查找速度快。

二分查找的方法:

int left =0,right=n-1;

int find=n;//find标记找到的位置,初始化为n,表示没找到。

while( left<= right){

int mid=(left+right)/2

if(a[mid]==x){//找到了,就标记位置,并退出循环

find=mid;

break;

}

if(x<a[mid]) right=mid-1;//x只能在左半部分

if(a[mid]<x) left=mid+1;//x只能在右半部分

}

if(find!=n)printf("%d\n",find);

else printf("not find\n");

二分查找:①找内容

②找到东西是有序的

局部统计一定在具体统计之前赋初值

不可以早赋,全局统计可以在定义变量时赋初值

如:

【题目描述】
有 N 个人排成一排,假设他们的身高均为正整数,请找出其中符合以下条件的人:排在他前面且比他高的人数与排在他后面且比他高的人数相等。

【输入】
第一行为一个正整数 N,1<N<1000,表示有多少个人。
下面 N 行,每行一个正整数,表示从前往后每个人的身高,假设每个人的身高≤10000。

【输出】
一行一个整数,表示满足这个条件的人数。

【输入样例】
4
1
2
1
3

【输出样例】
2

【样例说明】
第 3、第 4 个人满足条件。

代码

#include<cstdio>

using namespace std;

int i,j,k,s=0,t1,t2,n,a[1001];

int main() {

scanf("%d",&n);

for(i=1;i<=n;i++)

scanf("%d",&a[i]);

for(i=1;i<=n;i++) {

t1=t2=0; //统计之前赋初值

for(j=1;j<i;j++) {

if(a[j]>a[i])

t1++;//排在他前面且比他高的人数

}

for(k=i+1;k<=n;k++) {

if(a[k]>a[i])

t2++;//排在他后面且比他高的人数

}

if(t1==t2)

s++;//为了计这样的人有几个

}

printf("%d",s);

return 0; }

第五课 一维数组的元素排序

主要学习三种排序:选择排序、冒泡排序和插入排序这三种排序各有各的优点

最重要的是返回值

bool complare (int a,int b)

{return a>b//返回值

}真为ture,假为false

 

【题目描述】
某商场的仓库中有 n 件商品,每件商品的价格在 0~1000 之间(价格为 0 的商品为赠品)。现在商场经理要求将这 n 件商品按价格由低到高排序。请编程输出 n 件商品排序后的情况。

【输入】
第一行一个正整数 n,表示有 n 件商品,1≤n≤100000。
接下来的 n 行,每行一个整数,表示第 i 件商品的价格。

【输出】
n 行,每行输出一个整数。

【输入样例】
5
1
8
1
2
2

【输出样例】
1
1
2
2
8

此题的特点是数据太多,数据范围比较小

代码

方法一

运用了桶排序按照数据的取值范围(范围小,数据多)

#include<iostream>

using namespace std;

int num[1001],number,n,i,j;

int main() {

cin>>n;

for(i=1;i<=n;i++) {

cin>>number;

num[number]++; //记录整数number出现的次数

}

for(i=0;i<1001;i++) {

for(j=1;j<=num[i];j++)

cout<<i<<endl;

}

return 0; }

方法二

#include<cstdio>

using namespace std;

int a[1001],t,n,i,j;

int main() {

scanf("%d",&n);

for(i=1;i<=n;i++) {

scanf("%d",&t);

a[t]++;

}

for(i=0;i<1001;i++) {

for(j=1;j<=a[i];j++)

printf("%d\n",i);

}

return 0; }

第七课 二维数组的定义和操作

二维数组是为了解决一维数组遗留下来的问题

在二维数组中每一个元素就又是一个一维数组,在定义二维数组中不可以忽略掉第二维大小

①定义二维数组的一般格式为:

类型标识符    数组名[常量表达式1][常量表达式2]

一般可以把二维数组看成一张表格或一个矩阵

②在定义二维数组定义的同时可以进行初始化赋值,既可以分行初始化,也可以部分行初始化

③二维数组的储存方式是行优先的连续储存

引用二维数组的一个元素格式为

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

例如:

cin>>h[3][1];h[3][1]=h[3][1]*2;cout<<h[3][1];

第八课  二维数组应用举例

 

【题目描述】
输入一个正整数 n,输出 n 行的数字三角形。其中,第 1 行为数字 1,第 2 行为数字 23,第 3行为数字 456,第 4 行为数字 7890,第 5 行为数字 12345,…

【输入】
一行一个正整数 n,1≤n≤100。

【输出】
n 行的数字三角形。

【输入样例】
4

【输出样例】
1
23
456
7890

代码

#include<cstdio>

using namespace std;

int a,b=1;

int main() {

scanf("%d",&a);

for(int i=1;i<=a;i++) {

for(int j=1;j<=i;j++) {

printf("%d",b%10);

b++;

}

printf("\n");

}

return 0;

}

它的具体实现采用了赋值法,对这个题分析可以发现,

对于右上角的每一个元素a[i][i]分析发现a[i][j]=j-i+1

第九课 数字方阵

主要是为了更好的解决数字方阵的问题,体会数组下标的运算。

第十课 字符数组

一个字符数组只能存一个或一段文字。用二维的字符数组可以存若干个

char str[10]只能存一段文字,此文字有10个字符

char str[10][100]10行每行不超过100个字符

不加下标表示读一段文字,加下标表示只读一个元素

空格作间隔符,读不进空格

如:

输入“hello world!”

输出为:

hello

world!

因为s1输出hello,s2输出了world

因为空格做了间隔符

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值