第六章:数组

6-1 数组

题目:让用户输入一组整数以-1结束输入,算出这组数的平均值,并且输出大于平均值的数。

  • 我们需要记录用户所有输入的数字才能在判断出平均值后输出大于平均值的数,这里要用到一个新的数据类型数组。

程序实现:

  1. #ifndef biggerThanAvg_h
  2. #define biggerThanAvg_h
  3. #include <stdio.h>
  4. void biggerThanAvg(void);
  5. #endif
  6. #include "biggerThanAvg.h"
  7. void biggerThanAvg(void)
  8. {
  9. int x;
  10. double sum = 0;
  11. double avg = 0;
  12. int cnt = 0;
  13. int number[100];
  14. printf("请输入一些整数以-1结束:");
  15. scanf("%d", &x);
  16. while (x != -1)
  17. {
  18. number[cnt] = x;
  19. sum += x;
  20. cnt++;
  21. scanf("%d", &x);
  22. }
  23. if (cnt > 0)
  24. {
  25. avg = sum / cnt;
  26. printf("%f\n", avg);
  27. for (int i = 0; i < cnt; i++)
  28. {
  29. if (number[i] > avg)
  30. {
  31. printf("%d\n", number[i]);
  32. }
  33. }
  34. }
  35. }
  36. #include <stdio.h>
  37. #include "biggerThanAvg.h"
  38. int main(int argc, char *argv[])
  39. {
  40. biggerThanAvg();
  41. return 0;
  42. }

测试样例:

  1. 请输入一些整数以-1结束:1 2 3 4 5 6 7 8 9 -1
  2. 5.000000
  3. 6
  4. 7
  5. 8
  6. 9
  7. --------------------------------
  8. Process exited after 9.368 seconds with return value 0

定义数组

  • <类型>变量名称[元素数量];
  • int grades[100];
  • double weight[20];
  • 元素数量必须是整数
  • C99之前:元素数量必须是编译时刻确定的字面量、常量

数组

  • 是一种容器(放东西的东西),特点是:

    • 其中所有的元素具有相同的数据类型
    • 一旦创建,不能改变大小
    • (数组中的元素在内存中是连续依次排列的)

数组的单元

  • 数组的每个单元就是数组类型的一个变量
  • 使用数组时放在[]中的数字叫做下标或索引,下标从0开始计数:
    • grades[0]
    • grades[99]
    • average[5]

有效的下标范围

  • 编译器和运行环境都不会检查数组下标是否越界,无论是对数组单元做读还是写
  • 一旦程序运行,越界数组可能造成问题,导致程序崩溃
    • segmentation fault
  • 但是也可能运气好,没造成严重的后果
  • 所以这是程序员的责任来保证程序只使用有效的下标值:[0,数组的大小 - 1]

使用数组程序的对应操作

  1. 数组大小
  2. 定义数组
  3. 初始化数组
  4. 数组参与运算
  5. 遍历数组输出

6-2 数组计算

数组初始化

  • 数组的集成初始化

    • int a[] = {2,4,5,7,3,4,5,6,7};
  • 集成初始化时的定位C99 ONLY
    • int a[10] = {

      [0] = 2, [2] = 3, 6,

      ]
  • 用[n]在初始化数据中给出定位
  • 没有定位的数据接在前面的位置后面,比如6就接在3的位置
  • 其他位置的值补零
  • 也可以不给出数组大小让编译器算
  • 特别适合初始数据稀疏的数组

数组的大小

  • sizeof给出整个数组所占据的内容的大小,单位是字节

    • sizeof(a)/sizeof(a[0])
  • sizeof(a[0])给出数组中单个元素的大小,于是相除就得到了数组的单元个数
  • 这样的代码,一旦修改数组中初始的数据,不需要修改遍历的代码

数组的赋值

  • 数组遍历本身不能被赋值
  • 要把一个数组的所有元素交给另一个数组,必须采用遍历
    • for (i=0; i<length; i++){ b[i] = a[i]; }

遍历数组

  • 通常都是使用for循环,让循环变量i从0到小于数组的长度,这样循环体内最大的i正好是数组最大的有效下标
  • 常见的错误是:
    • 循环结束条件是小于等于数组长度,或;
    • 离开循环后,继续用i的值来做数组元素的下标

*数组传参

  • 数组作为函数参数时,往往必须再用另一个参数来传入数组的大小
  • 数组在作为函数参数时:
    • 不能在[]中给出数组的大小
    • 不能再利用sizeof来计算数组元素个数

二维数组的初始化

int a[][5] ={

{0,1,2,3,4},

{2,3,4,5,6}

}

  • 列数是必须给出的,行数可以由编译器来数
  • 每行一个{},逗号分隔
  • 最后的逗号可以存在,有古老的传统
  • 如果省略,表示补零
  • 也可以用定位(* C99 ONLY)

