C语言博客作业04--数组
| 这个作业属于哪个班级 |
| ---- | ---- | ---- |
| 这个作业的地址 |
| 这个作业的目标 | 学习数组有关内容|
|姓名|张静雯|
1.本章学习总结(3分)
1.1 学习内容总结
1.1.1数组中如何查找数据,有哪些做法
-
顺序查找法
先假设X不在数组中,置flag为0,如果在数组中找到了X,置flag为1,说明在数组a中找到了X,跳出循环,如果flag为1,说明X不在数组a中
案例:PTA题目7-2 查找整数
-
二分法
二分法查找首先需要一组排序好的数组,定义left(数据集的开头),right(数据集结尾)两个变量,然后在这组数据中找到mid=(left+right)/2,然后将待查找元素与mid所指元素进行比较,如果相等将索引返回,如果查找元素大于mid所指元素,则将left向右移动即left=mid+1;如果查找元素小于mid所指元素,则将left向左移动即right=mid-1。当left大于right时,说明该数不存在于数组中,结束循环。
1.1.2数组中如何插入数据,怎么做,可以写个伪代码或动态图展示方法
找到要插入位置的下标,从该位置开始每个数往后移一位,腾出该位置,将要插入的数插入。
实现案例:PTA 7-6 简化的插入排序
1.1.3数组中如何删除数据,这个有多种做法,请一一展示。
-
找到要删除的位置,从该位置开始,所有数据往前移一位。
-
目的是删除第detnum个数,新构建一个数组,设置循环变量j,当j不等于detnum时,把原来的数组中的数据放到新数组中,如果j等于detnum时,不放入新数组。
1.1.4数组中目前学到排序方法,主要思路?
1.选择排序法
主要思路:
从待排序的区间中经过选择和交换后选出最小的数值存放到 a[0] 中,再从剩余的未排序区间中经过选择和交换后选出最小的数值存放到 a[1] 中,a[1] 中的数字仅大于 a[0],依此类推,即可实现排序。
案例:
2.冒泡排序法
冒泡排序的基本思想就是不断比较相邻的两个数,让较大的元素不断地往后移。经过一轮比较,就选出最大的数;经过第2轮比较,就选出次大的数,以此类推。
案例:
1.1.5数组做枚举用法,有哪些案例?
1.1.6哈希数组用法,目前学过哪些案例,举例展示。
百度百科:Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
案例:
1.2字符数组、字符串特点及编程注意事项。
1.2.1字符数组:
- 输入:
for(i=0;i<5;i++)
putchar(t[i])
- 输出:
- 一维数组
for(i=0;i<5;i++)
printf("%c",str[i])
- 二维数组
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%c",&a[i][j]);
}
printf("\n");
}
特点:
数组元素的个数是固定的,一般用下标法控制
1.2.2字符串:
- 输入:
- scanf输入
scanf("%s",str) - 循环输入
i=0
while((str[i]=getchar())!'\n')
i++;
str[i]='\0';
- fgets函数
fets(str,100,stdin)
三种方法的特点
==1.scanf无法接收带空格的字符串
2.循环输入,切记要加入str[i]='\0';否则的话字符串将没有结束符
3.fgets函数
- 接受带空格字符串,输入长度少于n-1,会多带一个换行符==
- 循环条件要这样设置for(i=0;str[i]&&stri[i]!='\n';i++)
- 输出:
- 循环输出
char str[80]
for (i=0;str[i]!='\0';i++) putchar(str[i]);
printf("%s",str)
printf("%s","hello")
- put函数
puts(str)
puts("hello");
输出字符串后自动换行
输出参数可以是字符数组名或字符串常量,输出遇'\0'结束
2.PTA实验作业(7分)
2.1 数组循环左移(3分)
2.1.1 伪代码
定义数字个数n,移动的次数movetime,数组a
输入数字个数,移动次数,数组a
for k=0 to moveTimes-1
a[n]=a[0]
for j=detnum to n-1
a[j]=a[j+1] //向左移一位
end up
a[n-1]=a[n]
end up
for i=0 to n-1
if i为0
直接输出a[i]
else 输出空格a[i]
2.1.2 代码截图
2.1.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。
由于没有找到和自己差距较大的同学代码,我在网上找到了一份其他人写的代码做对比。
出处:
代码参考:
分析:该代码没有重构数组来进行左移,而是直接通过控制输出来实现代码的移动,假设移动的次数为moveTimes,那么第moveTimes个元素会被移动到第一个,所以控制输出的是a[moveTimes-1],后面的数字依次输出,当达到数组的最后一位数时,再从数组的一位开始输出直到第moveTimes-1个。相比于我自己的代码,这位博主的做法只用到了一个循环就同时实现了输出和循环左移的过程,而我的代码需要moveTimes个循环才能实现左移,实现输出时又需要一个循环,该代码的做法是很巧妙的,可以节省很多时间,值得我好好学习。
2.2 找鞍点(2分)
选择阅览室或鞍点这2题介绍二维数组。并说明和超星视频做法区别。
2.2.1 伪代码
输入二维数组
for j=0to num-1
max初始化为0
for i=0 to num-1
如果a[j][i]大于等于a[j][max]
max=1
end up//找到最大的数在第max列
for i=0 to num
判断a[i][max] 和大小a[j][max]
如果a[j][max]大于a[i][max]
flag=1
否则flag=0
end up
if flag=1 输出鞍点
else 输出NONE
2.2.2 代码截图
2.2.3 请说明和超星视频做法区别,各自优缺点。
超星视频做法
总体思路和超星视频的做法大致一样,所不同的在于控制输出的时候,我的代码用了临时变量flag来判断是否有鞍点,而实际上当i没有提前退出时i=n,就可以说明没有鞍点。
2.2.4需要注意的地方
PTA的题目里有一个测试点为并列极值,最后一个数为鞍点,所以在判断最大数的下标是,把条件改为
if (a[j][i] >= a[j][max])
{
max = i;
}
即可通过测试点,但实际上如果有并列极值,第一个是鞍点的情况,该代码是不能返回正确的结果的,因为在出现并列极值的情况下,该代码是默认取最后一个数的下标,判断它是否为该列最小,事实上,更科学的做法应该是把两个极值都进行判断是否为该列最小。
2.3 切分表达式(2分)
选择切分表达式这题介绍字符数组。并说明和超星视频做法区别。
2.3.1 伪代码
输入数组
定义flag=1
for (i = 0; str[i] != '\n'; i++)
if str[i]为'.'或者数字0~9
直接输出str[i]&&falg=0
else if str[i]为'*'或者'/'
if flag==0 说明前一个是数字
输出\nstr[i]\n
else 前一个不是数字
输出str[i]\n&&flag=1
else if (str[i] 为 '-'或者 '+')
if i=0 说明该符号是运算符
输出str[i]
else if str[i]的前一个是'('
输出str[i]
else if str[i]的前一个是')'
输出str[i]\n
else 输出\nstr[i]\n
flag=1
end if
2.3.2 代码截图
2.3.3 请说明和超星视频做法区别,各自优缺点。
我的思路:关键在于控制换行符的输出,先把输入的字符分为数字的组成成分和其他符号
数字的组成成分有两种可能
1,1.0~9和'.'
2.输入的是‘+’和‘-’,且该字符位于第一位或者‘(’的后面一个
这两种情况都为数字成分,不做拆分,前后都不需要输出转换符
其他成分组成
1.都在输出时后面都要加上换行符
2.判断前一个字符是否为数字成分,若是数字组成成分前面也要加一个换行符来和前面的数字成分切分
超星视频的伪代码:
超星视频的思路:
历遍每一个字符数组,判断字符是否需要切分,如果字符是需要切分的,输出该字符和换行符,如果不用切分,直接输出字符
字符情况:
1.如果是'*''/''('')',需要切分
2.如果是字符09,判断下一位字符是否为09或者'.',如果是,不用切分,不是要切分
3.判断‘+’和‘-’是加减还是正负号,如果是如果前一个'+''-'位于第一个或者‘(’后面,是正负号,否则是加减。
超星视频里的代码值得学习的地方:
1.判断前一个和后一个字符可以用a[i-1]和a[i+1]
2.进入一个if条件以后,我们可以知道这个字符不会进入其他的if条件,直接用continue跳出循环,无需进入不必要的分支,使得整个程序更高效。