MOOC哈工大2020C語言程序設計精髓練兵區編程題第十一周


1 找出按字典順序排在最前面的國名(4分)

題目內容:

輸入5個國名,編程找出並輸出按字典順序排在最前面的國名。

提示:所謂字典順序就是將字符串按由小到大的順序排列,因此找出按字典順序排在最前面的國名指的就是最小的字符串。

int main()
{
    char c[5][11];
    int result = 0;
    printf("Input five countries' names:\n");
    for (int i = 0; i < 5; ++i)
    {
        gets(c[i]);
    }
    for (int i = 0; i < 5; ++i)
    {
        if (strcmp(c[result], c[i]) > 0)
        {
            result = i;
        }
    }
    printf("The minimum is:%s\n", c[result]);
    return 0;
}

2 學生成績管理系統V2.0(4分)

題目內容:

某班有最多不超過30人(具體人數由鍵盤輸入)參加某門課程的考試,參考前面章節的“學生成績管理系統V1.0”,用一維數組和函數指針作函數參數編程實現如下菜單驅動的學生成績管理系統:

(1)錄入每個學生的學號和考試成績;

(2)計算課程的總分和平均分;

(3)按成績由高到低排出名次表;

(4)按成績由低到高排出名次表;

(5)按學號由小到大排出成績表;

(6)按學號查詢學生排名及其考試成績;

(7)按優秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5個類別,統計每個類別的人數以及所占的百分比;

(8)輸出每個學生的學號、考試成績。

要求程序運行后顯示的菜單如下:

1.Input record

2.Caculate total and average score of course

3.Sort in descending order by score

4.Sort in ascending order by score

5.Sort in ascending order by number

6.Search by number

7.Statistic analysis

8.List record

0.Exit

Please enter your choice:

然后,根據用戶輸入的選項執行相應的操作。

#define N 30

//打印選項菜單
void PrintMenu();

//錄入每個學生的學號和考試成績;
void InputRecord(long id[], float scores[], int n);

//計算課程的總分和平均分;
void CalculateTotalAndAverageScoreOfCourse(float scores[], int n);

//按成績由高到低排出名次表;
void SortInDescendingOrderByScore(long id[], float scores[], int n);

//按成績由低到高排出名次表;
void SortInAscendingOrderByScore(long id[], float scores[], int n);

//按學號由小到大排出成績表
void SortInAscendingOrderByNumber(long id[], float scores[], int n);

//按學號查詢學生排名及其考試成績
void SearchByNumber(long id[],float scores[], int n);

//按優秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5個類別,統計每個類別的人數以及所占的百分比;
void StatisticAnalysis(float scores[], int n);

//輸出每個學生的學號、考試成績。
void ListRecord(long id[],float scores[], int n);

int main()
{
    int n, m;
    long id[N];
    float scores[N];
    printf("Input student number(n<30):\n");
    scanf("%d", &n);
    PrintMenu();
    while (scanf("%d", &m) && m != 0)
    {
        switch (m)
        {
            case 1:
                InputRecord(id, scores, n);
                break;
            case 2:
                CalculateTotalAndAverageScoreOfCourse(scores, n);
                break;
            case 3:
                SortInDescendingOrderByScore(id, scores, n);
                break;
            case 4:
                SortInAscendingOrderByScore(id, scores, n);
                break;
            case 5:
                SortInAscendingOrderByNumber(id, scores, n);
                break;
            case 6:
                SearchByNumber(id, scores, n);
                break;
            case 7:
                StatisticAnalysis(scores, n);
                break;
            case 8:
                ListRecord(id, scores, n);
                break;
            default:
                printf("Input error!\n");
        }
        PrintMenu();
    }
    printf("End of program!\n");
    return 0;
}

void PrintMenu()
{
    printf("Management for Students' scores\n"
           "1.Input record\n"
           "2.Caculate total and average score of course\n"
           "3.Sort in descending order by score\n"
           "4.Sort in ascending order by score\n"
           "5.Sort in ascending order by number\n"
           "6.Search by number\n"
           "7.Statistic analysis\n"
           "8.List record\n"
           "0.Exit\n"
           "Please Input your choice:\n");

}
void InputRecord(long id[], float scores[], int n)
{
    int i;
    printf("Input student's ID and score:\n");
    for(i=0;i<n;i++)
    {
        scanf("%ld%f", &id[i], &scores[i]);
    }
}

void CalculateTotalAndAverageScoreOfCourse(float scores[], int n)
{
    float sum = 0;
    for (int i = 0; i < n; ++i)
    {
        sum += scores[i];
    }
    printf("sum=%.0f,aver=%.2f\n", sum, sum / n);
}