6.3 课后习题

1、题目内容: 题目内容:

一个多项式可以表达为 x 的各次幂与系数乘积的和,比如:

2χ 6 +3χ 5 +12χ 3 +6χ+20

现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系

数相加然后输出。

程序要处理的幂最大为 100。

输入格式:

总共要输入两个多项式,每个多项式的输入格式如下:

每行输入两个数字,第一个表示幂次,第二个表示该幂次的系数,所有的系数都是整数。第

一行一定是最高幂,最后一行一定是 0 次幂。

注意第一行和最后一行之间不一定按照幂次降低顺序排列;如果某个幂次的系数为 0,就不

出现在输入数据中了;0 次幂的系数为 0 时还是会出现在输入数据中。

输出格式:

从最高幂开始依次降到 0 幂,如:

2x6+3x5+12x3-6x+20

注意其中的 x 是小写字母 x,而且所有的符号之间都没有空格,如果某个幂的系数为 0 则

不需要有那项。

输入样例:

6 2

5 3

3 12

1 6

0 20

6 2

5 3

2 12

1 6

0 20

输出样例:

4x6+6x5+12x3+12x2+12x+40

题目分析:

  • 求和其实就是将相同幂的常数项相加。
  • 要处理的最大的幂为100个
  • 可以用一个长度为100数组arr来存储两个多项式D1和D2的结果。
  • 用户第一次输入 0 n 代表第一个多项式结束,第二次输入 0 n代表第二个多项式结束
  • 我们用arr[0]表示多项式的系数为0的这个项的系数,1表示系数为1这个项的系数依此类推
  • 用户每输入一个多项式,根据幂次m将系数累加到对应的arr[m]中,直到用户输入完所有的多项式。
  • 最后从最高的系数开始输出整个多项式,如果某个幂次系数为0则不做输出,系数为0的幂次代表这个幂次下没有多项式。因此我们在做累加时需要记录最高的系数,以便输出。

程序实现:

  1. #include <stdio.h>
  2. #include "sumOfPolynomial.h";
  3. int main(int argc, char *argv[])
  4. {
  5. sumOfPolynomial();
  6. return 0;
  7. }
  8. #ifndef sumOfPolynomial_h
  9. #define sumOfPolynomial_h
  10. #include <stdio.h>
  11. void sumOfPolynomial(void);
  12. #endif
  13. #include "sumOfPolynomial.h"
  14. void sumOfPolynomial(void)
  15. {
  16. int arr[100] = {0};
  17. int polynomialIndex = 0; //为2时终止循环
  18. int power = 0; //幂次
  19. int coefficient = 0; //系数
  20. int maxPower = 0; //最高幂
  21. int i;
  22. printf("请输入两个多项式,幂次和系数以空格分开,幂次从高到低最后一项是0次幂:\n");
  23. //输入累加求和
  24. do
  25. {
  26. scanf("%d %d", &power, &coefficient);
  27. if (power == 0)
  28. {
  29. polynomialIndex++;
  30. }
  31. if (power > maxPower)
  32. {
  33. maxPower = power;
  34. }
  35. arr[power] += coefficient;
  36. } while (polynomialIndex < 2);
  37. //输出结果
  38. for (i = maxPower; i > -1; i--)
  39. {
  40. if (arr[i] > 0)
  41. {
  42. if (i == 0)
  43. {
  44. printf("%d", arr[i]);
  45. }
  46. else
  47. {
  48. if (i == 1)
  49. {
  50. printf("%dx", arr[i]);
  51. }
  52. else
  53. {
  54. printf("%dx%d", arr[i], i);
  55. }
  56. }
  57. }
  58. //不是最后一项且下一项的系数大于0才拼接加号
  59. if (i > 0 && arr[i - 1] > 0)
  60. {
  61. printf("+");
  62. }
  63. }
  64. printf("\n");
  65. }

测试样例:

  1. 请输入两个多项式,幂次和系数以空格分开,幂次从高到低最后一项是0次幂:
  2. 6 2
  3. 5 3
  4. 3 12
  5. 1 6
  6. 0 20
  7. 6 2
  8. 5 3
  9. 3 12
  10. 1 6
  11. 2 3
  12. 0 20
  13. 4x6+6x5+24x3+3x2+12x+40
  14. --------------------------------
  15. Process exited after 40.41 seconds with return value 0
  16. 请输入两个多项式,幂次和系数以空格分开,幂次从高到低最后一项是0次幂:
  17. 2 6
  18. 0 0
  19. 3 6
  20. 0 0
  21. 6x3+6x2
  22. --------------------------------
  23. Process exited after 21.46 seconds with return value 0

2、题目内容:

给定一个 n*n 矩阵 A。矩阵 A 的鞍点是一个位置(i,j),在该位置上的元素是第 i 行上的

最大数,第 j 列上的最小数。一个矩阵 A 也可能没有鞍点。

你的任务是找出 A 的鞍点。

输入格式:

输入的第 1 行是一个正整数 n, (1<=n<=100),然后有 n 行,每一行有 n 个整数,同

一行上两个整数之间有一个或多个空格。

输出格式:

对输入的矩阵,如果找到鞍点,就输出其下标。下标为两个数字,第一个数字是行号,第二

个数字是列号,均从 0 开始计数。

如果找不到,就输出

NO

题目所给的数据保证了不会出现多个鞍点。

输入样例:

4

1 7 4 1

4 8 3 6

1 6 1 2

0 7 8 9

输出样例:

2 1

题目分析:

  • 既然是一个n*n的矩阵,我们可以用一个二维数组arr[n][n]来存储这个矩阵。
  • 鞍点是i行上最大的数,j列上最小的数。
  • 获取一行中最大的数num,再判断num是否该列最小的数如果是则为此矩阵的一个鞍点,否则继续判断下一行。

程序实现:

  1. #include <stdio.h>
  2. #include "getSaddlePointOfMatrix.h"
  3. int main(int argc, char *argv[])
  4. {
  5. getSaddlePointOfMatrix();
  6. return 0;
  7. }
  8. #ifndef getSaddlePointOfMatrix_h
  9. #define getSaddlePointOfMatrix_h
  10. #include <stdio.h>
  11. #include <limits.h>
  12. void getSaddlePointOfMatrix(void);
  13. int getMaxNumberColIndexByRow(int arr[4][4], int rowIndex, int colCount);
  14. int getMinNumberByCol(int arr[4][4], int colIndex, int rowCount);
  15. #endif
  16. #include "getSaddlePointOfMatrix.h"
  17. //获取一行中最大值的列坐标
  18. int getMaxNumberColIndexByRow(int arr[4][4], int rowIndex, int colCount)
  19. {
  20. int maxNumber = INT_MIN;//int最小值
  21. int maxColIndex = 0;
  22. int i;
  23. for (i = 0; i < colCount; i++)
  24. {
  25. if (arr[rowIndex][i] > maxNumber)
  26. {
  27. maxNumber = arr[rowIndex][i];
  28. maxColIndex = i;
  29. }
  30. }
  31. return maxColIndex;
  32. }
  33. //获取一列中最小的值
  34. int getMinNumberByCol(int arr[4][4], int colIndex, int rowCount)
  35. {
  36. int minNumber = INT_MAX;//int最大值
  37. int i;
  38. for (i = 0; i < rowCount; i++)
  39. {
  40. if (arr[i][colIndex] < minNumber)
  41. {
  42. minNumber = arr[i][colIndex];
  43. }
  44. }
  45. return minNumber;
  46. }
  47. void getSaddlePointOfMatrix(void)
  48. {
  49. int i, j;
  50. int rowIndex, colIndex;
  51. int maxRowNumber = 0;
  52. int minColNumber = 0;
  53. int n = 4;
  54. int isHaveSaddlePoint = 0;
  55. int arr[4][4] = {
  56. {1, 7, 4, 1},
  57. {4, 8, 3, 6},
  58. {1, 6, 1, 2},
  59. {0, 7, 8, 9}};
  60. //判断每一行的最大值是否为该列的最小值
  61. for (i = 0; i < n; i++)
  62. {
  63. colIndex = getMaxNumberColIndexByRow(arr, i, n);
  64. maxRowNumber = arr[i][colIndex];
  65. minColNumber = getMinNumberByCol(arr, colIndex, n);
  66. if (maxRowNumber == minColNumber)
  67. {
  68. isHaveSaddlePoint = 1;
  69. rowIndex = i;
  70. break;
  71. }
  72. }
  73. if (isHaveSaddlePoint)
  74. {
  75. printf("%d %d\n", rowIndex, colIndex);
  76. }
  77. else
  78. {
  79. printf("NO\n");
  80. }
  81. }

tips:这里为了方便测试将数组写死在程序了,你可以试着把这个改为用户输入。

** 思考**

  • 是否也可以先求每一列的最小数,让后判断该数是否是所在行最大的数呢?
  • 这里的算法复杂度O=n2 ,是否有算法复杂度为logn的算法呢?
  • 这里只求了一个鞍点,如果有多个鞍点时如何改进我们的算法使得可以计算多个鞍点呢?

测试样例:

  1. 2 1
  2. --------------------------------
  3. Process exited after 0.1303 seconds with return value 0

