• 数组


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


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


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

    1.1 学习内容总结

    ⭐数组中如何查找数据

    有序数组

    • 二分法

    采用二分法,将最中间的数与用户输入的数进行比较,逐步缩小所求数在数组中的区间(+1或-1),直至匹配,或得出无法找到的结论。

    无序数组


    无序数组没有规律,它的查找只能线性进行,通过循环将数组中的前后元素逐个比较。

    #include <stdio.h>
    #define MAX 20
    int main()
    {
    	int n;//输入n个整数
    	int x;//需要找到的数字
    	int arr[MAX];//定义数组用于储存输入的整数
    	int flag = 1;
    
    	scanf("%d %d", &n,&x);
    
    	for (int i = 0; i < n; i++)//输入数组的各个元素
    	{
    		scanf("%d", &arr[i]);
    	}
    
    	for (int i = 0; i < n; i++)//遍历数组,寻找数字x
    	{
    		if (arr[i] == x)//找到所需数字
    		{
    			printf("%d", i);
    			flag = 0;
    			break;
    		}
    	}
    	if (flag)//遍历数组后仍未寻到所需数字
    	{
    		printf("Not Found");
    	}
    	
    	return 0;
    }
    

    ⭐数组中如何插入数据


    输入一个数x,将数组中的元素与x逐一比较,如果其大于x,则记录该元素的下标i,然后此元素下标和其后的元素的下标都加一,即后移一位,然后将x赋值给数组的那个下标arr[i]。

    #include <stdio.h>
    #define MAX 10
    int main()
    {
    	int n,x;
    	int temp;
    	int arr[MAX];
    	
    	//输入
    	scanf("%d", &n);//输入个数
    	for (int i = 0; i < n; i++)//循环输入数组元素
    	{
    		scanf("%d", &arr[i]);
    	}
    	scanf("%d", &x);//输入需插入的数
    
    	//插入排序
    	if (x >= arr[n - 1])//插在尾
    		{
    			arr[n] = x;
    		}
    
    	else if (x <= arr[0])//插在头
    	{
    		for (int i = n; i > 0; i--)
    		{
    			arr[i] = arr[i - 1];
    		}
    		arr[0] = x;
    	}
    	else//插在中间
    	{
    		for (int i = 0; i < n; i++)
    		{
    			if ((arr[i] <= x && arr[i + 1] > x) || x <= arr[i])
    			{
    				for (int j = n; j > i + 1; j--)
    				{
    					arr[j] = arr[j - 1];
    				}
    				arr[i + 1] = x;
    				break;
    			}
    		}
    	}
    	//输出数组元素
    	int flag = 1;
    	for (int i = 0; i <= n; i++)
    	{
    		printf("%d ", arr[i]);
    	}
    
    	return 0;
    }
    

    ⭐数组中如何删除数据


    输入一个数x,将数组中的元素与x逐一比较,若某一数组元素等于x,则记录该元素的下标i,且其后的数据都向前移位,实现覆盖第i项数据。

    #include <stdio.h>
    #define MAX 100
    int main()
    {
    	int n;//表示数组元素个数
    	int arr[MAX];
    	int k;//表示删除次数
    	int x;//表示每行删掉的数
    	int num;
    
    	//输入
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++)
    	{
    		scanf("%d", &arr[i]);
    	}
    	scanf("%d", &k);
    
    	//删除元素
    	num = n;//数组元素个数
    	for (int i = 1; i <= k; i++)//删除次数
    	{
    		scanf("%d", &x);
    		for (int i = x - 1; i < num - 1; i++)
    		{
    			arr[i] = arr[i + 1];
    		}
    		num -= 1;
    	}
    
    	//输出
    	for (int i = 0; i < n - k; i++)
    	{
    		if (i == 0)//第一次输出,前不带空格
    			printf("%d", arr[i]);
    		else
    			printf(" %d", arr[i]);
    	}
    
    	return 0;
    }
    

    ⭐数组中目前学到排序方法及主要思路

    • 冒泡法

    从当前元素起,向后依次比较每一对相邻元素,若逆序则交换。对所有元素均重复以上步骤,直至最后一个元素。

    上方gif动图来自网络,某大佬博主

    #include <stdio.h>
    #define MAX 255 /*数组长度上限*/
    
    void bubbleSort (int arr[], int len) 
    {
        int temp;
        int i, j;
        for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
            for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
                if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
    }
     
    int main (void) {
        int arr[ARR_LEN] = {3,5,1,-7,4,9,-6,8,10,4};
        int len = 10;
        int i;
         
        bubbleSort (arr, len);
        for (i=0; i<len; i++)
            printf ("%d	", arr[i]);
        printf("
    ");
         
        return 0;
    }
    
    • 选择法

    每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。

    上方gif动图来自网络,某大佬博主

    #include <stdio.h>
    void swap(int *a,int *b) 
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    void selectionSort(int arr[], int len) 
    {
        int i,j;
     
        for (i = 0 ; i < len - 1 ; i++) 
        {
            int min = i;
            for (j = i + 1; j < len; j++)     
                if (arr[j] < arr[min])
                    min = j; 
               swap(&arr[min], &arr[i]);    
        }
    }
    

    冒泡法与选择法的区别


    • 冒泡算法,每次比较如果发现较小的元素在后面,就交换两个相邻的元素。
    • 而选择排序算法先并不急于调换位置,先从a[0]开始逐个检查,看哪个数最小就记下该数的下标i,等一次遍历后,再把a[i]和a[0]对调,这时a[0]到a[10]中最小的数据就换到了最前面的位置。
    • 即选择排序每扫描一遍数组,只需要一次交换,而冒泡可能需要很多次。

    ⭐数组做枚举用法


    用0-N的整形数字做下标可读性不高,为解决这个问题,我们可以使用枚举变量作为下标来访问数组。

    enum color{black,white,red,blue,green}; //类型定义
    enum color{black,white,red,blue,green} color1; //定义变量
    enum color{black,white,red,blue,green} colorx[2]; //定义枚举类型的数组变量
    
    • enum 是枚举,也就说如果变量的类型为enum, 那么它的取值只可以是这个枚举中的一种。

    ⭐哈希数组用法


    将一大类数据用已知的hash函数进行分类,映射到固定大小的数组中。

    #include<stdio.h>//此处参考借用了网络上的哈希查找案例
     
    #define LEN 13
    #define N 11
    int data[N]={10,9,8,7,5,4,6,3,2,1,95};   //原始数据;
    int hash[LEN]={0};   //哈希表,初始化为0;
     
    void Create()
    {
    	for(int i=0;i<N;i++)  //循环将原始数据保存到哈希表中;
    	{
    		//将关键字插入到哈希表hash中;
    		int j=data[i]%13;  //计算哈希地址;
    		while(hash[j])  //元素位置已被占用;
    			j=(++j)%LEN;  //线性探测法解决冲突;
    		hash[j]=data[i];
    	}
    }
    int Haxi_Sou(int key)
    {
    	int i=key%LEN;  //计算哈希地址;
    	while(hash[i]&&hash[i]!=key)   //判断是否冲突;
    		i=(++i)%LEN;   //线性探测法解决冲突;
    	if(hash[i]==0)  //查找到开放单元,表示查找失败;
    		return -1;  //返回失败值;
    	else
    		return i;   //返回对应的元素下标;
    }
    int main(void)
    {
    	int key;
    	Create();  //调用函数创建哈希表;
    	printf("哈希表中各元素的值:");
    	for(int i=0;i<LEN;i++)
    		printf("%d ",hash[i]);
    	printf("
    ");
    	printf("输入查找的关键字;");
    	scanf("%d",&key);
     
    	int pos=Haxi_Sou(key);  //调用函数在哈希表中查找;
    	if(pos>0)
    		printf("查找成功,该关键字在数组中的下标为 %d !!!",pos);
    	else
    		printf("查找失败!!!");
    	printf("
    ");
    	return 0;
    }
    

    ⭐字符数组、字符串特点及编程注意事项

    • 要数组传入一个函数作判断时,需传入数组名和数组长度。
      eg
    int arr[10];
    scanf("%d",&n);
    ChooseSort(arr,n)//传入的为数组名arr,而不是arr[]
    void ChooseSort(int date[],int n)或(int *p,int n
    
    • static int a[10],可将数组元素全部初始化为0。
    • 字符串的输出"%s",字符的输出"%c"。
    • 字符串常量:用一对双引号""括起来的字符序列。
    • --字符串结束符,其等于0,所以判断最后一个元素时可写成s[i]!=0或s[i]!=''(注意为单引号,'')。
    • 字符数组的最后一个元素是'',所以char s[N]="Happy"的数组长度为6(还有一个'')。
    • "a"为字符串,在内存中占两个字节(a,);'a'为字符,在内存中只占一个字节(a)。
    • 输入:fgets(buf,10,stdin)//buf为数组名,10为数组的最大长度,可接收空格及其他字符。
      当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。


    2.PTA实验作业(7分)

    2.1 将数组中的数逆序存放

    ⭐2.1.1 伪代码

    ⭐2.1.2 代码截图

    ⭐2.1.3 找一份同学代码比较,说明各自代码特点

    对比与反思


    • 我的代码与该同学的代码的区别主要是对逆序的处理方法不同。
    • 该同学在输入数组元素后采用逆序的方法直接输出(即从n开始--),而我是采用了两两交换的方法(第一位与最后一位交换,第二位与倒数第二位交换......)对数组重新赋值,最后再输出数组元素。
    • 相比之下,我的方法显得更为繁琐,多了许多无意义的步骤,我会争取在后面的编程中改进,写题前尽量思考简便的做法。

    2.2 鞍点

    ⭐2.2.1 伪代码


    ⭐2.2.2 代码截图


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


    • 大体思路相同,均是先找到一行中的最大元素,然后循环判断其与在所在的列上的其他元素,若其是所在列的最小值,则为鞍点,反之不是鞍点。
    • 我的写法与超星相似,但在变量名的设计上还有待提高。
    • 我们应该注意的是循环中用于标志是否为鞍点的变量flag需在每次循环时重赋值,否则会影响结果。

    2.3 切分表达式

    ⭐2.3.1 伪代码


    ⭐2.3.2 代码截图


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


    • 超星使用了continue语句来提前结束循环,以减少程序运行时间,大大提高了程序的效率。
    • 超星将切分表达式所需的代码分装成不同的功能函数,使主函数更加简洁,同时使代码更加清晰易懂,便于读者阅读。
    • 我对运算符的分类比超星更少,但没有想到可以使用continue语句,编程能力仍需提高,同时超星上的变量命名及功能函数的分装也是我所欠缺的部分。
  • 相关阅读:
    【学习笔记】《架构整洁之道》(2)
    【学习笔记】《架构整洁之道》(1)
    《漫长的婚约》
    My 2020 work schedule
    canal-clientadapter 数据同步实验
    confluence异常关闭恢复
    nginx 添加第三方nginx_upstream_check_module 模块实现健康状态检测
    keepalived问题阐述及配置
    keepalived+lvs 部署
    lvs基础
  • 原文地址:https://www.cnblogs.com/noyiie/p/14030588.html
Copyright © 2020-2023  润新知