void SortInDescendingOrderByScore(long id[], float scores[], int n)
{
    int  flag, t2;
    float t1;
    printf("Sort in descending order by score:\n");
    //冒泡排序
    for (int i = 0; i < n; ++i)
    {
        flag = 0;
        for (int j = 0; j < n - 1 - i; ++j)
        {
            if(scores[j] < scores[j + 1])
            {
                //交換分數
                t1 = scores[j];
                scores[j] = scores[j + 1];
                scores[j + 1] = t1;

                //交換ID
                t2 = id[j];
                id[j] = id[j + 1];
                id[j + 1] = t2;

                //冒泡排序優化
                flag = 1;
            }
        }
        if(!flag)
        {
            break;
        }
    }
    for (int k = 0; k < n; ++k)
    {
        printf("%ld\t%.0f\n", id[k], scores[k]);
    }
}

void SortInAscendingOrderByScore(long id[], float scores[], int n)
{
    int  flag, t2;
    float t1;
    printf("Sort in ascending order by score:\n");
    //冒泡排序
    for (int i = 0; i < n; ++i)
    {
        flag = 0;
        for (int j = 0; j < n - 1 - i; ++j)
        {
            if(scores[j] > scores[j + 1])
            {
                //交換分數
                t1 = scores[j];
                scores[j] = scores[j + 1];
                scores[j + 1] = t1;

                //交換ID
                t2 = id[j];
                id[j] = id[j + 1];
                id[j + 1] = t2;

                //冒泡排序優化
                flag = 1;
            }
        }
        if(!flag)
        {
            break;
        }
    }
    for (int k = 0; k < n; ++k)
    {
        printf("%ld\t%.0f\n", id[k], scores[k]);
    }
}

void SortInAscendingOrderByNumber(long id[], float scores[], int n)
{
    int  flag, t2;
    float t1;
    printf("Sort in ascending order by number:\n");
    //冒泡排序
    for (int i = 0; i < n; ++i)
    {
        flag = 0;
        for (int j = 0; j < n - 1 - i; ++j)
        {
            if(id[j] > id[j + 1])
            {
                //交換分數
                t1 = scores[j];
                scores[j] = scores[j + 1];
                scores[j + 1] = t1;

                //交換ID
                t2 = id[j];
                id[j] = id[j + 1];
                id[j + 1] = t2;

                //冒泡排序優化
                flag = 1;
            }
        }
        if(!flag)
        {
            break;
        }
    }
    for (int k = 0; k < n; ++k)
    {
        printf("%ld\t%.0f\n", id[k], scores[k]);
    }
}

void SearchByNumber(long id[],float scores[], int n)
{
    int number, i, flag = 0;
    printf("Input the number you want to search:\n");
    scanf("%d", &number);
    for (i = 0; i < n; i++)
    {
        if(id[i] == number)
        {
            flag = 1;
            break;
        }
    }
    if(flag)
    {
        printf("%ld\t%.0f\n", id[i], scores[i]);
    }
    else
    {
        printf("Not found!\n");
    }
}

void StatisticAnalysis(float scores[], int n)
{
    int a, b, c, d, e, f;
    a = b = c = d = e = f = 0;
    float score;
    for (int i = 0; i < n; ++i)
    {
        score = scores[i];
        if(score == 100)
        {
            a++;
        }
        else if(score >= 90 && score < 100 )
        {
            b++;
        }
        else if(score >= 80)
        {
            c++;
        }
        else if(score >= 70)
        {
            d++;
        }
        else if(score >= 60)
        {
            e++;
        }
        else
        {
            f++;
        }
    }
    printf("<60\t%d\t%.2f%%\n", f, (float)(100 * f) / n);
    printf("%d-%d\t%d\t%.2f%%\n" , 60, 69, e, (float)(100 * e) / n);
    printf("%d-%d\t%d\t%.2f%%\n" , 70, 79, d, (float)(100 * d) / n);
    printf("%d-%d\t%d\t%.2f%%\n" , 80, 89, c, (float)(100 * c) / n);
    printf("%d-%d\t%d\t%.2f%%\n" , 90, 99, b, (float)(100 * b) / n);
    printf("%d\t%d\t%.2f%%\n", 100, a,(float)(100 * a) / n);
}

void ListRecord(long id[],float scores[], int n)
{
    for (int i = 0; i < n; ++i)
    {
        printf("%ld\t%.0f\n", id[i], scores[i]);
    }
}

3 月份表示(4分)

題目內容:

用指針數組保存表示每個月份的英文單詞以及“Illegal month”的首地址,然后編程實現:從鍵盤任意輸入一個數字表示月份值n,程序輸出該月份的英文表示,若n不在1~12之間,則輸出“Illegal month”。

int main()
{
    char *month[13] = {"Illegal month", "January", "February", "March", "April", "May", "June", "July", "August",
                     "September", "October", "November", "December"};
    int n;
    printf("Input month number:\n");
    scanf("%d", &n);
    if(n < 0 || n > 12)
    {
        printf("%s\n", month[0]);
    }
    else
    {
        printf("month %d is %s\n", n, month[n]);
    }
    return 0;
}

4 程序改錯——1(4分)

題目內容:

從鍵盤任意輸入m個學生n門課程的成績,然后計算每個學生各門課的總分sum和平均分aver。下面程序存在極為隱蔽的錯誤,請分析錯誤的原因,並修改程序,同時按照給出的程序運行示例檢查修改后的程序。


#include  <stdio.h>
#define STUD 30            //最多可能的學生人數
#define COURSE 5             //最多可能的考試科目數
void  Total(int *score, int sum[], float aver[], int m, int n);
void  Print(int *score, int sum[], float aver[], int m, int n);
int main(void)
{
         int     i, j, m, n, score[STUD][COURSE], sum[STUD];
         float   aver[STUD];
         printf("Enter the total number of students and courses:\n");
         scanf("%d%d",&m,&n);
         printf("Enter score:\n");
         for (i=0; i<m; i++)
         {
            for (j=0; j<n; j++)
            {
                scanf("%d", &score[i][j]);
            }
        }
        Total(*score, sum, aver, m, n);
        Print(*score, sum, aver, m, n);
        return 0;
}
 
void  Total(int *score, int sum[], float aver[], int m, int n)
{
        int  i, j;
        for (i=0; i<m; i++)
        {
            sum[i] = 0;
            for (j=0; j<n; j++)
            {
                sum[i] = sum[i] + *(score + i * n + j);
            }
            aver[i] = (float) sum[i] / n;
        }
}
 
void  Print(int *score, int sum[], float aver[], int m, int n)
{
        int  i, j;
        printf("Result:\n");
        for (i=0; i<m; i++)
        {
            for (j=0; j<n; j++)
            {
                printf("%4d\t", *(score + i * n + j));
            }
            printf("%5d\t%6.1f\n", sum[i], aver[i]);
     }
}

修改后

#define STUD 30            //最多可能的學生人數
#define COURSE 5             //最多可能的考試科目數

void Total(int *score, int sum[], float aver[], int m, int n);

void Print(int *score, int sum[], float aver[], int m, int n);

int main(void)
{
    int i, j, m, n, score[STUD][COURSE], sum[STUD];
    float aver[STUD];
    printf("Enter the total number of students and courses:\n");
    scanf("%d%d", &m, &n);
    printf("Enter score:\n");
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            scanf("%d", &score[i][j]);
        }
    }
    Total(*score, sum, aver, m, n);
    Print(*score, sum, aver, m, n);
    return 0;
}

void Total(int *score, int sum[], float aver[], int m, int n)
{
    int i, j;
    for (i = 0; i < m; i++)
    {
        sum[i] = 0;
        for (j = 0; j < n; j++)
        {
            sum[i] = sum[i] + *(score + i * COURSE + j);
        }
        aver[i] = (float) sum[i] / n;
    }
}

void Print(int *score, int sum[], float aver[], int m, int n)
{
    int i, j;
    printf("Result:\n");
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            printf("%4d", *(score + i * COURSE + j));
        }
        printf("%5d%6.1f\n", sum[i], aver[i]);
    }
}

5 程序改錯——2(4分)

題目內容:

下面主函數調用函數SortString()按奧運會參賽國國名在字典中的順序對其入場次序進行排序,目前程序存在錯誤,請修改正確,並按照給出的程序運行示例檢查修改后的程序。

#include  <stdio.h>
#include  <string.h>
#define   M  150 /* 最多的字符串個數 */
#define   N  10 /* 字符串最大長度 */
void SortString(char *ptr[], int n);
int main()
{
  int    i, n; 
  char   *pStr[M];
  printf("How many countries?\n");
  scanf("%d",&n);
  getchar();        /* 讀走輸入緩沖區中的回車符 */
  printf("Input their names:\n");
  for (i=0; i<n; i++)  
  {
      gets(pStr[i]);  /* 輸入n個字符串 */
  }
  SortString(pStr, n); /* 字符串按字典順序排序 */
  printf("Sorted results:\n");
  for (i=0; i<n; i++)                    
  {
      puts(pStr[i]);  /* 輸出排序后的n個字符串 */
  }
  return 0;
}
void SortString(char *ptr[], int n)
{
  int   i, j;
  char  *temp = NULL;
  for (i=0; i<n-1; i++)    
  {
      for (j=i+1; j<n; j++)
      {
         if (strcmp(ptr[j], ptr[i]) < 0)    
         {
              temp = ptr[i];
              ptr[i] = ptr[j];
              ptr[j] = temp;
         } 
      }   
  } 
}

