zoukankan      html  css  js  c++  java
  • C语言博客作业04--数组

    这个作业属于哪个班级 C语言--网络2011/2012
    这个作业的地址 C博客作业04--数组
    这个作业的目标 学习如何设计函数、C语言基本数据类型

    目录

    0. 展示PTA总分

    1. 本章学习总结

    2. PTA实验作业



    0.展示PTA总分



    1. 本章学习总结

    1.1 学习内容总结

    1)查找数据

    • 顺序查找
      • 无序有序排列的数组均可以使用
      • 即按照顺序逐个查找目标数字/字符
      • 伪代码:(计数指定数据的个数)
    /*计数目标数据的数量时,利用count++自增运算*/
    // 跳出循环后,可以通过count的值,判断数组里是否有目标数据
    //
    /*需要利用目标数据的位置时(如增、删、改),将count++改为break,利用break跳出循环;或用return返回目标数据的下标*/
    //可以使用flag,当找到目标数据时,flag = 1,反之 flag = 0。若未找到则及时结束函数,避免数组越界
    //
                For i=0 to n-1
                      IF a[i] = target
                      then
                            count++   
                      END IF
                END For
    
    • 二分查找
      • 适用于有序排列的数据
      • 即判断区间中间的数据是否为目标数据。若不为目标数据,判断该数据与目标数据的关系后,进入减半的区间,继续判断中间数据
      • 代码(查找目标数据,并返回下标)(以从小到大顺序排列的数组为例)
    
    int BinSearch(int a[99], int n, int key, int count)      
    {
        int locMin = 0;           //最小下标
        int locMax = n - 1;       //最大下标
        int mid;                  //中间下标
        while (locMin <= locMax)            //当最小下标不大于最大下标时,继续遍历数组
        {
            mid = (locMax + locMin) / 2;    //取查找区间内的中间下标
    
            if (a[mid] == key)              //找到目标数据时,返回目标数据的下标    
            {
                return mid; 
            }
          /*根据目标数据和中间数据的关系,重新确定查找的区间*/
            else
            {
                if (key < a[mid])            
                {
                    locMax = mid - 1;      
                }
    
                else if (key > a[mid])
                {
                    locMin = mid + 1;
                }
            }
        }
    
        return -1;      //循环结束后,若未找到目标数据,则返回负数。通过该函数的返回值,确定是否有目标数据存在于数组之中
    }
    

    2)插入数据

    • 伪代码(以升序排列为例)
          //①先查找到需要插入的位置
          For i = 0 to n-1
                IF putNum < a[i]
                   break跳出循环
                END IF
          END For
          //②再移动数组
          For j = n-1 to i
                a[j+1] = a[j]
          END For
          //③将需要插入的数据插入,并将表示数组数据个数的n加一
          a[i] = putNum
          n++
    
    • 流程图:

    3)删除数据

    • 原数组删除:删除数据较少时使用

      • (步骤1:删除一个目标数据)
      • 利用查找数据,找到需要删除数据的位置
      • 确定删除的数据位置后,将数组左移一位,覆盖掉要删除的数据
      • 最后将数组元素个数,n--
      • (步骤2:)
      • 循环步骤1,直到在数组中找不到目标数据。(可以使用flag,判断数组中是否找到目标数据)
      • 简易流程图:
    • 新构造数组:删除数据较多时使用

      • 新构造一个数组
      • 定义两个数组下标,一个为原数组的下标i,一个为重构数组的下标j
      • 遍历原数组进行判断,若数据不为要删除的目标数据,将数据写入新构造的数组中,并且此时新构造数组的下标自增
      • 简易流程图:

    4)排序方法

    • 冒泡排序
      • (步骤1:将两个相邻的数比较,先将一个最值“冒泡”,移到右边)
      • (步骤2:范围减小后,循环重复步骤1,将每个区间内的最值“冒泡”出去)
      • 代码:(以升序排列为例)
          int i,j;      //外循环控制次数,遍历的范围;内循环遍历数组
          int temp;
    
          for(i = 0; i < n-1; i++)                 //每执行一次冒泡,内循环的范围减小
          {
                for(j = 0; j < n-1-i; j++)         //通过逐个判断,将区间内的最大值移动到区间的最右边
                {
                      if(num[j] > num[j+1])      //逐个判断,若a[j+1] < a[j], 交换a[j] 和a[j+1]
                      {
                            temp = num[j];
                            num[j] = num[j+1];
                            num[j+1] = temp;
                      }
                }
           }
    
    • 选择排序
      • (步骤1:遍历数组,选择出最值,将最值放到指定位置)
      • (步骤2:范围减小,循环重复步骤1)
      • 代码:(以升序排列为例)
          int i,j;
          int minloc;           //最小值的下标       
          int temp;
    
          for(i = 0; i < n-1; i++)
          {
                minloc = i;      //使最小值的下标等于内循环开始时,数组的下标
                for(j = i; j < n; j++)      //从num[i]开始遍历数组,找到区间内的最小下标   
                {
                      if(num[minloc] > num[j])
                      {
                            minloc = j;
                      }
                }
                
                temp = num[i];            //交换,将范围内最小值与a[i]交换
                num[i] = num[minloc];
                num[minloc] = temp;
          }
    

    5)数组统计

    • 思路:
      • 循环步骤1
      • 步骤1:输入数据,将该数据作为静态数组的下标,该下标对应的数据自增
    • 代码:
          static int vote[1000];    //定义静态数组,使数组各项为0
    
          for(i=0; i<n; i++)
          {
              scanf("%d",&num);     //输入需要统计的数据
              vote[num]++;          //将该数据作为静态数组下标。每次出现时,vote[]对应的值加1,统计出数据出现的次数  
          }
    
    
    • 案例一:7-4 点赞
    • 案例二:7-5 调查电视节目受欢迎程度

    6)哈希数组

    • 用法
      • 定义静态数组int hash[256],
      • 与投票类似,将输入的数据作为hash[]数组的下标
      • 出现的数据对应下标的数组数据 = 1
      • 遍历数组,输出值等于1,对应的下标
      • 这样就完成了删除重复的数据,并将数据按照ASCII码排序
    • 案例
      • 删除重复数据,并按照ASCII码升序排列(伪代码)
          定义 static int hash[256] //因为ASCII码的范围为[0,255],共256个元素
          输入要输入的数据数 n
          For i = 0 tp n-1
          {
                输入数据 str
                hash[str] = 1;      //将str对应下标的数组赋值为1。用于接下来判断数据是否存在
          }
          END For
          
          For i = 0 to 255          //遍历hash数组,输出出现的数据
          {
                IF hash[i] = 1
                than
                      输出i         //也可以在定义一个新的数组,将i的值放入新的数组中
                END IF
          }
          END For      
    

    7)二维数组

    • 二维数组特点:
      • 定义: 类型名 数组名[行长度][列长度]
      • 存放:二维数组在内存中是按行连续存放的
      • 赋初值:
        分行赋初值: int num[2][2] = {{1}, {2,1}};
        顺序赋初值: int num[2][2] = {1, 0, 2, 1};
      • 省略行长度:
        对所有元素都赋了初值
        分行赋值中,列出了所有行 int num[ ][3] = {{1, 2}, { }};
      • 根据题意,理清行(i)与列(j)的关系,有利于解决关于二维数组的图形问题

    8)字符数组

    • 字符串特点

      • 字符串是特殊的一维数组,需要用一维数组来存放

      • 字符串的末尾有结束标志'',而''之后的其它数组元素与字符串无关

      • 与数字数组相比,字符数组并不需要明确的有效元素个数作为循环的限制条件。

      • 字符数组的限制条件一般为结束标志''。当用fgets输入字符串时,字符串末尾往往会接一个' ',再接上结束标志,这种情况结束条件要适当改变
        条件:while(str[i]) 或者 while(str[i] && str[i] != ' ')

    • 需注意事项

      • 区分"a"和'a'
        初始化:char str[6] = "a"; //其中"a"为字符串
        赋值: str[0] = 'a'; //其中'a'为字符

      备注:初始化——> str[0] = 'a'; str[1] = ''

      • 字符串的输入:
        注意空格:scanf(输入的字符串(%s)不能含有空格,scanf遇到空格时停止输入)
        注意回车:fgets(输入的字符串遇到回车时结束,但如果输入的元素加上结束标志没有填满数组,则数组结束标志前还会有一个换行符(' ')
        注意结束标志:循环getchar()输入(逐个输入字符构成字符数组,但在输入完成后,需记住在末尾添加结束标志


    2. PTA实验作业

    2.1 数组左移

    • 2.1.1 伪代码
            输入数组元素个数n,左移位数moveNum
            moveNum = moveNum % n        //解决位移位数不小于元素个数的情况。若左移位数与元素个数相等,则不进行位移。若位移位数大于元素个数,则将位移位数为原来位移位数与元素个数的余数
            定义一个新数组tempNum[moveNum]
            For i = 0 to moveNum         //原数组的前几位放入新数组中               
            {
                 tempNum[i] = moveNum[i];
            }
            END For
    
          For  i = moveNum to n - 1
          {
    		number[i - moveNum] = number[i];      //数组内后几位数前移
    	}
            END For
    
           For  (j = 0, i = n - moveNum; i < n; i++, j++)
    	{
    		number[i] = temp[j];
    	}
            END For
    
    • 2.1.2 代码截图


    • 2.1.3 同学的代码
    #include <stdio.h>
    #define MAXN 100
    
    int ArrayShift( int a[], int n, int m );
    
    int main()
    {
        int a[MAXN], n, m;
        int i;
    
        scanf("%d %d", &n, &m);
        for ( i = 0; i < n; i++ ) scanf("%d", &a[i]);
    
        ArrayShift(a, n, m);
    
        for ( i = 0; i < n; i++ ) {
            if (i != 0) printf(" ");
            printf("%d", a[i]);
        }
        printf("
    ");
    
        return 0;
    }
    
    int ArrayShift(int a[], int n, int m)
    {
    	for (int i = 0; i < m; i++)
    	{
    		int temp = a[n - 1];
    		a[n - 1] = a[0];
    		for (int A = 0; A < n - 2; A++)
    		{
    			a[A] = a[A + 1];
    		}
    		a[n - 2] = temp;
    	}
        return 1;
    }
    
    • 优点:
      同学:

      • 代码思路清晰,可读性强,易于理解
      • 代码简洁明了
    • 不足:
      同学:

      • 注释较少
        自己:
      • 代码冗长
      • 定义的全局变量过多
      • 函数形参的设置有所不足,应该使用形参将需要的参数传入函数,而不是过多地定义全局变量
      • 函数的返回类型。该代码中函数的返回类型多为void,所做的仅仅是将代码切分开来,没有很好地利用函数的返回值

    2.2 阅览室

    • 2.2.1 伪代码
          /*数据表达*/
    /*需要输入的变量*/
          定义 dayNum bookNum ch hh mm
    
          定义静态数组 lend[1001][2] 
          定义静态数组 back[1001][2] 
          // lend[][0] 放置是否借书
          // lend[][1] 放置借书的时间
    
    /*与时间计算相关的变量*/
          定义 sumtime //存放总时间
          定义 times   //存放次数
          定义 avgTime //存放平均时间     
    
          定义bookMax  //最大书号
    
          /*数据处理*/
          For i = 0 to dayNum - 1
          {
                
                      /*重置一些变量的值*/
                      清空数组lend[][]
                      清空数组book[][]
                      bookMax = 0;
                      times = 0;
                      sumTime = 0;
                
                      while(1)
                      {
                          输入书号 bookNum
                            输入借出或归还 ch
                            输入时间 hh:mm
                            
                            IF bookMax < bookNum
                            then 
                                  bookMax = bookNum
                            END IF
                      
                            IF bookNum = 0
                            then 
                                  break
                            END IF
    
                            IF ch = 'S' || ch = 'E'
                            then
                                  IF ch = 'S'
                                        lend[bookNum][1] = hh * 60 + mm /*存储时间(分钟)*/
                                        lend[bookNum][0] = 1     /*已借书*/
                                  END IF
    
                                  ELSE IF ch = 'E' && (back[bookNum][0] = 0 || back[bookNum][1] < lend[bookNum][1])
                                  then
                                        存储时间(分钟)
                                        back[bookNum][0] = 1     /*已还书*/
                                  END IF
                            END IF
                                  
                            /*借出并归还,且时间合法时*/
                            IF lend bookNum][0] == 1 && back[bookNum][0] == 1 && back[bookNum][1] >= lend[bookNum][1]		
                            then
                                  sumTime += back[bookNum][1] - lend[bookNum][1]; // 计算借阅时间的总和   
                   	              times++;      //次数累计
    
                  		      lend[bookNum][0] = back[bookNum][0] = 0;      //将借阅判断归零
                            END IF
                      }           
                      END while
    、
                            输出借阅总时间和次数
          }
          END For
                                   
    
    • 2.2.2 代码截图





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

      • 超星:
        1.将每天借阅记录存放在二维数组之中
        2.思路清晰,代码简洁明了

      • 自己:
        不足
        1.没有使用二维数组存放阅读记录
        2.代码冗长

    2.3 切分表达式

    • 2.3.1 伪代码
          定义 flag //判断是否为”首个“数字
          定义 sign //判断是否为负数、正数
    
          For i = 0 to str[i] = '
    '
                IF flag = 1		//判断首个数字是否为带符号的正负数
                then
                      IF str[i] = '-'
                      then 
                            sign = 1;
    		  END IF
    
                      ELSE IF str[i] = '+'
                      then
                            sign = 2;
                      END IF
                END IF
                
                flag = 0
          
                IF str[i]为0~9的字符
                then
                      将str[i]转化为数字,赋道number中
                
                IF str[i+1]不为0~9的字符
                then 
                      IF str[i+] = '.'
                      then
                            通过sign判断首个数字有没有带有正负号
                            IF sign = 1 || sign = 2
                            then
                                  通过switch分支,将输出的number前填上‘+'或’-‘,输出的number不换行
                            END IF
                            
                            ELSE       
                            then
                                  输出number不换行
                            END IF
                       END IF
                       ELSE
                       then
                            直接输出number,并换行     
                            
                            number = 0;
    			sign = 0;       //变量归零
                       END IF
                END IF
    
                ELSE
                      IF sign = 0
                      then      
                            IF str[i] = '.'
                            then      
                                  输出小数点,不换行
                            END IF
                            
                            ELSE 
                            then
                                  输出字符,换行
                            END IF
    
                            IF str[i] = 40 //左括弧的ASCII码值
                            then
                                  flag = 1
                            END IF
                      END IF
                END IF
    
    • 2.3.2 代码截图




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

      • 超星:
        1.遇到数字或小数点,或是符号位的+、-,直接输出不换行
      • 自己:
        不足
        1.将字符数字转化为了数值,未考虑到可以直接输出,导致代码冗长
        2.多判断了符号位的+、-,将+、-连同数值一起输出
  • 相关阅读:
    2019-2020-1学期 20192426 《网络空间安全导论》第九周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第八周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第七周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第六周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第五周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第四周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第三周学习总结
    2019-2020-1学期 20192426 《网络空间安全导论》第二周学习总结
    1924班小组讨论 组员:袁浩然 公凯文 张纹豪 马一 张家华
    20192414 2019-2020-1学期 《网络空间安全导论》第九周学习报告
  • 原文地址:https://www.cnblogs.com/welcome-to-tomorrow/p/14130859.html
Copyright © 2011-2022 走看看