第1课 一维数组的定义
数组: 为了表示同一批对象的统一属性。
定义格式: 类型标识符 数组名[常量表达式];
(类型标识符可以为任何基本数据类型或结构体;数组名必须是合法的标识符;常量表达式的值为数组元素个数。)
int d[50],g[100];
int a[5*10];
#define N 50
int b[N];
引用数组的格式: 数组名[下标]
(下标只能为整型常量或整型表达式,值必须在数组定义的下标范围内,不能一次引用整个数组,只能逐个引用数组的单个元素。)
第2课 一维数组的输入与输出
利用循环语句逐个输出数组元素,例:
int h[100];
for(i=0;i<100;i++) cout<<h[i];
数组赋值:
键盘读入
int h[100];
fot(i=0;i<100;i++) cin>>h[i];
- 直接赋值
int h[100],a[20]; for(i=0;i<100;i++) h[i]=0; for(i=0;i<20;i++) a[i]=i*2+1;
- “整体”赋值
①memset函数:“按字节”赋值,一般用于char型数组,若是int类型的数组,一般赋值为0或1。使用前包含头文件#include<cstring>。
②fill函数:“按元素”赋值,可以是整个数组或部分连续元素,可以赋任何值。需包含头文件#include<algorithm>。
可在定义数组的同时,给所有或部分元素赋值,例:
int a[10]={0,1,2,3,4,5,6,7,8,9};
int a[10]={0,1,2,3,4}; //部分赋初值,后面的元素自动初始化为0
int a[]={1,2,3,4,5};//不定义数组长度,直接根据赋值个数定
经典例题:走楼梯
【问题分析】
假设f(i)表示走到第i级楼梯的走法,则走到第i(i>2)级楼梯有两种可能:一种是从第i-1级楼梯走过来;另一种是从第i-2级楼梯走过来。根据加法原理,f(i)=f(i-1)+(i-2),边界条件为:f(1)=1,f(2)=2。具体实现时,定义一维数组f,用赋值语句从前往后对数组的每一个元素逐个赋值。本质上,f(i)构成了斐波那契数列。
#include<cstdio>
using namespace std;
int main()
{
int n,i,f[31];
scanf("%d",&n);
f[1]=1;f[2]=2;
for (i=3;i<=n;i++)
f[i]=f[i-1]+f[i-2];
for (i=1;i<n;i++)
printf("%d",f[i]);
printf("%d\n",f[n]);
return 0;
}
第3课 一维数组的插入删除
插入操作时应注意将数组定义的足够大。
例:插队问题
【问题分析】
N个人的排队情况可以用数组q表示,q[i]表示排在第i个位置上的人。定义数组时多定义一个位置,然后重复执行:q[i+1]=q[i],其中i从n-x。最后再执行q[x]=q[n+1],输出q[1]~q[n]。
#include<cstdio>
using namespace std;
int main()
{
int n,i,x,q[102];
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&q[i]);
scanf("%d",&x);
for (i=n;i>=x;i--)
q[i+1]=q[i];
q[x]=q[n+1];
for (i=1;i<n;i++)
printf("%d\n",q[n]);
return 0;
}
第4课 一维数组的查找统计
常见查找算法:“顺序”查找和“二分”查找。
顺序查找:按从前到后的顺序,将数组中的元素依次与要查找的数x进行比较。
二分查找:又叫“折半”查找,其优点是比较次数少,查找速度快。
假设数组a[n]是严格递增的,每个元素都是int型,现在要查找x这个元素,的二分查找的算法框架可以这样写:
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");
经典例题 比身高:
#include<cstdio>
using namespace std;
int h[1001],n,i,j,ans,t1,t2;
int main()
{
scanf("%d",&n);
for (i = 1;i <= n;i++)
scanf("%d",&h[i]);
for (i=1;i<=n;i++)
{
t1=t2;
for (j=1;j<i;j++)
if(h[j]>h[i])
t1++;//排在他前面且比他高的人数
for(j = i+1;j<=n;j++)
if(h[j]>h[i])
t2++;//排在他后面且比他高的人数
if(t1 == t2)
ans++;
}
printf("%d\n",ans);
return 0;
}
全局统计可以在定义变量时赋初值,局部统计在统计开始之前赋值。
第5课 一维数组的元素排序
最基本的三种排序算法:选择排序、冒泡排序和插入排序。
经典例题 站队:
选择排序
#include<cstdio>
using namespace std;
int main()
{
int n,j,i,k,temp,h[101];
cin>>n;
for (i=1;i<=n;i++)
cin>>h[i];
for (i=1;i<=n;i++)
{
k=i;
for (j=1+i;j<=n;j++)
if(h[j]<h[k])
k=i;//在i~n之间最小元素
temp=h[i];
h[i]=h[k];
h[k]=temp;//将i~n之间的最小元素放到第i个位置
}
for (i=1;i<n;i++)
cout<<h[i]<<" ";
cout<<h[n]<<endl;
return 0;
}
冒泡排序
#include<cstdio>
using namespace std;
int main()
{
int n,i,j,temp,h[101];
cin>>n;
for (i=1;i<=n;i++)
cin>>h[i];
for (i=1;i<n;i++)
{
bool flag = true;
for (j = 1;j<=n;j++)
if(h[j]>h[j+1])
{
temp=h[j];
h[j]=h[j+1];
h[j+1]=temp;
flag = flase;
}
if(flag) break;
}
for (i=1;i<n;i++)
cout<<h[i]<<" ";
cout<<h[n]<<endl;
return 0;
}
插入排序
#incldue<cstdio>
using namespace std;
int main()
{
int n,i,j,k,temp,h[101];
cin>>n;
for (i=1;i<=n;i++)
cin>>h[i];
for (i=2;i<=n;i++)
{
temp=h[i];
k=1;
while (h[k]<=temp&&k<i)
k++;
for (j=i-1;j>=k;j--)
h[j+1]=h[j];
h[k]=temp;
}
for (i=1;i<n;i++)
cout << h[i] <<" ";
cout << h[n] << endl;
return 0;
}
第6课 一维数组的应用举例
经典例题 商品排序:
【问题分析】
分析数据发现一个重要特征:数据虽然很多,但是数据范围比较小。这种情况下,可以使用另外一种排序算法——桶排序,定义一个int型数组 num[1001],num[x]记录整数x出现的次数,初始化都为0,没读到一个数x,就执行num[x]=num[x]+1。输出时,从0~1000穷举x,每个x输出num[x]次。
#include<cstdio>
using namespace std;
int n,j,i,number,num[1001];
int main()
{
cin>>n;
for (i=1;i<=n;i++)
{
cin>> number;
num[number]++;//记录整数number出现的次数
}
for (i=0;i<1001;i++)
}
素数大酬宾(筛选法):
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int n,j,i;
bool p[100001];
for (i=0;i<=100000;i++)
p[i] = true;
p[1] = flase;
cin>>n;
cout<<2;
for (i=2;i<=sqrt(n);i++)
if(p[i])
for (j=2;i*j<=n;j++)
p[i*j]=flase;
for (i=3;i<=n;i++)
if(p[i])
cout << " " << i;
cout << endl;
return 0;
}
第7课 二维数组的定义和操作
格式:类型标识符 数组名[常量表达式1][常量表达式2];
(常量表达式1的值表示第一维大小,常量表达式2的值表示第二维大小,二者乘积就是二维数组的元素个数。)
例 回型方阵:
#include<iostream>
using namespace std;
int n,j,i,k,a[10][10];
int main()
{
cin>>n;
for (k=1;k<=(n+1)/2;k++)
for(i=k;i<=n+1-k;i++)
for(j=k;j<=n+1-k;j++)
a[i][j]=k;
for (i=1;i<=n;i++)
{
for(j=1;j<n;j++)
cout << a[i][j] <<" ";
cout << a[i][n] << endl;
}
return 0;
}
第8课 二维数组应用举例
杨辉三角形:
【问题分析】
定义一个二维数组tri存储杨辉三角形(其实只用到二维数组的左下部分)。对于第i行(1≤i≤n),共有i个数,其中第一个数和最后一个数都是1,其他数tri[i][j]=tri[i-1][j-1]+tri[i-1][j]。具体实现,采用“”递推法“,逐行逐列给给每个元素赋值。
#include<iostream>
#include<cstring>
#include<iomanip>
using namespace std;
int n,j,i,tri[21][21];
int main()
{
cin>>n;
for(i=1;i<=n;i++)
{
tri[i][1]=1;
tri[i][i]=1;
for(j=2;j<i;j++)
tri[i][j] = tri[i+1][j-1] + tri[i-1][j];
}
for(i=1;i<=n;i++)
{
for(j=1;j<i;j++)
cout << setw(6) << tri[i][j] << " ";
cout << setw(6) << tri[i][i] <<endl;
}
return 0;
}
第9课 数字方针
例 蛇形方阵:
【问题分析】
可以把蛇形方阵看成一条一条的直线(从右上到左下的斜线),每条直线上的数的个数为:1,2,3,...,n-1,n,n-1,...,3,2,1。每条直线上的元素位置有一一个重要特点:行号和列号相加为定值,从2到2xno同时,还可以分析出对称性.以最中间的直线为界,左上角和右下角的两个区域里的所有数的位置都是对称的,满足a[i][j]+a[n+1-i][n+1-j]等于nxn+1。因此,只需要模拟填出前n条直线上的数字,另外n-1条的元素值直接通过对称性来赋值。
#include<iostream>
#include<iomanip>
#include<cstring>
using namespace std;
int main(){
int n,i,j,k,t=0,a[21][21];
cin>>n;
for(k=1;k<=n;k++)
if(k%2)
for(j=1;j<=k;j++){
i=k+1-j;
t++;a[i][j]=t;
a[n+1-i][n+1-j]=n*n+1-t;}
else
for(j=k;j>=1;j--){
i=k+1-j;
t++;
a[i][j]=t;
a[n+1-i][n+1-j]=n*n+1-t;}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++);
cout<<setw(5)<<a[i][j];
cout<<endl;}
return 0;
}
第10课 字符数组
如果数组中的每个元素都是一个字符,这样的数组称为字符数组有时,把一维字符数又称为“字符串”定义字符数组的方法与定义其他类型数组的方法类似。
给字符数赋值的方法很多,例如:
用字符常量逐个初始化:char letter[3]=[‘a’,‘e’,‘o’]
用赋值语句逐个元素值letter[o]=‘a’
例 数字和:
【问题分析】
由于n可能到200位,任何整数类型都是不可能存储的。因此定义一个一维字符数组读取存储这个超大数,然后把每个字符转换成数值累加求和。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char n[201];
int main()
{
int n,sum=0;
scanf("%s",&n);
for (i=0;i<strlen(n);i++)
sum=sum+n[i]-'0';//strlen(n)表示求字符串的长度
printf("%d\n",sum);
return 0;
}
心得:
理解了数组的含义,学会了一维数组的定义并掌握了一维数组的元素引用、物理存储方式、输入输出操作、元素插入和删除操作和在一维数组中进行元素查找,也可以用一维数组解决一些实际问题,学会了三种排序算法和跟踪数组元素调试程序。也学习了有关二维数组的基本操作,并综合应用二维数组的基本操作解决一些实际问题,通过数字方阵体会了数组的下标运算,掌握了字符数组的输入输出方法。本单元整体围绕数组进行详细的讲解,这种定义方法也简化了编程的整体结构,提高了编程效率,数组为我们的编程带来了便利,应好好利用。
定义下标时应注意下标的大小;注意引用数组元素时下标不能越界,下标编号都是从0开始的;引用整个数组时应通过循环语句进行逐一赋值。