C语言博客作业04 数组
这个作业属于哪个班级 | C语言--网络2011/2012 |
---|---|
这个作业的地址 | C博客作业04--数组 |
这个作业的目标 | 学习数组相关内容 |
姓名 | 朱芳芳 |
0.展示PTA总分(0----2)
1.本章学习总结(3分)
1.1.1知识点梳理
一维数组:
一个变量可以存n个变量,(类似于有顺序的空盒子群)
语法:
类型 数组名[长度(正整数)];
eg:
int score[5];
char score[5];
访问数组中的元素:
取值:数组名[编号];
赋值:数组名[编号] = 值;
元素:
数组中实际存放的一个个数据。
下标/索引:
系统自动分配的编号,从0开始。
长度:
数组实际保存元素的个数。
数组的赋值:
1、先声明,后赋值。
类型 数组名[长度];
数组名[下标] = 值;
2、在声明的时候初始化。
1)、类型 数组名[长度] = {数据1,数据2,数据3,数据4,.......};
eg:char charTest[3] = {'a','b','c'};
2)、类型 数组名[] = {数据1,数据2,数据3,数据4,.......};
eg:char charTest[] = {'a','b','c'};
//第二种方式的长度,编译器会根据元素的个数来确定。
3)、类型 数组名[5] = {数据1,数据2};
//给的数据小于指定的长度
eg:char charTest[5] = {'a','b','c'};
4)、类型 数组名[5] = {[下标]=数据1,[下标]=数据2,};
//给的数据小于指定的长度
eg:char charTest[5] = {[3] = 'a',[1] = 'b',[0] = 'c'};
遍历数组:
用循环依次访问数组中的每一个元素。
数组的越界:
定义:访问不属于数组本身空间的元素,运行时会报错,也可能是未知的异常。
数组最大访问的下标:长度-1。
计算数组的长度:
1 sizeof(数组名);:得到这个数组占用内存的总长度。
数组的长度 = sizeof(数组名) / sizeof(类型);
2引进库函数<string. h>,使用strlen();
注意:
1、数组和数组变量之间,不能赋值。
eg:
int nums1[5] = {1,2,3,4,5};
int nums2[5] = nums1;
2、数组名声明后也不能直接赋值。
eg:
int nums1[5] ;
nums1 = {1,2,3,4,5};
原因:数组名是一个地址常量。
数组作为函数的参数:
**语法**:
返回值类型 函数名(类型 数组名[]){ 函数体; }
注意:参数中数组的长度可不写,写了也没用,规范的写法时不写。
一组代码
void test1(int nums[]){
nums[0]=11;
nums[1]=22;
nums[2]=33;
}
int main(int argc,const char * argv[])
{
int nums[] = {1,2,3};
test();
for(int i = 0;i<3;i++)
{
//注意:这里输出的不是1,2,3,而是11,22,33。
printf("%d \n",nums[i]);
}
return 0;
}
上面的代码涉及到另外一个概念:引用传递。
概念:传递的是地址,相当于把该变量的内存地址共享给函数。
特点:在函数内部改变了形参的值,外面的实参也会发生变化。
说明:基本数据类型(int,char,long,double,float,short)不是引用传递;
数组是引用传递。
注意:
1、在函数中,不能直接计算形参(数组)的长度,永远等于2。解决办法就是在多传递一个参数,作为数组的长度。
2、函数的数组形参可以不写长度,但是区分类型。
1.1.2知识点技巧总结
查找数据
使用循环,遍历数组,判断语句,匹配后跳出循环
七大查找算法
- 顺序查找
- 二分查找
- 插值查找
- FIbonacci查找
- 分块查找
- 树表查找
- HashTable查找
eg:
二分查找(Binary Search)说明:元素必须是有序的,如果是无序的则要先进行排序操作。
基本思想:也称为是折半查找,属于有序查找算法。用给定值k先与中间结点的关键字比较,
中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较
结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
插入数据
使用循环,找到要插入的位置,记住位置,将该位置的元素全部往后移动一位(利用循环),在此过程中注意数组的越界,再将要插入得数据赋值到该位置。
删除数据
同上,往前移动一位
数组的循环左移
伪代码:
输入数组;
输入数组长度n和移动次数m;
while(移动次数大于0)
{
for()
}
排序方法:
冒泡排序:
#include<stdio.h>
#define N 10
int main ()
{
int a[N];
int i,j,t;
printf("Please input %d numbers:\n",N);
for(i<0;i<N;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=N-1;i++)
{
for(j=0;j<N-i;j++)
{
if(a[j]>a[j+1])
{
t=a[j];a[j]=a[j+1];a[j+1]=t;
}
}
}
printf("The resortrd numbers is :\n");
for(i=0;i<N;i++)
{
printf("%-4d",a[i]);
}
}
选择排序:
//选择法:选择法的算法思想是先固定第一个值,将该固定的值依次与后面的值进行比较,如果大于/小于,则交换来达到将最大值或最小值放在最后。#include"stdio.h"
#include<stdio.h>
#define N 4
int main ()
{
int a[N];
int i,j,k,t;
for(i=0;i<N;i++)
{
scanf("%d",&a[i]);
}
printf("\n");
for(i=0;i<N;i++)
{
k=i;
for(j=i+1;j<N;j++)
{
if(a[k]>a[j]) //将两个数进行交换
{
k=j;
}
}
if(k!=i)
{
t=a[k];a[k]=a[i];a[i]=t;
}
}
for(i=0;i<N;i++)
{
printf("%d ",a[i]);
}
}
交换排序//略
数组中如何插入数据,怎么做,可以写个伪代码或动态图展示方法
思想:数据的移动
第一种,数组初始化的时候直接开辟足够大的空间,你虽然只有7个数字,但是你数组可以直接初始化一个容量为50的数组,那么之后再添加少量元素的时候,便不需要考虑扩容的问题。int a[50] = {12, 23, 34, 45, 56, 67};有了无需扩容的考虑之后,便需要实现你的真正需求:插入元素。这时候,就像 @kanesunny 所说的,你在纸上画一画,便能发现如果要方便地、且不覆盖原有元素,那么必须从后往前移动,也就是说先把 67 移动到 a[n](n为数组长度),然后依次移动极可
第二种,可以直接不考虑将原数组扩容的问题,而是直接创建一个新的容量为 n+1 的数组,然后将所有元素挪入进新数组
#include <stdio.h>
#define N 5 //宏定义,并不是必须的
int main()
{
int powers[N] = {42332, 45771, 40907, 41234, 40767};
int count = 5;//元素个数
int deletePower;//用户要删除的元素
int deleteIndex = -1;//对应删除的元素下标,赋值一个不可能的值
int insertPower;
int i;
/*********数组的删除************/
printf("请输入要删除的元素:");
scanf("%d",&deletePower);
for (i = 0; i < count ;i++)
{
if(deletePower == powers[i])
{
deleteIndex = i;
break;
}
else
{
printf("您输入的值未在数组中,请重新输入!\n");
exit(0);
}
}
count--;
for(i = deleteIndex; i < count; i++)
{
powers[i] = powers[i+1];
}
printf("您删除后的数组为:");
for(i=0;i<count;i++)
{
printf("%d ",powers[i]);
}
printf("\n");
/*********数组的插入************/
printf("请输入要插入的元素:"); //默认插在数组最后
scanf("%d",&insertPower);
powers[count] = insertPower;
printf("您插入后的数组为:");
for(i=0;i<count+1;i++)
{
printf("%d ",powers[i]);
}
}
重构数组:数组长度
数组中目前学到排序方法,主要思路?
顺序,逆序,
数组做枚举用法,有哪些案例?
哈希数组用法,目前学过哪些案例,举例展示。
去重,查找重复数据
思路1:
1.构建一个新的数组存放结果
2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比
3.若结果数组中没有该元素,则存到结果数组中
思路2:
1.先将原数组进行排序
2.检查原数组中的第i个元素 与 结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置
3.如果不相同,则将该元素存入结果数组中
思路3:
1.创建一个新的数组存放结果2.创建一个空对象3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,
则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。
说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复
思路4:
新建一新数组,遍历传入数组,值不在新数组就加入该新数组中;
字符数组、字符串特点及编程注意事项。
2.PTA实验作业(7分)
2.1 冒泡法排序 (3分)
将N个整数按从小到大排序的冒泡排序法是这样工作的:从头到尾比较相邻两个元素,如果前面的元素大于其紧随的后面元素,则交换它们。通过一遍扫描,则最后一个元素必定是最大的元素。然后用同样的方法对前N−1个元素进行第二遍扫描。依此类推,最后只需处理两个元素,就完成了对N个数的排序。
本题要求对任意给定的K(<N),输出扫描完第K遍后的中间结果数列。
2.1.1 伪代码
输入N和K(1≤K<N≤100;
输入一维数组a[N];
for(;i<k;)//外层循环,控制排序的次数k
{
for(;n-i-1;)//每一轮的排序,次数随着最大数放到最右边的个数而减少,与K没有直接联系
{
相邻两个数比较大小后交换排序;
}//内层循环,控制每轮将最大的数放到最后
}
end for;
printf("%d ",a[i]);
for(int i=0;i<n-1;i++)//输出数组使用循环,控制格式对第一个单独处理
{
printf("%d",a[n-1]);
}
end for;
2.1.2 代码截图
2.1.3
2.2 找鞍点(2分)
一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。
本题要求编写程序,求一个给定的n阶方阵的鞍点。
输入格式:
输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。
输出格式:
输出在一行中按照“行下标 列下标”(下标从0开始)的格式输出鞍点的位置。如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。
2.2.1 伪代码
for()
{
输入数组;
}
for()
{
找出每行中的最大的数字;
}
for()
{
比较这个数字所在列是否是最小数字;
}
if(找到)
{
输出所在位置;
}
else
{
输出没有找到;
}
2.2.2代码截图
2.2.3
2.3 切分表达式(2分)
四则运算表达式由运算数(必定包含数字,可能包含正或负符号、小数点)、运算符(包括+、-、*、/)以及小括号((和))组成,每个运算数、运算符和括号都是一个token(标记)。现在,对于给定的一个四则运算表达式,请把她的每个token切分出来。题目保证给定的表达式是正确的,不需要做有效性检查。
2.3.1 伪代码
输入数组
while()//
{
判断数字, 输出;
判断符号,输出;
判断加号,输出;
}
end while;
2.3.2 代码截图
2.3.3
同学的代码 注释比较多,较容易理解,自己的代码,比较难读