2019-12-24

  第五单元数组

知识点总结
第一课 一维数组的定义(理解数组的含义,掌握一维数组的元素引用和物理存储方式。)
(1)一维数组的定义格式:类型标识符 数组名[常量表达式];其中,类型标识符可以是任何基本数据类型,也可以是结构体等构造类型,相同类型的数组可以一起定义。数组名必须是合法的标识符。常量表达式的值即为数组元素的个数。例:int h[50];就表示定义一个一维数组h,共有50个元素,他们的编号从零开始到49,每个元素都是int类型。注意:int h[50];中取不到h[50]最多到49,数组下标从零开始。应用时,要注意下标是否越界,除数不能为零。
(2)一维数组的元素引用数组定义好后,就可以“引用”数组中的任意一个元素。引用格式为“数组名[下标]”,如h[5]、h[i2+1]等。其中,下标只能为整型常量或整型表达式,值必须在数组定义的下标范围内,否则会出现“下标越界错误”。需要注意的是,不能一次引用整个数组,只能逐个引用数组的单个元素。例如,对于一个数组a来说,语句“cout<<a;”是不合法的。
(3)一维数组的存储结构数组在计算机内存单元中是连续存储的。程序一旦执行到数组的定义语句,就会开辟出若干字节的内存单元。例,对于以定义的数组“int h[50];”,假设系统给它分配的内存单元地址从1000开始,则“1000”就称为该数组在内存中的“首地址”,由于每个元素都是int类型,占用四个字节。可以算出以上h数组共占用200个字节的空间。也就是说,整个数组所占的内存大小等于数组元素类型的大小乘以数组元素的个数。同时,根据数组在内存单元中的首地址和数组类型可以计算出该数组中任意第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++里,还提供了两个函数给数组“整体”赋值:
memset函数,是给数组按字节进行赋值,一般用在char型数组中,如果是int类型的数组,一般赋值为0和-1,使用前需要包含头文件#include。
fill函数,是给数组“按元素”进行赋值,可以是整个数组,也可以是部分连续元素,可以赋任何值,使用前需要包含头文件#include。注意区分两种函数的用法。
第三课 一维数组的插入删除(学会操作,应用解决问题。)在实际应用中,经常需要在数组中插入一个元素,或者删除数组中的某一个元素,称为数组的插入操作或者删除操作。插入一个元素,需要先找到插入的位置,将这个元素及其之后的所有元素依次往后移一位,再将给定的元素插入到该位置。删除某一个元素,也需要先找到删除的位置,将该位置及其之后的所有元素依次向前移一位,覆盖原来位置上的元素。插入或者删除一个区间,连续若干个数,只要重复以上单个元素的操作即可,另外,插入操作需要注意把数组下标定义的足够大。
例题:1 插队问题
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]);
retuen 0;这个程序利用一维数组的插入删除,把N个人进行排队。用q[i]表示排在第i个位置上的人。定义数组时多定义一个位置,然后重复执行:q[i+1]=q[i],其中,i从nx。最后再执行q[x]=q[n+1],输出q[1]q[n]。
第四课 一维数组的查找统计(学会在一维数组中进行顺序查找和二分查找。熟练应用。)一维数组的查找操作就是在一维数组中查找有没有某个元素,它的值等于指定的值,查找操作的结果可能是一个没找到,找到到一个或者找到很多个。常见的查找算法,有顺序查找和二分查找。顺序查找,就是按照从前往后的顺序,将数组中的元素依次与要查找的数进行比较,如果数组中的元素是有序的,递增或者递减也可以采用二分查找。二分查找又称折半查找,其优点是比较次数少,查找速度快。假设数组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”);
有时需要注意:变量应定义在循环内还是循环外,区别不同。
第五课 一维数组的元素排序(掌握选择排序,冒泡排序和插入排序。应用)“排序”就是按照某个关键字的大小,将若干对象从小到大,或者从大到小进行重新排列,关键字是对象的某一个属性,它可以是任何基本数据类型,甚至结构体等。算法1,选择排序选择排序的基本思想是:每一趟从待排序的数据中,通过“打擂台”比较选出最小元素,放在这些数据的最前面。这样,第一趟,把n个数中最小的放在第一个位置,第二趟把剩余的n-1个数中,最小的放在第二个位置,第三趟把剩余的n-2个数中,最小的放在第三个位置……第n-1趟把剩下的2个数中最小的放在第n-1个位置,剩下的最后一个数,一定最大,自然落在了第n个位置。
算法2 ,冒泡排序冒泡排序的基本思想是:从第一个数开始,依次不断比较相邻的两个元素,如果“逆序”交换。这样,一趟排序结束后,最大的元素就放在了第n个位置了。对于冒泡排序,还可以做些算法“优化”。如果一趟排序下来,都没有任何“逆序”数对,即没有发生“交换”操作,则说明已经排好序了。此时,就可以立刻退出循环。
算法3,插入排序插入排序的基本思想是:把所有待排序元素分成前后两段,前一段是已经排好序的,后一段是待排序的。每一趟都是把后一段的第一个数“插入”到前一段的某一个位置,保证前一段仍然是有序的。开始时,第1个数作为前一段肯定是有序的;第一趟,把第2个数插入进去,保证前2个数有序;第二趟,把第3个数插入进去,保证前3个数有序;……第n-1趟,把第n个数插入进去,保证n个数都有序。
第六课 一维数组的应用举例(学会跟踪数组元素调试程序,综合应用。)桶排序:
{int n,i,j,number,num[1001];
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;//输出num[i]次i
return 0;
}
算法一:穷举法 穷举商品编号2~n,,判断每个编号是否为素数。这种方法效率不高,一旦n过大,程序就会超时。
算法二:筛选法 筛选法又称筛法,相比穷举法,筛法的效率更高。第七课 二维数组的定义和操作(理解二维数组及其存储结构,掌握二维数组的初始化、输入输出操作。)
(1)二维数组的定义和初始化一般格式:类型标识符 数组名[常量表达式1][常量表达式2];常量表达式1的值表示第一维大小,常量表达式2的值表示第二维大小,常量表达式1和常量表达式2的乘积就是二维数组元素的个数。二维数组更多是来表示矩阵,解决矩阵的变化问题。(2)二维数组的存储及元素引用二维数组的存储方式是“行优先”的连续存储,先逐个存储第0行上的所有元素,再逐个存储第1行上的所有元素,依次类推。(3)二维数组的输入输出针对每一个元素进行,结合两个维度的下标变化,用循环嵌套实现。第八课 二维数组应用举例例1:杨辉三角形,采用“递推法”,逐行逐列给每个数组元素赋值。
int n,i,j,tri[21][21];
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];
}
第九课 数字方阵数字
方阵就是一个行列数相等的二维数组,其中的每个元素都是数字。解决方阵问题的两种方法:1 解析法 找出每一个方阵元素f[i][j]与i、j和数组规模n的通项公式,然后直接用两重循环给数组元素赋值,相对比较容易,一般用在初始化等场合。2 模拟法 把数字方阵看成一个动态的填数过程,把n*n个数依次填入数组中,每填好一个数,就定位好下一个球数的位置i和j。第十课 字符数组如果数组中的每一个元素都是一个字符,这样的数组称为“字符数组”。有时,把一维字符数组又称为“字符串”。存储:对于字符数组的定义在计算机内部存储时,字符串的末尾都会有一个空字符’\0’。
赋值:
用字符常量逐个初始化:char letter[5]={‘a’,‘e’,‘i’,‘o’,‘u’};
用赋值语句逐个元素赋值:letter[0]=‘a’,…
用scanf读入整个数组:scanf("%s",letter);
用scanf逐个元素读入:scanf("%c",&letter[0]);…
用cin输入整个数组:cin>>letter;用cin逐个元素输入:cin>>letter[0];…
用gets读入整个数组:gets(letter); 可以读入字符间的空格。
用getchar逐个读入:letter[0]=getchar();…
字符数组的输出:
用cout输出整个数组:cout<<letter;
用cout逐个元素输出:cout<<letter[0];…
用printf输出整个数组:printf("%s",letter);
用printf逐个元素输出:printf("%c",letter[0]);…
用puts输出整个数组:puts(letter);
用putchar逐个元素输出:putchar(letter[0]);…需要注意,在用scanf的%格式或gets读入字符串时,会在字符串末尾自动添加一个空字符’\0’。而使用getchar等方法读入字符串时,则要在字符串后手工加’\0’。
学习收获
第五单元,主要讲述了数组的使用,包含一维数组和二维数组。数组的使用方便了相同变量的定义,使程序更简洁。对于一维数组,要注意排序问题,数组中元素的取用,判断,比较。而二维数组要注意矩阵问题,方块阵问题,注意行列关系。在做练习题时,稍有不注意,容易出现的问题主要为:1 数组下标越界,数组元素定义时,是从零开始,而最后一位是取不到的。所以在定义下标时要适量大一点。2 数组长度太长,在比较或判断时出现超时现象。在解决一些实际问题时,要注意合理编写程序,考虑超时问题,调整运行的顺序可能就不超时了。3 二维数组的输入是“行优先”,在输入某个矩阵时一定要注意行列数。4 矩阵计算问题要避免重复角上的元素。5 注意字符数组输入时的空格问题。
学习感悟
我在学习第五单元时,明显体会到,程序变长了,题目复杂了,很多问题要解决需要更多的循环,判断。是在学习新的知识同时,加强了旧知识的应用,这一综合,让我在做J题的时候出现了许多小问题,稍有不慎某个for语句或者if语句就会出错,再多重复合下,经常会使程序乱循环,得出错误答案。这些问题的出现,也让我知道了前面知识的欠缺,新知识的注意问题,让我在复习时有所侧重,注意。做完数组的20个题后,也有很多收获,基本了解了什么问题下应用什么数组,数组经常出现的问题,在综合练习题中再继续练习,做到灵活应用。

