程序設計入門-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以前:元素數量必須是編譯時刻肯定的字面量、常量

數組code

  • 是一種容器(放東西的東西),特色是:
    • 其中全部的元素具備相同的數據類型
    • 一旦建立,不能改變大小
    • (數組中的元素在內存中是連續依次排列的)

數組的單元索引

  • 數組的每一個單元就是數組類型的一個變量
  • 使用數組時放在[]中的數字叫作下標或索引,下標從0開始計數:
    • grades[0]
    • grades[99]
    • average[5]

有效的下標範圍ip

  • 編譯器和運行環境都不會檢查數組下標是否越界,不管是對數組單元作讀仍是寫
  • 一旦程序運行,越界數組可能形成問題,致使程序崩潰
    • segmentation fault
  • 可是也可能運氣好,沒形成嚴重的後果
  • 因此這是程序員的責任來保證程序只使用有效的下標值:[0,數組的大小 - 1]

使用數組程序的對應操做內存

  1. 數組大小
  2. 定義數組
  3. 初始化數組
  4. 數組參與運算
  5. 遍歷數組輸出

6-2 數組計算

數組初始化ci

  • 數組的集成初始化
    • 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 課後習題

一、題目內容: 題目內容:
一個多項式能夠表達爲 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

二、題目內容:
給定一個 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
相關文章
相關標籤/搜索