程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)
第六章:数组
6-1 数组
题目:让用户输入一组整数以-1结束输入,算出这组数的平均值,并且输出大于平均值的数。
- 我们需要记录用户所有输入的数字才能在判断出平均值后输出大于平均值的数,这里要用到一个新的数据类型数组。
程序实现:
#ifndef biggerThanAvg_h
#define biggerThanAvg_h
#include <stdio.h>
void biggerThanAvg(void);
#endif
#include "biggerThanAvg.h"
void biggerThanAvg(void)
{
int x;
double sum = 0;
double avg = 0;
int cnt = 0;
int number[100];
printf("请输入一些整数以-1结束:");
scanf("%d", &x);
while (x != -1)
{
number[cnt] = x;
sum += x;
cnt++;
scanf("%d", &x);
}
if (cnt > 0)
{
avg = sum / cnt;
printf("%f\n", avg);
for (int i = 0; i < cnt; i++)
{
if (number[i] > avg)
{
printf("%d\n", number[i]);
}
}
}
}
#include <stdio.h>
#include "biggerThanAvg.h"
int main(int argc, char *argv[])
{
biggerThanAvg();
return 0;
}
测试样例:
请输入一些整数以-1结束:1 2 3 4 5 6 7 8 9 -1
5.000000
6
7
8
9
--------------------------------
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]
使用数组程序的对应操作
- 数组大小
- 定义数组
- 初始化数组
- 数组参与运算
- 遍历数组输出
6-2 数组计算
数组初始化
- 数组的集成初始化
- int a[] = {2,4,5,7,3,4,5,6,7};
- 集成初始化时的定位C99 ONLY
- int a[10] = {
[0] = 2, [2] = 3, 6,
]
- int a[10] = {
- 用[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的幂次代表这个幂次下没有多项式。因此我们在做累加时需要记录最高的系数,以便输出。
程序实现:
#include <stdio.h>
#include "sumOfPolynomial.h";
int main(int argc, char *argv[])
{
sumOfPolynomial();
return 0;
}
#ifndef sumOfPolynomial_h
#define sumOfPolynomial_h
#include <stdio.h>
void sumOfPolynomial(void);
#endif
#include "sumOfPolynomial.h"
void sumOfPolynomial(void)
{
int arr[100] = {0};
int polynomialIndex = 0; //为2时终止循环
int power = 0; //幂次
int coefficient = 0; //系数
int maxPower = 0; //最高幂
int i;
printf("请输入两个多项式,幂次和系数以空格分开,幂次从高到低最后一项是0次幂:\n");
//输入累加求和
do
{
scanf("%d %d", &power, &coefficient);
if (power == 0)
{
polynomialIndex++;
}
if (power > maxPower)
{
maxPower = power;
}
arr[power] += coefficient;
} while (polynomialIndex < 2);
//输出结果
for (i = maxPower; i > -1; i--)
{
if (arr[i] > 0)
{
if (i == 0)
{
printf("%d", arr[i]);
}
else
{
if (i == 1)
{
printf("%dx", arr[i]);
}
else
{
printf("%dx%d", arr[i], i);
}
}
}
//不是最后一项且下一项的系数大于0才拼接加号
if (i > 0 && arr[i - 1] > 0)
{
printf("+");
}
}
printf("\n");
}
测试样例:
请输入两个多项式,幂次和系数以空格分开,幂次从高到低最后一项是0次幂:
6 2
5 3
3 12
1 6
0 20
6 2
5 3
3 12
1 6
2 3
0 20
4x6+6x5+24x3+3x2+12x+40
--------------------------------
Process exited after 40.41 seconds with return value 0
请输入两个多项式,幂次和系数以空格分开,幂次从高到低最后一项是0次幂:
2 6
0 0
3 6
0 0
6x3+6x2
--------------------------------
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是否该列最小的数如果是则为此矩阵的一个鞍点,否则继续判断下一行。
程序实现:
#include <stdio.h>
#include "getSaddlePointOfMatrix.h"
int main(int argc, char *argv[])
{
getSaddlePointOfMatrix();
return 0;
}
#ifndef getSaddlePointOfMatrix_h
#define getSaddlePointOfMatrix_h
#include <stdio.h>
#include <limits.h>
void getSaddlePointOfMatrix(void);
int getMaxNumberColIndexByRow(int arr[4][4], int rowIndex, int colCount);
int getMinNumberByCol(int arr[4][4], int colIndex, int rowCount);
#endif
#include "getSaddlePointOfMatrix.h"
//获取一行中最大值的列坐标
int getMaxNumberColIndexByRow(int arr[4][4], int rowIndex, int colCount)
{
int maxNumber = INT_MIN;//int最小值
int maxColIndex = 0;
int i;
for (i = 0; i < colCount; i++)
{
if (arr[rowIndex][i] > maxNumber)
{
maxNumber = arr[rowIndex][i];
maxColIndex = i;
}
}
return maxColIndex;
}
//获取一列中最小的值
int getMinNumberByCol(int arr[4][4], int colIndex, int rowCount)
{
int minNumber = INT_MAX;//int最大值
int i;
for (i = 0; i < rowCount; i++)
{
if (arr[i][colIndex] < minNumber)
{
minNumber = arr[i][colIndex];
}
}
return minNumber;
}
void getSaddlePointOfMatrix(void)
{
int i, j;
int rowIndex, colIndex;
int maxRowNumber = 0;
int minColNumber = 0;
int n = 4;
int isHaveSaddlePoint = 0;
int arr[4][4] = {
{1, 7, 4, 1},
{4, 8, 3, 6},
{1, 6, 1, 2},
{0, 7, 8, 9}};
//判断每一行的最大值是否为该列的最小值
for (i = 0; i < n; i++)
{
colIndex = getMaxNumberColIndexByRow(arr, i, n);
maxRowNumber = arr[i][colIndex];
minColNumber = getMinNumberByCol(arr, colIndex, n);
if (maxRowNumber == minColNumber)
{
isHaveSaddlePoint = 1;
rowIndex = i;
break;
}
}
if (isHaveSaddlePoint)
{
printf("%d %d\n", rowIndex, colIndex);
}
else
{
printf("NO\n");
}
}
tips:这里为了方便测试将数组写死在程序了,你可以试着把这个改为用户输入。
** 思考**
- 是否也可以先求每一列的最小数,让后判断该数是否是所在行最大的数呢?
- 这里的算法复杂度O=n2 ,是否有算法复杂度为logn的算法呢?
- 这里只求了一个鞍点,如果有多个鞍点时如何改进我们的算法使得可以计算多个鞍点呢?
测试样例:
2 1
--------------------------------
Process exited after 0.1303 seconds with return value 0
程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)的更多相关文章
- 程序设计入门-C语言基础知识-翁恺-第四周:循环控制-详细笔记(四)
目录 第四周:循环控制 4-1 for循环 4-2 循环控制 各运算符优先级(图) 4-3 课后习题 4-4 讨论题 第四周:循环控制 4-1 for循环 for循环像一个计数循环:设定一个计数器,初 ...
- 程序设计入门-C语言基础知识-翁恺-第七周:指针与字符串-详细笔记(七)
目录 第七周:指针与字符串 7.1 指针初步 7.2 字符类型 7.3 字符串 7.3 课后练习 第七周:指针与字符串 7.1 指针初步 sizeof 是一个运算符,给出某个类型或变量在内存中所占据的 ...
- 程序设计入门-C语言基础知识-翁恺-第五周:函数-详细笔记(五)
目录 第五周:函数 5.1 函数 5-2 使用函数 5.3 课后习题 第五周:函数 5.1 函数 什么是函数? 函数是一块代码,接受零个或多个参数,做一件事情,并返回零个或一个值. 函数声明语法 返回 ...
- 程序设计入门-C语言基础知识-翁恺-第三周:循环-详细笔记(三)
目录 第三周:循环 3.1 循环 3.2 循环计算 3.3 课后习题 3.4 讨论题(不需要掌握) 第三周:循环 3.1 循环 while循环 语法: while(条件表达式){ //循环体语句 } ...
- 程序设计入门-C语言基础知识-翁恺-期中测试
一.试题 程序设计入门—C 语言期中测评 试题下载地址: http://nos.netease.com/edu-lesson-pdfsrc/217E194E46A6595A3F554380337490 ...
- 程序设计入门-C语言基础知识-翁恺-第一周:简单的计算程序-详细笔记(一)
目录 第一周:简单的计算程序 1.1 第一个程序 Hello World! 1.2 变量 1.3 计算 1.4 编程作业及课后讨论 第一周:简单的计算程序 1.1 第一个程序 Hello World! ...
- 程序设计入门-C语言基础知识-翁恺-第二周:简单的计算程序-详细笔记(二)
目录 第二周:判断 2.1 比较 2.2 判断 2.3 课后习题 第二周:判断 2.1 比较 简单的判断语句: if(条件成立){ //执行代码 } 条件 计算两个值之间的关系,所以叫做关系运算 关系 ...
- Golang 入门系列(三)Go语言基础知识汇总
前面已经了 Go 环境的配置和初学Go时,容易遇到的坑,大家可以请查看前面的文章 https://www.cnblogs.com/zhangweizhong/category/1275863.html ...
- 程序设计入门——C语言 习题汇总
<img width="108" height="40" alt="浙江大学" src="http://imgsize.ph ...
随机推荐
- Graph_Master(连通分量_G_Trajan+Thought)
Graph_Master~(连通分量) 题目大意:给出m条边(隧道,无向),每条边连接两个点(矿场).要在这些矿场中建设救援出口,防止矿场坍塌造成人员伤亡,问最少需要几个救援出口,以及对应方案数.(假 ...
- 上采样和PixelShuffle(转)
有些地方还没看懂, mark一下 文章来源: https://blog.csdn.net/g11d111/article/details/82855946 去年曾经使用过FCN(全卷积神经网络)及其派 ...
- CBT怎样进行注册
CBT币未来升值千倍?揭秘为何比特云币注册认证送矿机? 比特云币先机先机,1月6号准备启动,虚拟货币新宠云比特(Cloud Bit 简称CBT)将于近日强势登陆交易市场.这款由全球最大的比特矿工联盟发 ...
- LDA学习之beta分布和Dirichlet分布
---恢复内容开始--- 今天学习LDA主题模型,看到Beta分布和Dirichlet分布一脸的茫然,这俩玩意怎么来的,再网上查阅了很多资料,当做读书笔记记下来: 先来几个名词: 共轭先验: 在贝叶斯 ...
- Vuex访问状态对象的方法
除了<Vuex最基本样例>中的方法外,还有两种方法访问状态对象state: 只需要改app.vue文件 方法一:引入computed <template> <div id ...
- JavaScript声明全局变量三种方式的异同
JavaScript中声明变量很简单var(关键字)+变量名(标识符). 方式1 1 2 var test; var test = 5; 需注意的是该句不能包含在function内,否则是局部变量.这 ...
- form表单提交数据的数据格式
form表单提交的数据格式默认是 enctype="application/x-www-form-urlencoded"这样将input框的数据与input框的name属性以键值对 ...
- mysql数据库优化课程---17、mysql索引优化
mysql数据库优化课程---17.mysql索引优化 一.总结 一句话总结:一些字段可能会使索引失效,比如like,or等 1.check表监测的使用场景是什么? 视图 视图建立在两个表上, 删除了 ...
- 新东方雅思词汇---9.1、sist
新东方雅思词汇---9.1.sist 一.总结 一句话总结: 站 resist 英 [rɪ'zɪst] 美 [rɪ'zɪst] vi. 抵抗,抗拒:忍耐 vt. 抵抗:忍耐,忍住 n. [助剂] ...
- DataContext的在控件树上的传递
控件树,在树上的每一个分支,包括叶子(比如:grid,stackpanel,lable,TextBlock)等,都有DataContext属性,并且该值可以实现从“外层”向内层传递 <Grid ...