在Oracle数据库中可以借助PL/SQL结合循环与日期时间函数实现这一需求。下面是一个具体的解决方案,通过计算两个给定的时间段,并按照每个小时分割输出结果。 以下是完整的代码示例及解释: ```plsql DECLARE start_time DATE := TO_DATE('2019-01-09 11:00', 'YYYY-MM-DD HH24:MI'); -- 起始时间 end_time DATE := TO_DATE('2019-01-09 12:30', 'YYYY-MM-DD HH24:MI'); -- 结束时间 current_time DATE := start_time; -- 初始化当前时间为起始时间 next_hour DATE; interval_minutes NUMBER; BEGIN WHILE current_time < end_time LOOP IF (current_time + INTERVAL '1' HOUR) <= end_time THEN next_hour := current_time + INTERVAL '1' HOUR; -- 如果下一个整点还在结束时间前,则取下一个整点 ELSE next_hour := end_time; -- 否则将next_hour设置为end_time END IF; interval_minutes := TRUNC((next_hour - current_time) * 24 * 60); -- 计算间隔分钟数 DBMS_OUTPUT.PUT_LINE(TO_CHAR(current_time, 'YYYY-MM-DD HH24:MI') || ' ' || TO_CHAR(next_hour, 'YYYY-MM-DD HH24:MI') || ' ' || interval_minutes || ' 分钟'); current_time := NEXT_HOUR; -- 将current_time更新至下一时间段起点 END LOOP; END; ``` 该脚本实现了以下功能: 1. 定义了开始时间和结束时间; 2. 使用`WHILE`循环逐小时处理区间; 3. 判断每一区间的终点是下一个整点还是最终时间; 4. 输出每个区间对应的起止时间和所包含的分钟数; 运行上述脚本会得到类似如下的输出(取决于实际数据): ``` 2019-01-09 11:00 2019-01-09 12:00 60 分钟 2019-01-09 12:00 2019-01-09 12:30 30 分钟 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值