第一课:一维数组的定义
数组就是按顺序排列的相同类型的变量。他们往往都是为了表示同一批对象的统一属性。
在C++中,使用一维数组时,一般是从0开始编号,h[i]就表示第i+1个数据,i称为下边变量。
一维数组的定义
格式:类型标识符 数组名 {常量表达式}
标识符可以是任何基础数据类型,也可以是结构体等构造类型,相同类型的数组可以一起定义。
批量数据如何一次性输入到一维数组:(1)键盘读入:int h[100];
for(i=0;i<100;i++) cin>>h[i];
(2)直接赋值: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;
C++里还提供了两个函数给数组整体赋值:(1)msmset函数是给数组"按字节"进行赋值,在int类型中一般赋值为0和-1,msmset(b,0sizeof(b))将b数组所有元素均赋值为0,需要头文件#include<cstring>。
(2)fill函数
fill函数是给数组"按元素"进行赋值,可以是整个数组,也可以是部分连续元素,可以赋任何值
fill(a,a+10,5)将a数组的前十个元素赋值为5,需要头文件#include<algorithm>
如何使两个数组的值相等:
方法1:b[0]=a[0];
b[1]=a[1];
b[2]=a[2];
.......
方法2:通过循环赋值
int i;
for(i=0;i<5;i++)
{b[i]=a[i]}
2一维数组的元素引用
1:引用格式为"属于名[下标]"
2:下标总能为整型常量或整型表达式
3:下标从零开始
4:不能一次引用整个数组只能逐个引用数组的单个元素
特别注意在定义数组下标是应该稍大点,防止下标越界。
定义数组时写在主函数外面能储存更大的字节(全局变量)
写在里面能存储的的字节比较小(局部变量)
int a[110];
int main(){
int x,n=0;
while(cin>>x)(不知道具体的x就这样输入,判断x是否符合要求
3:一维数组的存储结构
1:数组名本身是该数组的首地址
2:数组大小必须是值为正的常量,一但定义,不能改变大小
3:数组在计算机中是连续储存的
例题:走楼梯
问题描述:一个楼梯有n级,小苏同学从下往上走,一步可以跨一级,也可以跨两级。问:他走到第N级楼梯有多少种走法?
#include<iostream>
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;
}
判断一个正整数n是否能被一个 “幸运数”整除。幸运数是指一个只包含4 或7的正整数,如7、.47 .477等都是幸运数,17、42则不是幸运数。
[输人格式]
-行一个正 整数n, 1≤n≤000[输出格式]
-行一个字符串,如果能被幸运数整除输出“YES";否则,输出“NO”。[输人样例]47
(输出样例]YES
[问题分析]
分析发现,I 1000范围内的幸运数只有14个。于是,将这14个幸运数直接存储到一1组lucky中,再穷举判断其中有没有一个数能整除n。
include<iostream>
using namespace std;
int main(){
int n,lucky[14]={4,7,44,47,74,77,444,447,474,477,744,747,774,777};
scanf ("&d",&n) ;
bool flag = false;
for(int i = 0;i<14; i++)
if(n%lucky[i]== 0) flag = true;
if(flag) printf("YES\n");
else printf ("NO\n");
return 0;
}
第3课:一维数组的插入与删除
插入一个元素,需要先找到插入的位置(假设下标为x),将这个元素及其之后的所有元素依次后移一位(注意要从后往前操作),再将给定的元素插入(覆盖)到位置x
删除某一个元素,也需要先找到删除的位置(假设下标为x)将下标为x+1及其之后的所有元素依次向前移动一位
插入操作需要注意吧数组下标定义的足够大。
插队问题
例1插队问题
[问题描述]
有n个人(每个人有一个唯一的编号 ,用1~n之间的整数表示)在一个水龙头前排队准备接水,现在第n个人有特殊情况,经过协商,大家允许他插队到第x个位置。输出第n个人插队后的排队情况。
[输人格式 ]
第一行1个正整数n,表示有n个人,2<n≤100。
第二行包含n个正整数,之间用一个空格隔开,表示排在队伍中的第1~第n个人的编号。
第三行包含1个正整数x,表示第n个人插队的位置,1≤x<n
[输出格式]
一行包含n个正整数,之间用一一个空格隔开,表示第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",q[i]);
printf("&d\n" ,q[n]);
return 0;
}
删除元素
有n个人(每个人有一个唯的编号 ,用1~n之间的整数表示)在一一个水龙头前排队准备 水,现在第x个人有特殊情况离开了队伍,求第x个人离开队伍后的排队情况。
[输人格式]
第一行1个正整数n,表示有n个人,2<n≤100。
第二行包含n个正整数,之间用一个空 格隔开,表示排 在队伍中的第1个到第n个人的编号第三行包含1个正整数x,表示第x个人离开队伍,1≤x≤n。
(输出格式]
一行包含n-1 个正整数,之间用一个空格隔开表示第x个人离开队伍 后的排队情况
#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=x;i<n;i++) q[i] = q[i+1];
n--;
for(i=1;i< n;i++) printf("%d",q[i]);
printf("&d\n" ,q[n]);
return 0;
}
常见的查找算法有 “顺序”查找和“二分”查找。顺序查找就是按照从前往后的顺序将数组中的元素依次与要查我的数x进行比较。如果数组中的元素是有序的(递增或者递减)。也可以采用二分查找。二分查想又称“折半”查找,其优点是比较次数少、查找速度快。
公司聚餐年会为了活跃气氛,设置了摇奖环节,参加聚会的每位员工都有一张带有号码的抽奖券,现在主持人依次公布n个不同的获奖号码,小谢看着自己的抽奖券上的号码nmu,无比紧张,请编写一个程序,如果小谢过奖了,请输出他中的第几个号码,如果没有中奖,请输出0。
#include<cstdio>
using namespace std;
int main() {
int n,i,num, f,g[101] ;
scanf ("%d" ,&n) ;
for(i = 1; i <= n; i++) scanf("%d",&g[i] ) ;
scanf ("%d" , &num) ;
f=0;
for(i = 1; i<= n;i++)
if(g[i]==num){f=i;break}
printf("%d\n",f);
return 0;
}
#include<cstdio>
using namespace std;
int main() {
int n,i,win,f,left,right ,mid,g(101];
scanf ("%d", &n) ;
for(i=1; i<=n; i++)
scanf("%d" ,&g[i]);
scanf("%d" , &win) ;
f=0;
left = 1; right = n;
while(left <= right) (
mid = (left + right)/ 2;
if(g[mid] == win){f = mid; break; }
if(win < g[mid]) right = mid - 1;
if(g[mid] < win)left = mid + 1;
}
printf("%d\n",f);
return 0;
}
“排序”就是按照某个关键字的大小,将若干对象从小到大或者从大到小进行重新排列。关键字是对象的某一个属性,它可以是任何基本数据类型,甚至结构体等。
算法1选择排序
选择排序的基本思想是:每趟从待 排序的数据中,通过“打擂台”比较选出最小元素,放在这些数据的最前面。这样第一趟把n 个数中(第1个到第n个)最小的放在第一个位置,第二趟把剩余的n-1个数中(第2个到第n个)最小的放在第二个位置,第三趟把剩余的n-2个数中(第3个到第n个)最小的放在第三个位置,....第n-1 趟把剩下的2个数中(第n-1个到第n个)最小的放在第n-1个位置,剩下的最后一个数(第n个)一定最大,自然落在了第n个位置。
算法2冒 泡排序
冒泡排序的基本思想是:从第一个数开始,依次不断比较相邻的两个元素,如果“逆序”就交换。这样,一趟排序结束后,最大的元索就放在了第n个位置了。对于冒泡排序,还可以做些算法“优化”。如果一趟排序下来,都没有任何“逆序”数对,即没有发生“交换”操作,则说明已经排好序了。此时,就可以立刻退出循环。
算法3插人排序
插入排序的基本思想是;把所有待排序元素分成前后两段,前一段是已经非好序的,后一段是导排序的。每一趟都是把后一段的第一个数 “插人”到前一段的某一个位置,保证前一段仍然是有序的。开始时,第1个数作为前一段肯定是有序的;第一 -趟 ,把第2个数插入进去,保证前2个数有序;第二趟,把第3个数插入进去,保证前3个数有序....第n-1趟,把第n个数插人进去,保证n个数都有序
第六课,一维数组的应用举例
数据虽然很多,但是数据范围比较小。这种情况下,可以使用另外-一种排序算法桶排序。 定义一个int型数num[ 1001],num[x ]记录整数x出现的次数,初始化都为0,每读到一个数x,就执行num[x ]=num[x]+1。输出时,从0~1000穷举x,每个x输出num[x]次。
商品排序
某商场的仓库中有n件商品,每件商品的价格在0~1000之间(价格为0的商品为赠品)。现在商场经理要求将这n件商品按价格由低到高排序,请编程输出n件商品排序后的情况
#include<iostream>
using namespace sta;
int n, i, j,number,num[1001] ;
int main() {
cin>> n;
for(i=1;i<=n;i++){
cin >> number ;
num [ number]++;
for(i = 0; i < 1001; i++)
for(j=1;j<=num[i];j++)
cout<<i<<endl;
return 0;
}
算法1:穷举法
算法2:筛选法
例3素数大酬宾。
[问题描述]
某商场的仓库中有n种商品,每件商品按1-n依次编号。现在商场经理突发奇想决定将编号为素数(质数)的所有商品拿出来搞优惠酬宾活动。请编程帮助仓库管理员将编号为素数的商品选出来。
#include<iostream>
#include< cmath>
using namespace std;
int main() {
int n,i,j;
bool flag;
cin >> n;
cout << 2;
for(i = 3; i<=n;i++){
flag = true;
for(j=2;j<= sqrt(i); j++)
if(i%j==0){ flag= false;
break;
}
if(flag) cout<<" "<<i;
}
cout<<endl;
return 0;
穷举法
#include<iostream>
#include<cmath>
using namespace std;
int main() {
int n,i,j;
bool p[100001] ;
for(i = 0; i <= 100000; i++) p[i]= true;
p[1] = false;
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; 1<=n;1++)
if(p[i]) cout<<" "<<i;
cout << endl ;
return 0;
}
筛选法
第七课:二维数组的定义和操作
一维数组的每一个元素又是一个一维数组,这种数组称为二维数组。
格式为 类型标识符 数组名[常量表达式1][常量表达式2];
常量表达式1的值表示地一维的大小,常量表达式2表示第二维的大小,常量表达式1和常量表达式2的乘积就是二维数组的元素个数。
在二维数组定义的同时,可以进行初始化赋值。例如:
2日3列
int a[2][3] = {(1,2,3}, {4,5,6}};//分行初始化int a[2][3] = {1,2,3,4,5,6}; 1/不分行初始化
以上两种初始化都相当于下面6个语句:
a[0][0] = 1; a[0][1] = 2; a[0] [2] = 3 ;a[1][0]= 4; a[1][1] = 5; a[1] [2] = 6;
也可以给数组中的部分元素初始化。例如:
int a[2][3] = { {1,2}, {4}};
第一行只有2个初值,按顺序分别赋值给a[0][0]和:I[ 1 ][0],其他元素默认为0。
在定义二。维数组时,可以省略第一维的大小
2.二维数组的存储及元素引用
因为二维数组本质上是一维数组的每一个元素 又是一个, 维数组,而计算机内部存储-维数组采用的是连续存储单元。所以,二维数组的存储方式是行优先”的连续存储,先逐个存储第0行上的所有元素,再逐个存储第1行上的所有元素,依此类推。1
引用二维数组的某一个元素,格式为:不能整体引用
数组名I下标1]↑下标20]
二维数组的输入与输出
回形方阵
# include<iostream>
using namespace std;
int n,i,j,k,mi,ma,a[10] [10] ;
int main(){
cin>>n;
for(i = 1; i <= (n+1)/2; i++)
for(j = 1;j <= (n+1) /2; j++) f
a[i][j] = min(i,j) ;
a[i][n+1-j]=a[n+1-i][j]=a[n+1-i][n+1-j]=a[iJlj];
for(i = 1; i<= n; i++) (
for(j=1;j<=n-l;j++)(
cout << a[i] [j] <<"" ;
cout << a[i][n] «< endl;
return 0;
}
第十课:字符数组
也就是说,字符串的末尾都会有一个空字符'10'3给字符数组赋值的方法很多,例如:
用字符常量逐个初始化:char letter[ 5 ]={'a','e','','o','u'};用赋值语句逐个元素赋值:letter[ 0 ]='a';...
用scanf读人整个数组:aa(%s" ,ltrt?数组名不用scanf逐个元素读人:scanf("%c",&letter[ 0 ]);...
用cin输人整个数组:; cin1>> letter; 带用cin逐个元素输人cin>> letter[ 0];.. 内格做为问.
包书安格
用gets读人整个数组getstetter); 不做为号用getchar逐个读人:letter 0 J=getchan( ); ...
字符数组的输出方法也很多,例如:用cout输出整个数组:cout>> letter;
用cout逐个元素输出:cout>> letter[0];..用printf 输出整个数组:printf( "%s",ltter);
用printt 逐个元素输出:rinf("%c",ltter[ 0]);用puts输出整个数组:pustCetter):
用putchar逐个元素输出putcharCetter 0)]);
学习心得
最近学习了数组相关的知识。数组,其实就是一组具有相同类型变量的集合。数组包含数组名和数组元素。程序可以通过数组的下标实现对数组元素的访问。当变量数目很多时,再用以前的方法,即定义一个变量用一个变量,就很难解决问题,这时数组就可以很简单的代替多次定义的难题。