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

同学的代码 注释比较多,较容易理解,自己的代码,比较难读

posted @ 2020-12-13 22:24  calizo  阅读(321)  评论(0编辑  收藏  举报