2019-12-24

我的梦境 提交于 2019-12-25 01:19:33
                         数组收获与感悟

定义:数组是有序的并且具有相同类型的数据的集合。
一维数组
1、一般形式:类型说明符 数组名[常量表达式];例如: int a[10]; 元素为a[0]----a[9].
2、常量表达式中不允许包含变量,可以包含常量或符号常量。
3、数组元素下标可以是任何整型常量、整型变量或任何整型表达式。
4、可以对数组元素赋值,数组元素也可以参与运算,与简单变量一样使用。
5、使用数值型数组时,不可以一次引用整个数组,只能逐个引用元素。
6、需要整体赋值时只可以在定义的同时整体赋值。如
int a[10]={0,1,2,3,4,5,6,7,8,9};正确。
int a[10]; a[10]={0,1,2,3,4,5,6,7,8,9};错误。
7、可以只给一部分元素赋值。例如:
int a[10]={5,8,7,6};后面没有赋值的元素值默认为0。
8、对全部数组元素赋值时可以不指定数组长度,例如:
int a[10]={0,1,2,3,4,5,6,7,8,9};可以写成 int a[]={0,1,2,3,4,5,6,7,8,9};
但是,既不赋初值,也不指定长度是错误的。例如:int a[];错误。
一维数组的应用:
1.幸运数的划分
问题描述:
判断一个正整数n是否能被一个“幸运数”整除。幸运数是指一个只包含4或7的正整数,如7,47,477等都是幸运数,17,42则不是幸运数。
输入格式:
一行一个正整数n,1<=n<=1000。
输出格式:
一行一个字符串,如果能被幸运数整除输出“YES”,否则输出“NO”.
#include
using namespace std;
int main()
{
int n,flag=0;
cin>>n;
for(int i=1;i<=n;i++)
{
int j=i;
//do-while循环判断当前的j是不是一个幸运数
do
{
if(j%104||j%107)
flag=1;
else
{
flag=0;
break;
}
j/=10;
}while(j);
//if语句判断输入的数字n能否被当前的幸运数整除,如果能整除,输出YES,退出程序
if(flag1&&n%i0)
{
cout<<“YES”<<endl;
return 0;
}
}
if(flag==0)
cout<<“NO”<<endl;
return 0;
}
2.校门外的树
描述
某校大门外长度为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
using namespace std;
int main()
{
int L,M;
int num[10001]={0};
int n=0;
cin>>L>>M;
int a[100],b[100];
for(int i=0;i<M;i++)
{
cin>>a[i]>>b[i];
for(int j=a[i];j<=b[i];j++)
{
num[j]=1;
}
}
for(int i=0;i<=L;i++)
{
if(num[i]==0)//判断是否重合
{
n++;
}
}
cout<<n;
return 0;
}
二维数组
1、一般形式:类型说明符 数组名[常量表达式1][常量表达式2];例如:
int a[3][4];可以看成是包含3个一维数组,每个一维数组里包含4个元素。一共34=12个元素。
所有元素为 a[0][0],a[0][1],a[0][2],a[0][3]
a[1][0],a[1][1],a[1][2],a[1][3]
a[2][0],a[2][1],a[2][2],a[2][3]
2、与一维数组一样元素下标可以是是任何整型常量、整型变量或任何整型表达式。
3、需要整体赋值时只可以在定义的同时整体赋值。例如:
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};正确。
int a[3][4]; a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};错误。
4、可以把所有数据写在一个花括号内。例如:
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};正确。
5、可以只对部分元素赋值。例如:
int a[3][4]={{1},{5},{9}};其余未赋值的元素默认为0。
int a[3][4]={{1},{5,6}};可以看成是int a[3][4]={{1,0,0,0},{5,6,0,0},{0,0,0,0}};
6、对全部数组元素赋值时可以省略第一维长度,第二维不可以省略。例如:
a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
可以写成a[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
或者a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
应用:
描述
用数字1,2,3,4,…,n
n这n2个数蛇形填充规模为n*n的方阵。

蛇形填充方法为:

对于每一条左下-右上的斜线,从左上到右下依次编号1,2,…,2n-1;按编号从小到大的顺序,将数字从小到大填入各条斜线,其中编号为奇数的从左下向右上填写,编号为偶数的从右上到左下填写。

比如n=4时,方阵填充为如下形式:

1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
输入
输入一个不大于10的正整数n,表示方阵的行数。
输出
输出该方阵,相邻两个元素之间用单个空格间隔。
样例输入
4
样例输出
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
源代码
#include
int t=1,a[21][21];
int main(){
int n,i,j;
scanf("%d",&n);
i=j=1;
while(t<=n*n){
while(1){
if(i<1||j>n){
i++;j–;//保证对角线元素依次相加
break;
}
else{
a[i][j]=t;t++;i–;j++;
}
}
if(jn) i++;
else if(i
1) j++;
while(1){
if(i>n||j<1){
j++;i–;break;
}
else{
a[i][j]=t;t++;i++;j–;
}
}
if(in) j++;
else if(j
1) i++;
}
for(i=1;i<=n;i++){
for(j=1;j<n;j++)
printf("%d “,a[i][j]);
printf(”%d\n",a[i][n]);
}
}
3.有趣的跳跃
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
一个长度为n(n>0)的序列中存在“有趣的跳跃”当前仅当相邻元素的差的绝对值经过排序后正好是从1到(n-1)。例如,1 4 2 3存在“有趣的跳跃”,因为差的绝对值分别为3,2,1。当然,任何只包含单个元素的序列一定存在“有趣的跳跃”。你需要写一个程序判定给定序列是否存在“有趣的跳跃”。

输入
一行,第一个数是n(0 < n < 3000),为序列长度,接下来有n个整数,依次为序列中各元素,各元素的绝对值均不超过1,000,000,000。
输出
一行,若该序列存在“有趣的跳跃”,输出"Jolly",否则输出"Not jolly"。
样例输入
4 1 4 2 3
样例输出
Jolly
源代码:
#include<stdio.h>
#include<stdlib.h>
#define max 3001 //序列长度max
int main()
{
int a[max],b[max]; //a数组用来接收输入的值,数组用来对输入的值进行操作
int n,temp;
scanf("%d",&n);
int i,j;
if(n==1){ //如果只有一个数,则直接输出
printf(“Jolly”);
return 0;
}
for(i=0;i<n;i++)
scanf("%d", &a[i]);
for(i=0;i<n-1;i++){ //b数组等于a数组相邻值之差的绝对值
b[i]=abs(a[i]-a[i+1]);
}
for(i=0;i<n-1;i++) //对b数组的元素进行排序
for(j=i;j<n-1;j++)
if(b[i]>b[j]){
temp=b[i];
b[i]=b[j];
b[j]=temp;
}
for(i=0;i<n-2;i++){ //判断排好序的数组是不是等差数列
if(b[i+1]-b[i]1)
continue;
else
break;
}
if(i
n-2) //为什么i要等于n-2呢?是不是为n的排序后有n-12个值,因为i是从0开始的嘛
printf(“Jolly”);

else
    printf("Not jolly");
return 0;

}
字符数组
1、定义:char a[10];字符数组a长度为10。每个元素只能存放一个字符。例如:
a[0]=‘h’;a[1]=‘a’;a[2]=‘p’;……
2、初始化:
char a[]={‘h’,‘a’,‘p’,‘p’,‘y’};
char a[]=“happy”;
char a[]={“happy”}; 注意,因为字符串结尾自动加’\0’,所以char a[]=“happy”;长度为6,不是5。
3、C语言中没有字符串变量,字符串的输入、存储、处理和输出等必须通过字符数组实现。
4、字符串的输入。
scanf();可以用%C逐个字符输入比如char a[6];for(i=0;i<6;i++) scanf("%c",&a[i]);
可以用%S以字符串的形式输入,比如char a[6];scanf("%s",a);注意,a前不用加&,因为a是数组名,已经代表了数组首地址。
注意:以%S输入时,以第一个非空白字符开始,终止于第一个空白字符。比如:输入How are you时。只输出How.
gets();作用为输入一个字符串。与scanf();功能一致,但空格和回车都存放在数组中,最后自动加入‘\0’.不会出现上面输出不全的情况。
调用方式为:gets(数组名);需要包含头文件“stdio.h”.
例:1.char letter[5]={‘a’,‘e’,‘i’,‘o’,‘u’}
2.对于数组a[10]:用getchar()赋值:
for(i=0;i<10;i++)
a[i]=getchar();
用scanf()赋值:
for(i=0;i<10;i++)
scanf("%c",&a[i]);(逐个元素读入)
scanf("%s",a);(整个元素读入)
5、字符串的输出。
printf();可以使用%C逐个字符输出,比如:char a[6];for(i=0;i<6;i++) printf("%c",a[i]);
可以用%S以字符串的形式输出,比如char a[6];printf("%s",a);
puts();输出一个字符串,结尾自动换行。
调用形式:puts(字符数组名或字符串常量);需包含头文件“stdio.h”
例:对于数组a[10]:用putchar()赋值:
for(i=0;i<10;i++)
a[i]=putchar();
用printf()赋值:
for(i=0;i<10;i++)
printf("%c",a[i]);(逐个元素输出)
printf("%s",a);(输出整个数组)
常用字符串处理函数(以下函数需要头文件“string.h”)
1、strlen()作用是测试字符串长度。这里不包括‘\0’.使用形式strlen(数组名或字符串常量)
2、strcat()作用是连接两个字符串。调用方式strcat(字符数组1名,字符数组2名);合并后的字符串存放在字符数组1中。
3、strcmp()比较两个字符串是否相等。调用方式strcmp(字符串1,字符串2);相等时值为0。1>2时为正数。1<2时为负数。
4、strcpy()复制字符串。调用方式strcpy(字符数组1,字符串2);2的内容复制到1中。1只能是字符数组名。
应用举例:
1.扫雷游戏地雷数计算
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
扫雷游戏是一款十分经典的单机小游戏。它的精髓在于,通过已翻开格子所提示的周围格地雷数,来判断未翻开格子里是否是地雷。

现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格的周围格地雷数。

注:每个格子周围格有八个:上、下、左、右、左上、右上、左下、右下。

输入
第一行包含两个整数n和m,分别表示雷区的行数和列数。1 <= n <= 100, 1 <= m <= 100。
接下来n行,每行m个字符,‘’表示相应格子中是地雷,‘?’表示相应格子中无地雷。字符之间无任何分隔符。
输出
n行,每行m个字符,描述整个雷区。若相应格中是地雷,则用‘
’表示,否则用相应的周围格地雷数表示。字符之间无任何分隔符。
样例输入
3 3
??
???
?
?
样例输出
10
221
1
1
源代码
#include
#include
using namespace std;
int dx[8]={-1,-1,0,1,1,1,0,-1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
int main(){
char mine[101][101];
int sum[101][101]={0};
int n,m,i,j,ni,nj,k,ans=0;
scanf("%d %d\n",&n,&m);
for(i=0;i<n;i++){
for(j=0;j<m;j++)
mine[i][j]=getchar();
getchar();
}
for(i=0;i<n;i++)
for(j=0;j<m;j++)
if(mine[i][j]’?’)
for(k=0;k<8;k++){
ni=i+dx[k];
nj=j+dy[k];
if(ni>=0&&ni<n&&nj>=0&&nj<m&&mine[ni][nj]
’)
sum[i][j]++;
}
for(i=0;i<n;i++){
for(j=0;j<m;j++)
if(mine[i][j]==’
’)putchar(’*’);
else putchar(sum[i][j]+48);
putchar(’\n’);
}
return 0;
}
写在最后:数组是一个非常有用的工具,他的使用通常与循环结构相结合,一二维数组的不同应用也是C语言中的亮点,字符串hash真的很难,感觉有想法但是学的东西太少难以下笔去做。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!