程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)-程序员宅基地

技术标签: c/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]

使用数组程序的对应操作

  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的幂次代表这个幂次下没有多项式。因此我们在做累加时需要记录最高的系数,以便输出。

程序实现:

#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

转载于:https://www.cnblogs.com/simple-blog/p/9534037.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30493401/article/details/96944990

智能推荐

监听网络变化--含7.0以上适配_android.net.conn.connectivity_change-程序员宅基地

文章浏览阅读3.7k次,点赞3次,收藏7次。我们知道最早监听网络变化,是通过广播,静态或动态注册广播,处理"android.net.conn.CONNECTIVITY_CHANGE"这个action就可以了intent就可以了。我们发现"android.net.conn.CONNECTIVITY_CHANGE"这个action已经加了注解@Deprecated,不推荐使用了。根据注释说明,7.0及以上静态注册广播(manifest中)..._android.net.conn.connectivity_change

计算机学习目标_bytetrack+yolov5 c++-程序员宅基地

文章浏览阅读291次。开个坑_bytetrack+yolov5 c++

fatal error: filesystem: 没有那个文件或目录_fatal error: filesystem: no such file or directory-程序员宅基地

文章浏览阅读4.8k次,点赞12次,收藏39次。fatal error: filesystem: 没有那个文件或目录_fatal error: filesystem: no such file or directory

2020起重机械指挥作业考试题库及起重机械指挥模拟考试系统_换算英制直径5分钢丝绳为公制多少毫米?()。-程序员宅基地

文章浏览阅读1k次。题库来源:安全生产模拟考试一点通公众号小程序2020起重机械指挥作业考试题库及起重机械指挥模拟考试系统,包含起重机械指挥作业考试题库答案解析及起重机械指挥模拟考试系统练习。由安全生产模拟考试一点通公众号结合国家起重机械指挥考试最新大纲及起重机械指挥考试真题出具,有助于起重机械指挥考试试题考前练习。1、【判断题】指挥人员负责对可能出现的事故采取必要的防范措施。(√)2、【判断题】手势信号包括通用手势信号、专用手势信号和其它指挥信号。()(×)3、【判断题】吊装用的短环链,不..._换算英制直径5分钢丝绳为公制多少毫米?()。

大数据应用丨大数据时代的医学公共数据库与数据挖掘技术简介_dryad数据库-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏25次。本文我们将介绍几种数据库和数据挖掘技术,帮助临床研究人员更好地理解和应用数据库技术。数据挖掘技术可以从大量数据中寻找潜在有价值的信息,主要分为数据准备、数据挖掘、以及结果表达和分析。数据库技术是研究、管理和应用数据库的一门软件科学。通过研究数据库的结构、存储、设计、管理和应用的基本理论和实现方法,对数据库中的数据进行处理和分析。_dryad数据库

随便推点

SpringBoot整合Elastic-job实现_springboot + elasticjob-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏13次。SpringBoot整合Elastic-job实现【基本整合】:原理参考:Elastic-Job原理(1)引用pom依赖:<dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-core</artifactId> <..._springboot + elasticjob

Attensleep:一种基于注意力的单通道EEG睡眠分期深度学习方法_an attention-based deep learning approach for slee-程序员宅基地

文章浏览阅读791次。AttenSleep 基于注意力的深度学习架构从单通道EEG信号中进行睡眠阶段分类从基于多分辨率卷积神经网络( MRCNN )和自适应特征重标定( AFR )的特征提取模块入手。MRCNN可以提取低频和高频特征,而AFR可以通过建模特征之间的相互依赖关系来提高提取特征的质量。第二个模块是时间上下文编码器( TCE ),它利用多头注意力机制来捕获提取特征之间的时间依赖关系。特别地,多头注意力利用因果卷积对输入特征中的时间关系进行建模。使用三个公共数据集来评估提出的AttnSleep模型的性能。_an attention-based deep learning approach for sleep stage classification wit

Myeclipse技巧-程序员宅基地

文章浏览阅读71次。在了解MyEclipse使用技巧之前我们来看看MyEclipse是什么呢?简单而言,MyEclipse是Eclipse的插件,也是一款功能强大的J2EE集成开发环境,支持代码编写、配置、测试以及除错。下面让我们看看MyEclipse使用技巧的具体内容。MyEclipse使用技巧第一步: 取消自动validationvalidation有一堆,什么xml、jsp、jsf..._myeclipse是什么

c语言统计数组每个数出现的次数,统计数组中某个元素出现的次数和重复的次数...-程序员宅基地

文章浏览阅读8.9k次。//出现的次数function times(arr){var m=0,times=0;//m是数组中的元素,times用来统计出现的次数// for循环遍历arr数组for(var i=0;iif(arr[i]==m){times++;//数组中有相同值就加1}}return times;console.log(times);//这是打印出的出现的次数}times([0, 1, 2, 0, 1, ..._c语言统计数组中每个数字出现的次数

Jmeter连接InfluxDB2.0.4_influxdborganization jmeter-程序员宅基地

文章浏览阅读2.5k次,点赞5次,收藏14次。Jmeter连接InfluxDB2.0.4问题描述:在用Jmeter+InfluxDB构建监控时,因为docker构建的InfluxDB的版本是2.0.4,按照网上的教程进行后端监听器的填写,但是一直出现错误提示401等问题。网上的教程大多是1.X版本的,怀疑是数据库版本不一致导致的数据无法写入,通过调研,问题已解决。以下为配置方法。一、InfluxDB搭建完成后,查看Organization和Bucket名称,这里是ORZ_test和bucket_nameOrganization在这里我的理解_influxdborganization jmeter

关于第三方支付,看这篇文章就够了!-程序员宅基地

文章浏览阅读1.6k次。目录 目录 1、第三方支付概述 2、第三方支付起源 PayPal 支付宝 3、牌照发放 4、支付牌照 5、第三方支付参与者 6、第三方支付行业监管 监管意图对第三方支付可能产生的影响..._第三方支付本行对本行的费用

推荐文章

热门文章

相关标签