0.展示PTA总分
1.本章学习总结
1.1 学习内容总结
1.1.1一维数组
①一维数组的定义格式:类型名 数组名 [数组长度];
②一维数组的引用形式:数组名 [下标]
③下标的取值范围:[0,数组长度-1]
④只能引用单个的数组元素,不能一次引用整个数组
⑤引用数组元素时,方括号内是表达式,代表下标,也可以是变量,而定义数组时方括号内是常量表达式,可以包括常量和符号常量,但不能包含变量
⑥对数组元素赋初值格式:类型名 数组名 [数组长度] = {初值表};
可对全部元素赋值,如 int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
也可对部分元素赋值,如 int b[20] = {0,1};//表示对b数组的前两个元素赋初值
⑦静态储存的数组如果没有初始化,系统将自动给所有元素赋0
1.1.2二维数组
①数组的定义格式:类型名 数组名 [行长度][列长度];
②二维数组的引用形式:数组名 [行长度][列长度]
③二维数组先存放第0行的元素,再存放第1行的元素...每一行元素再按照列的顺序的存放
③二维数组的分行式赋初值格式:类型名 数组名 [行长度] [列长度] = {{初值表0},...,{初值表k},...};
可对全部元素赋值,如 int a[2][3] = { {1,2,3},{4,5,6},{7,8,9} };
也可对部分元素赋值,如 int b[4][3] = {{1,2,3},{},{4,5} };//表示对b数组的第0行和第2行的前两个元素赋初值
1.1.3一维字符数组
- 一维字符数组的定义、初始化和引用与其他类型的一维数组一样
1.1.4字符串
①字符串常量就是用一对双引号括起来的字符序列,即一串字符,如“happy”
②字符串有一个结束标志'\0',如“happy”由六个字符组成即'h','a','p','p','y','\0',前五个是字符串的有效字符,'\0'是字符串结束符
③将字符串存入字符数组时,由于'\0'的存在,数组的长度至少是字符串的有效长度+1
④字符串的存储——数组初始化
字符数组的初始化还可用字符串常量,如 static char s [6] = {"happy"};或 static char s [6] = "happy";
还可以采用赋值和输入的方法,如 static char s [6]; s[0] = 'a'; s[1] = '\0';
区分"a"和'a',"a"是字符串常量,包括'a'和'\0'两个字符,而'a'是字符常量,只有一个字符,可以赋给字符变量
所以 static char s [6]; s[0] = 'a'; s[1] = '\0';等价于 static char s [6] = “a”;
在程序中要将结束符'\0'存入字符数组,否则字符串就不能正常结束,影响后面操作
1.1.5在数组中查找数据
①遍历法,即挨个找,找到就输出该数在数组中的下标
void arrayFind(int a[MAX], int n, int number) //传入数组、数组长度和要找的数 { int i; for (i = 0; i < n; i++) { if (a[i] == number) { printf("%d\n", i); //找到元素,打印下标 } } return 0; }
②二分法,即将要找的数与数组的中间数比较,如果相同就输出中间数的下标,否则将要找的区间压缩
void arrayFind(int a[MAX], int n, int number) //传入数组、数组长度和要找的数 { int left = 0; int right = a[n]; int mid; while (left <= right) { mid = (left + right) / 2; { if (number == a[mid]) { printf("%d", mid); //找到元素,打印下标 return 0; } else if (number < a[mid]) { right = mid - 1; } else if (number > a[mid]) { left = mid + 1; } } } return 0; }
1.1.6在数组中插入数据
int main() { int i; int j; int a[MAX+1]; //先假定该数组已按从小到大排列,且该数组长度为插入后的长度 int number; 用循环给数组赋值 输入要插入的数 for(i=0;i<MAX;i++) { 找到比该数大的数组元素的下标 break; } for(j=MAX-1; j>=i; j--) { 将该下标(包括其本身)后面的元素下标加一 将该数插入该下标所在位置 } 输出插入后的数组 return 0; }
1.1.7删除数组中的数据
①一般法
int main() { int i; int j; int a[MAX]; int number; 用循环给数组赋值 输入要删除的数 for (i = 0; i <= MAX - 1; i++) { 找到要删除的数,记录下标 { for (j = i; j <= MAX - 2; j++) { 将该下标后面的元素向前移一位,实现覆盖 } } 跳出循环 } 输出删除后的数组 return 0; }
②记录下标法
int main() { int a[MAX]; int number; int delectIndex; 用循环给数组赋值 输入要删除的数 for (i = 0; i <= MAX - 1; i++) { 找到要删除的数的下标 { delectIndex=i; } } for(i=delectIndex;i<=MAX-2;i++) { 将该下标后面的元素向前移一位,实现覆盖 } 输出删除后的数组 return 0; }
1.1.8数组排序
①冒泡法
相邻元素两两比较,每趟将最值沉底即可确定一个数在结果的位置,确定元素位置的顺序是从后往前,其余元素可能作相对位置的调整。可以进行升序或降序排序。
int main() { int a[10]; int i; int j; int temp; for (i = 0; i < 10; i++) { scanf("%d", &a[i]); } for (j = 0; j < 9; j++) /*外循环控制排序趟数,n个数排n-1趟*/ { for (i = 0; i < 9 - j; i++) /*内循环每趟比较的次数,第j趟比较n-j次*/ { if (a[i] > a[i + 1]) /*相邻元素比较,逆序则交换*/ { temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } for (i = 0; i < 10; i++) { printf("%d", a[i]); } return 0; }
②选择法
每趟选出一个最值和无序序列的第一个数交换,n个数共选n-1趟。第i趟假设i为最值下标,然后将最值和i+1至最后一个数比较,找出最值的下标,若最值下标不为初设值,则将最值元素和下标为i的元素交
换。
int main() { int a[10]; int i; int j; int k; int temp; int n = 10; for (i = 0; i < 10; i++) { scanf("%d", &a[i]); } for (i = 0; i < n - 1; i++) /*外循环控制趟数,n个数选n-1趟*/ { k = i; /*假设当前趟的第一个数为最值,记在k中 */ for (j = i + 1; j < n; j++) /*从下一个数到最后一个数之间找最值*/ { if (a[k] < a[j]) /*若其后有比最值更大的*/ { k = j; /*则将其下标记在k中*/ } } if (k != i) /*若k不为最初的i值,说明在其后找到比其更大的数*/ { temp = a[k]; a[k] = a[i]; a[i] = temp; } /*则交换最值和当前序列的第一个数*/ } for (i = 0; i < 10; i++) { printf("%d", a[i]); } return 0; }
③插入法
将序列分为有序序列和无序列,依次从无序序列中取出元素值插入到有序序列的合适位置。初始是有序序列中只有第一个数,其余n-1个数组成无序序列,则n个数需进n-1次插入。寻找在有序序列中插入位置
可以从有序序列的最后一个数往前找,在未找到插入点之前可以同时向后移动元素,为插入元素准备空间
int main() { int a[10]; int i; int j; int temp; for (i = 0; i < 10; i++) { scanf("%d", &a[i]); } for (i = 1; i < 10; i++) /*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/ { temp = a[i]; /*将待插入数暂存于变量t中*/ for (j = i - 1; j >= 0 && temp > a[j]; j--) /*在有序序列(下标0 ~ i-1)中寻找插入位置*/ { a[j + 1] = a[j]; /*若未找到插入位置,则当前元素后移一个位置*/ } a[j + 1] = temp; /*找到插入位置,完成插入*/ } for (i = 0; i < 10; i++) { printf("%d ", a[i]); } return 0; }
1.1.9数组做枚举用法的案例
①在课本例题“调查电视节目收欢迎程度”中,将节目编号1~8作为数组下标进行计数操作
②在PTA“找重复数据I”一题中,用hush数组的下标对应每个数据,最后对hush数组进行遍历查重
③在PTA“阅览室”一题中,用数组下标存放书号
1.1.10哈希数组用法案例
- ①在PTA“找重复数据I”一题中,先定义一个静态储存的数组hush,然后遍历原数组,当原数组中的元素与hush数组的下标相等时,hush数组该下标所对应的值变为1,之后若再遇到hush的值为1的,即表示
有重复数据
1.2 本章学习体会
1.2.1学习感受
做数组PTA时,一维数组倒是还好,二维数组我感觉比较棘手的是内外两层循环与行列的结合运用,而字符数组就有点难办了,对字符数组的赋值跟输出的认识还是有点模糊。还有就是感觉我的代码的行数常常
比他人要多一些。
1.2.2代码量
两周代码量大约1016行
2.PTA实验作业
2.1出生年
2.1.1伪代码
int main() { int n; //目标年份中不同数字的个数 int i; //循环用的 int j; //循环用的 int year; //出生年份 int flag = 0; //记录有几个不同数 int count = 0; //年纪 static int b[10]; //将年份分拆成4个后,存入该数组 输入出生年份和目标年份中不同数字的个数 while (1) 将年份拆分成4个后,按下标存入b数组 for (i = 0; i < 10; i++) { 遍历b数组,有元素不为0的,flag加一 } 当flag达到n时,输出结果,并结束程序 若flag没达到要求,将flag和b数组清零 count++; year++; //年份与年纪都加一 end while return 0; }
2.1.2代码截图
2.1.3造测试数据
输入数据 | 输出数据 | 说明 |
---|---|---|
2000 4 | 13 2013 | 正常数据 |
6666 4 | 35 6701 | 正常数据 |
11111 3 | 9 11120 | 正常数据 |
9999 3 | 13 10012 | 正常数据 |
9999 4 | 无 | 程序炸了 |
666 5 | 无 | 程序炸了 |
2.1.4PTA提交列表及说明
选这题是因为我觉得这题挺好玩的,做的过程中也换了不少思路,虽然现在看当时的想法很笨(可能现在也是,哈哈哈),但终归是有了一些收获的。
另外我有个小毛病,我无论有没有修改后都会习惯地就点PTA的提交来看各个测试的情况,所以有些错误其实是重复的,因此我会适当跳过一些。
Q1:编译错误
A1:单纯的语法错误。
Q2:部分正确
A2:同时出现了运行超时、段错误,经分析,是发生了数组越位,导致循环不能正常退出,我于是选择用下标的方法处理拆分后的年份数据。
Q3:多种错误
A3:有点尴尬,换了一套算法后就全错了(哈哈哈),经分析,是在flag没达到要求时没有将flag和b数组清零,导致运行结果出错,在多了清零语句后,就通过所有测试点了。
2.1找鞍点
2.1.1伪代码
int main() { int n; //表示几阶的数组 int i; //循环用的 int j; //循环用的 int m; //循环用的 int lineMax; //行最大的数 int rowMin; //列最小的数 int lineDate; //行最大的数的下标 int rowDate; //列最小的数的下标 int a[N][M]; //数组 输入阶数 当阶数为1时,直接输出0 0 for (i = 0; i < n; i++) { for (j = 0; j < n; j++) 给数组赋值 } for (i = 0; i < n; i++) { rowDate = 0; for (j = 0; j < n; j++) { 每行找出列最小的数,记录其数值跟下标 } for (m = 0; m < n - 1; m++) { 找该列行最大的数,记录其数值跟下标 } 若两次查找出的数相同,表示该数符合条件,输出其行列下标,结束程序 } printf("NONE"); //找不到输出NONE return 0; }
2.1.2代码截图
2.1.3造测试数据
输入数据 | 输出数据 | 说明 |
---|---|---|
4 1 7 4 1 4 8 3 6 1 6 1 2 0 7 8 9 | 2 1 | 正常数据 |
3 2 5 6 A 4 1 0 8 5 6 | 1 2 | 有非数字 |
3 -1 -5 -6 -2 -5 -1 -3 -6 -10 | 2 0 | 全负数 |
2.1.4PTA提交列表及说明
我无论有没有修改后都会习惯地就点PTA的提交来看各个测试的情况,所以有些错误其实是重复的,因此我会适当跳过一些。
Q1:部分正确
A1:经分析,没有考虑n=1的情况,补充了几条语句后就通过了“n最小”的测试点。
Q2:部分正确
A2:经过几次调试都没过“最大规模,有并列极值元素,最后一个是鞍点”这一测试点,看了超新星平台后,就全过了。
2.1出生年
2.1.1伪代码
2.1.2代码截图
2.1.3造测试数据
输入数据 | 输出数据 | 说明 |
---|---|---|
0 | 1.0000 | 题目极限数据 |
5 | 148.4132 | 题目极限数据 |
-5 | 0.0067 | 负数 |
2.1.4PTA提交列表及说明
- 我无论有没有修改后都会习惯地就点PTA的提交来看各个测试的情况,所以有些错误其实是重复的,因此我会适当跳过一些。
3.阅读代码
- 代码功能:将输入的一段文字沿着矩阵以螺旋模式进行编码