修改后

#include <stdio.h>
#include  <string.h>

#define   M  150 /* 最多的字符串個數 */
#define   N  10 /* 字符串最大長度 */

void SortString(char *ptr[], int n);

int main()
{
    int i, n;
    char *pStr[M], str[M][N];
    printf("How many countries?\n");
    scanf("%d", &n);
    getchar();        /* 讀走輸入緩沖區中的回車符 */
    printf("Input their names:\n");
    for (i = 0; i < n; i++)
    {
        gets(str[i]);  /* 輸入n個字符串 */
    }
    for (i = 0; i < n; i++)
    {
        pStr[i] = str[i];
    }
    SortString(pStr, n); /* 字符串按字典順序排序 */
    printf("Sorted results:\n");
    for (i = 0; i < n; i++)
    {
        puts(pStr[i]);  /* 輸出排序后的n個字符串 */
    }
    return 0;
}

void SortString(char *ptr[], int n)
{
    int i, j;
    char *temp = NULL;
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (strcmp(ptr[j], ptr[i]) < 0)
            {
                temp = ptr[i];
                ptr[i] = ptr[j];
                ptr[j] = temp;
            }
        }
    }
}

6 找數組最值(4分)

題目內容:

按如下函數原型編程從鍵盤輸入一個m行n列的二維數組,然后計算數組中元素的最大值及其所在的行列下標值。其中,m和n的值由用戶鍵盤輸入。已知m和n的值都不超過10。

void InputArray(int *p, int m, int n);

int  FindMax(int *p, int m, int n, int *pRow, int *pCol);//函數返回最大值,pRow和pCol分別返回最大值所在的行列下標

#define N 10
#define M 10

void InputArray(int *p, int m, int n);

//函數返回最大值,pRow和pCol分別返回最大值所在的行列下標
int FindMax(int *p, int m, int n, int *pRow, int *pCol);

int main()
{
    int m, n, result, row, col, a[M][N];
    printf("Input m,n:\n");
    scanf("%d,%d", &m, &n);
    InputArray(a, m, n);
    result = FindMax(a, m, n, &row, &col);
    printf("max=%d,row=%d,col=%d\n", result, row, col);
}

void InputArray(int *p, int m, int n)
{
    printf("Input %d*%d array:\n", m, n);
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            scanf(" %d", p + i * 10 + j);
        }
    }
}

int FindMax(int *p, int m, int n, int *pRow, int *pCol)
{
    int max = p[0];
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if(max < p[i * 10 + j])
            {
                max = p[i * 10 + j];
                *pRow = i;
                *pCol = j;
            }
        }
    }
    return max;
}

7 冒泡排序(4分)

題目內容:

采用冒泡法進行升序排序法的基本原理是:對數組中的n個數執行n-1遍檢查操作,在每一遍執行時,對數組中剩余的尚未排好序的元素進行如下操作:對相鄰的兩個元素進行比較,若排在后面的數小於排在前面的數,則交換其位置,這樣每一遍操作中都將參與比較的數中的最大的數沉到數組的底部,經過n-1遍操作后就將全部n個數按從小到大的順序排好序了。

#define N 100

void BubbleSoft(int num[], int n);

int main()
{
    int n, num[N];
    printf("Input n:");
    scanf("%d", &n);
    printf("Input %d numbers:", n);
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &num[i]);
    }
    BubbleSoft(num, n);
    printf("Sorting results:");
    for (int i = 0; i < n; ++i)
    {
        printf("%4d", num[i]);
    }
    return 0;
}


void BubbleSoft(int num[], int n)
{
    int flag, temp;
    for (int i = 0; i < n; ++i)
    {
        flag = 0;
        //已經排過序的就不需要在進行排序了,所以-i
        for (int j = 0; j < n - 1 - i; ++j)
        {
            if(num[j] > num[j + 1])
            {
                temp = num[j + 1];
                num[j + 1] = num[j];
                num[j] = temp;

                flag = 1;
            }
        }
        //一次都沒交換則認為數組已經是有序的
        if(!flag)
        {
            break;
        }
    }
}

