程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)
目錄
- 第六章:數組
- 6-1 數組
- 6-2 數組計算
- 6.3 課后習題
第六章:數組
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 02、題目內容:
給定一個 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
總結
以上是生活随笔為你收集整理的程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Clang AST介绍
- 下一篇: js打字的效果