程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)的更多相关文章

  1. 程序设计入门-C语言基础知识-翁恺-第四周:循环控制-详细笔记(四)

    目录 第四周:循环控制 4-1 for循环 4-2 循环控制 各运算符优先级(图) 4-3 课后习题 4-4 讨论题 第四周:循环控制 4-1 for循环 for循环像一个计数循环:设定一个计数器,初 ...

  2. 程序设计入门-C语言基础知识-翁恺-第七周:指针与字符串-详细笔记(七)

    目录 第七周:指针与字符串 7.1 指针初步 7.2 字符类型 7.3 字符串 7.3 课后练习 第七周:指针与字符串 7.1 指针初步 sizeof 是一个运算符,给出某个类型或变量在内存中所占据的 ...

  3. 程序设计入门-C语言基础知识-翁恺-第五周:函数-详细笔记(五)

    目录 第五周:函数 5.1 函数 5-2 使用函数 5.3 课后习题 第五周:函数 5.1 函数 什么是函数? 函数是一块代码,接受零个或多个参数,做一件事情,并返回零个或一个值. 函数声明语法 返回 ...

  4. 程序设计入门-C语言基础知识-翁恺-第三周:循环-详细笔记(三)

    目录 第三周:循环 3.1 循环 3.2 循环计算 3.3 课后习题 3.4 讨论题(不需要掌握) 第三周:循环 3.1 循环 while循环 语法: while(条件表达式){ //循环体语句 } ...

  5. 程序设计入门-C语言基础知识-翁恺-期中测试

    一.试题 程序设计入门—C 语言期中测评 试题下载地址: http://nos.netease.com/edu-lesson-pdfsrc/217E194E46A6595A3F554380337490 ...

  6. 程序设计入门-C语言基础知识-翁恺-第一周:简单的计算程序-详细笔记(一)

    目录 第一周:简单的计算程序 1.1 第一个程序 Hello World! 1.2 变量 1.3 计算 1.4 编程作业及课后讨论 第一周:简单的计算程序 1.1 第一个程序 Hello World! ...

  7. 程序设计入门-C语言基础知识-翁恺-第二周:简单的计算程序-详细笔记(二)

    目录 第二周:判断 2.1 比较 2.2 判断 2.3 课后习题 第二周:判断 2.1 比较 简单的判断语句: if(条件成立){ //执行代码 } 条件 计算两个值之间的关系,所以叫做关系运算 关系 ...

  8. Golang 入门系列(三)Go语言基础知识汇总

    前面已经了 Go 环境的配置和初学Go时,容易遇到的坑,大家可以请查看前面的文章 https://www.cnblogs.com/zhangweizhong/category/1275863.html ...

  9. 程序设计入门——C语言 习题汇总

    <img width="108" height="40" alt="浙江大学" src="http://imgsize.ph ...

随机推荐

  1. 用 SqlConnectionStringBuilder 来写连接字符串,向连接字符串添加设置

    正常情况下写的连接字符串: connStr = "Data Source=127.0.0.1;DataBase=Hydor;UID=***;PWD=***;Pooling=true;Min ...

  2. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  3. ubuntu install vue , vue-cli , how to create project..

    <<install node.js <<the n model is manage the node.js version npm install -g n n stable ...

  4. hibernate:inverse、cascade,一对多、多对多详解

    1.到底在哪用cascade="..."? cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所 ...

  5. 【Python】@staticmethod和@classmethod的作用与区别

    前言 Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法.而使用@static ...

  6. 构建hadoop集群时遇到的问题

    在构建hadoop集群时,出现过主节点中的namenode或datanode启动不成功的问题.在日志文件中往往会显示namenode和datanode中clusterID不相同的问题,这个问题往往都是 ...

  7. mysql数据库开放远程连接的方法

    web与mysql数据库分离开来是一个不错的选择,避免因为大量的数据库查询占用CPU而使web资源不足,同时可以使web服务器的资源尽最大的提供浏览服务,而数据库服务器单独的只处理数据库事物. 适用范 ...

  8. 工作流引擎Activiti使用总结(转)

    1.简单介工作流引擎与Activiti 对于工作流引擎的解释请参考百度百科:工作流引擎 1.1 我与工作流引擎 在第一家公司工作的时候主要任务就是开发OA系统,当然基本都是有工作流的支持,不过当时使用 ...

  9. Android和iOS中Cocos2dx的横屏竖屏设置

    一.横屏.竖屏设置 1.android AndroidManifest.xml文件中, screenOrientation="landscape" 为横屏, screenOrien ...

  10. LabVIEW之生产者/消费者模式--队列操作

    LabVIEW之生产者/消费者模式--队列操作 彭会锋 本文章主要是对学习LabVIEW之生产者/消费者模式的学习笔记,其中涉及到同步控制技术-队列.事件.状态机.生产者-消费者模式,这几种技术在在本 ...