8 刪除字符串中與某字符相同的字符(4分)

題目內容:

在字符串中刪除與某字符相同的字符,要求用字符數組作函數參數。

#define STR_LEN 80

void DeleteCharacter(char str[], char c);

int main()
{
    char c, str[STR_LEN + 1];
    printf("Input a string:\n");
    gets(str);
    printf("Input a character:\n");
    c = getchar();
    DeleteCharacter(str, c);
    printf("Results:%s\n", str);
    return 0;
}

void DeleteCharacter(char str[], char c)
{
    int index = 0, i, j = 0;
    char str2[STR_LEN + 1];
    for (index = 0; str[index] != '\0'; ++index)
    {
        if(str[index] == c)
        {
            continue;
        }
        str2[j] = str[index];
        j++;
    }
    for (i = 0; i < j; ++i)
    {
        str[i] = str2[i];
    }
    str[i] = '\0';
}

9  求最大數和最小數的最大公約數(4分)

題目內容:

從鍵盤輸入10個正整數,求出最大數,最小數,以及他們的最大公約數。要求用數組實現。

int Gcd(int a, int b);

int main()
{
    int maxNum, minNum, num[10];
    printf("Input 10 numbers:\n");
    for (int i = 0; i < 10; ++i)
    {
        scanf("%d", &num[i]);
    }

    maxNum = minNum = num[0];
    for (int j = 0; j < 10; ++j)
    {
        if(maxNum < num[j])
        {
            maxNum = num[j];
        }

        if(minNum > num[j])
        {
            minNum = num[j];
        }
    }

    printf("maxNum=%d\n", maxNum);
    printf("minNum=%d\n", minNum);
    if(maxNum != 0 && minNum != 0)
    {
        printf("%d", Gcd(maxNum, minNum));
    }
    return 0;
}


int Gcd(int a, int b)
{
    if(a == 0 || b == 0)
    {
        return 0;
    }
    int r;
    do
    {
        r = a % b;
        a = b;
        b = r;
    } while (r != 0);

    return a;
}

10 數列合並(4分)

題目內容:

已知兩個不同長度的降序排列的數列(假設序列的長度都不超過5),請編程將其合並為一個數列,使合並后的數列仍保持降序排列。

【提示】假設兩個降序排列的數列分別保存在數組a和數組b中,用一個循環,從前往后依次比較保存在數組a和數組b中的兩個剩余序列里的第一個數,將其中的較大者存到數組c中,當一個較短的序列存完后,再將較長的序列剩余的部分依次保存到數組c的末尾。假設兩個序列的長度分別是m和n,在比較剩余序列的循環中,用i和j分別記錄兩個序列待比較的數組元素位置,循環結束后,若i小於m,則說明數組a中的數有剩余,將數組a中剩余的數存到數組c的末尾即可;若j小於n,則說明數組b中的數有剩余,將數組b中剩余的數存到數組c的末尾即可。在第一個循環中,用k記錄往數組c中存了多少個數,在第二個循環中,就從k這個位置開始繼續存儲較長序列中剩余的數。

函數原型:void Merge(int a[], int b[], int c[], int m, int n);

函數功能:將兩個長度分別為m和n、降序排列的子序列a和b合並后放到數組c中

#define N 5

void Merge(int a[], int b[], int c[], int m, int n);

void InputArray(int a[], int n);

int main()
{
    int m, n, a[N], b[N], c[N * 2];
    printf("Input m,n:");
    scanf("%d,%d", &m, &n);
    printf("Input array a:");
    InputArray(a, m);
    printf("Input array b:");
    InputArray(b, n);
    Merge(a, b, c, m, n);
    for (int i = 0; i < m + n; ++i)
    {
        printf("%4d", c[i]);
    }
    return 0;
}

void InputArray(int a[], int n)
{
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &a[i]);
    }
}

void Merge(int a[], int b[], int c[], int m, int n)
{
    int aIndex = 0; // 遍歷數組a的下標
    int bIndex = 0; // 遍歷數組b的下標
    int i = 0;      // 記錄當前存儲位置

    while (aIndex < m && bIndex < n)
    {
        //
        if (a[aIndex] >= b[bIndex])
        {
            c[i] = a[aIndex];
            aIndex++;
        }
        else
        {
            c[i] = b[bIndex];
            bIndex++;
        }
        i++;
    }

    // a剩余
    while (aIndex < m)
    {
        c[i] = a[aIndex];
        i++;
        aIndex++;
    }

    // b剩余
    while (bIndex < n)
    {
        c[i] = b[bIndex];
        i++;
        bIndex++;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM