C语言博客作业04--数组

| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业04--数组 |
| 这个作业的目标 | 学习数组相关内容 |
| 姓名 | 吴慧敏 |

0.展示PTA总分(0----2)


1.本章学习总结(3分)

1.1 学习内容总结

  • 数组中如何查找数据,有哪些做法
    数组的三种查找方法分别为:顺序查找,二分法查找(折半查找),分块查找
    顺序查找:不需要排序,遍历所有数组元素,查找时间较长。
    二分法查找:需要对所有数据进行排序,适合顺序结构。因为每次都是和中间值比较,如果大于选中间值后面的部分继续二分查找,如果小于中间值则选前面的部分
    继续执行。
    分块查找:需要按照数值大小进行排序分块,虽然每个块中的大小可以不排序,但是块的取值区间是排序的。
  • 数组中如何插入数据,怎么做,可以写个伪代码或动态图展示方法
    方法:将要插入的数字和每个数进行比较找到数a[i],然后将a[i]后的每个数后移一位,再将x插入空出的位置,x插入完成后即可跳出循环。
    伪代码:
输入数据
for (i = 0; i < N; i++)
{
     if (x <= a[i])每个数都要进行比较
     {
         for (j = N; j > i; j--)
         {
            a[i]后的每个数都要后移一位
         }
     }
}
for (i = 0; i <= N; i++)
{
输出数据(此时数组的长度为比原来多一)
}
  • 数组中如何删除数据,这个有多种做法,请一一展示。
    做法1:将当前这个要被删除的数字位置赋值后面一个数值.以后每个数字都这样做.
#include <stdio.h>
int main()
{
	int n;
	int i;
	int j;
	int k;
	int t;
	int a[100];
	scanf("%d", &n);
	if ((n >= 1) && (n <= 100))
	{
		for (i = 0; i < n; i++)
		{
			scanf("%d", &a[i]);
		}
		scanf("%d", &k);
		for (i = 1; i <= k; i++)//进行k次删除
		{
			scanf("%d", &t);
			for (j = t; j < (n-i+1); j++)
			{
				a[j-1] = a[j];
			}
		}
		printf("%d", a[0]);
		//输出经过k次删除后的数组
		for (i = 1; i < (n - k); i++)
		{
			printf(" %d", a[i]);
		}
	}
	return 0;
}

做法2:重新定义一个数组,重新存放除要删除的数据之外的所有数据

  • 数组中目前学到排序方法,主要思路?
    冒泡排序:对所有相邻记录的关键字值进行比效,如果是逆顺(a[j]>a[j+1]),则将其交换,最终达到有序化。
    冒泡排序算法:
for (i = n; i > 1;i--)
{
   for (j = 1; j <= i - 1; j++)
   {
   if(a[j]; key > a[j + 1]; key)
     {
     temp = a[j];
     a[j] = a[j + 1];
     a[j + 1] = temp;
     }
   }
}

选择排序:如果有N个元素需要排序,那么首先从N个元素中找到最小的那个元素与第0位置上的元素交换(说明一点,如果没有比原本在第0位置上的元素小的就不用交换了,后面的同样是),然后再从剩下的N-1个元素中找到最小的元素与第1位置上的元素交换,之后再从剩下的N-2个元素中找到最小的元素与第2位置上的元素交换,直到所有元素都排序好(也就是直到从剩下的2个元素中找到最小的元素与第N-2位置上的元素交换)。
eg.
初始状态: 49 38 65 97 76 13 27
第一趟: 从(38 65 97 76 13 27)中选择最小值13与49交换
13 38 65 97 76 49 27
第二趟: 从(65 97 76 49 27)中选择最小值27与38交换
13 27 65 97 76 49 38

  • 数组做枚举用法,有哪些案例?
    7-5 调查电视节目受欢迎程度:

    代码:
#include <stdio.h>
int main()
{
	int n;
	int i;
	int j;
	int a[1500];
	static int count[1500];//记录8个栏目各自的得票情况
	scanf("%d", &n);
	if ((n >= 1) && (n <= 1000))
	{
		/*输入n个整数(即n个观众的投票结果)*/
		for (i = 0; i < n; i++)
		{
			scanf("%d", &a[i]);
		}

		/*将观众的投票结果记录进count中*/
		for (i = 0; i < n; i++)
		{
			for (j = 1; j <= 8; j++)
			{
				if (a[i] == j)//a[i]为观众的投票结果数字,j为1-8的栏目编号
				{
					count[j]++;
				}
			}
		}
		/*输出栏目的编号和得票数*/
		for (j = 1; j <= 8; j++)
		{
			printf("%4d%4d\n", j, count[j]);//若写成printf("   %d   %d\n", j, count[j]);则会出现如果你[j]数据大于10的话,数值所占位置大于4位,从而造成格式错误
		}
	}
	return 0;
}



  • 哈希数组用法,目前学过哪些案例,举例展示。
    用法(去重):定义2个数组a[100001],b[i]。初始化b[100001],b用于判断数字是否出现两次。若出现b=2的情况则说明有重复数,跳出循环。
    案例--找重复数据:

#include <stdio.h>
int main()
{
	int n;
	int i;
	int j;
	int flag = 0;
	int a[100001];
	static int b[100001];//初始化b[i]
	scanf("%d", &n);
	if ((n >= 1) && (n <= 100000))
	{
		for (i = 0; i < n; i++)
		{
			/*边输入边找重复数字*/
			scanf("%d", &a[i]);
			b[a[i]]++;//对重复出现的数字累加
			if (b[a[i]] == 2)//出现2次即可
			{
				flag = 1;//控制有重复数的情况
				printf("YES");
				break;//跳出循环
			}
		}
		if (flag == 0)
		{
			printf("NO");
		}
	}
	else
	{
		printf("NO");
	}
	return 0;
}



/*
#include <stdio.h>
int main()
{
	int n;
	int i;
	int j;
	int flag = 0;
	int a[100000];
	scanf("%d", &n);
	if ((n >= 1) && (n <= 100000))
	{
		  /*输入n个数*/
/*for (i = 0; i < n; i++)
{
	scanf("%d", &a[i]);
}
//相当于输入的第一个数要和其后的每个数进行比较知道出现相同数字才跳出循环,运算量太大
for (i = 0; i < n - 1; i++)
{
	for (j = i + 1; j < n; j++)
	{
		if (a[i] == a[j])
		{
			flag = 1;
			printf("YES");
			break;
		}
	}
}
if (flag == 0)
{
	printf("NO");
}
	}
	return 0;
}*/ /*若用此种方法会出现测试点3, 4错误(n太大,运行超时)*/

  • 字符数组、字符串特点及编程注意事项。
    字符数组特点:数组初始化时,如果对全部元素都赋了初值,就可以省略数组长度。
    字符串特点
    1、字符串是引用类型:字符串的数据是存储在堆空间中,栈空间中的变量存储了该数据的引用地址。
    2、字符串是不可变的:当给一个字符串变量重新赋值时,旧值并没有销毁,而是重新开辟一块空间来存新值。
    3、字符串可以看做是一个只读的字符数组:也就是说我们可以用for循环遍历字符串,得到所有的单个字符;也可以用变量名[索引下标] 的形式得到相对应的字符。
    编程注意事项
    1.数组初始化时,如果对全部元素都赋了初值,就可以省略数组长度。
    2.'\0'是字符串结束符。
    3.数组长度至少是字符串的有效长度+1。

2.PTA实验作业(7分)

2.1 题目名1(3分)

2.1.1 伪代码

for  i=0 to n-1
输出一个数
end for
输出最后一个数

2.1.2 代码截图

2.1.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。

以下为姚庆荣同学的代码:

#include<stdio.h>
int main()
{
	int n;
	int temp=0;
	int num[10];
	int i;
	scanf("%d", &n);
	for( i=0;i<n;i++)
	{
		scanf("%d", &num[i]);
	}
	printf("%d", num[n-1]);
	for(i=n-2;i>=0;i--)
	{
		printf(" %d",num[i]);
	}
	return 0;
}
  • 我的代码特点:先进行n个整数的输入,在从数组的后面往前输出数字,并且为了满足行末无多余空格单独输出原数组的第一个数。
  • 姚庆荣同学的代码的特点:先进行n个整数的输入。先单独输出原数组的最后一个数,接着再进行循环输出其它数。

2.2 题目名2(2分)

2.2.1 伪代码

输入二维数据
for (i = 0; i < n; i++)
{
     for (j = 1; j < n; j++) 找出行上最大的数的值max以及所在的列数maxIndex;
     for (k = 0; k < n; k++)
     {
          判断是否有a[k][maxIndex] < max,有,则a[k][maxIndex]不 
          是鞍点,退出循环。
     }
     没有,则a[k][maxIndex]是鞍点,输出,count加1
}
if(count==0)
{
 说明没有提前退出循环,没有鞍点
}    

2.2.2 代码截图



2.2.3 请说明和超星视频做法区别,各自优缺点。

  • 我的代码做法:第一步:输入二维数据;第二步:先假设第i行的第一个元素就是行最大值,找出行上最大的数的值max以及所在的列数maxIndex;找到某行最大的数所对应的列的数字,输出结果。
    我的优点:情况考虑周到,利用了2层循环操作,灵活表示二维数组元素,在找到鞍点后提前退出循环break。在if (max <= a[i][j])加了等号(测试点:最大规模,有并列极值元素,最后一个是鞍点)
  • 超星视频优点:情况考虑周到,利用了2层循环操作,灵活表示二维数组元素,在找到鞍点后提前退出循环break。
  • 区别:和超星视频的做法基本一致。

2.3 题目名3(2分)

2.3.1 伪代码

if str[i] 是'('或')'或'*'或'/':
      找到token,换行输出str[i]
if str[i] 是数字或小数点:
   if  后一位是数字或小数点:
        输出数字,不换行
   else:
        输出数字,数字token在这里结束,再输出换行
if str[i] 是'+'或'-':
    if i==0  或  前一位是'(':
         str[i]是正负符号,直接输出,不换行
    else:
         是token,换行输出str[i]

2.3.2 代码截图

2.3.3 请说明和超星视频做法区别,各自优缺点。

说明:我的代码和超星视频做法基本一致。
优点:考虑到了多做种情况,运用了continue,可以提前结束本次循环,无需进入不必要分支,提高了程序效率。

posted @ 2020-12-13 21:49  蓝胖子WHM  阅读(161)  评论(0编辑  收藏  举报