第二次作業


要求一

要求二

6-7 刪除字符串中數字字符

刪除一個字符串中的所有數字字符。

函數接口定義:

void delnum(char *s);

其中 s是用戶傳入的參數。 函數的功能是刪除指針s所指的字符串中的所有數字字符。
裁判測試程序樣例:

#include "stdio.h"
void delnum(char *s);
int main ()
{ char item[80];
gets(item);
 delnum(item);
 printf("%s\n",item);
 return 0;
}

/* 請在這里填寫答案 */

輸入樣例:

a0bc+d496df

輸出樣例:

abc+ddf

1 設計思路

1> 遍歷數組,當找到數字時,進行2>
2> 將該位置及以后的值依次前移,重復1>直到字符串結尾

流程圖

實驗代碼

void delnum(char *s)
{
	int i,j;
	for(i=0;*(s+i)!='\0';i++)
	{
		if(*(s+i)>='0'&&*(s+i)<='9')
		{
			for(j=i;*(s+j)!='\0';j++)
			{
				*(s+j)=*(s+j+1);
			}
			i--;
		}
	} 
}

錯誤信息1:程序直接崩潰
錯誤解決:重新編寫程序,但該錯誤暫無解決方法
錯誤信息2:通過調試發現指針s的值會自動變化
錯誤解決:同上
錯誤信息3:重新編程后發現會多出非數字字符
錯誤解決:循環變量i未歸位,即未重新遍歷數組,前移后將i的值歸位

6-8 統計子串在母串出現的次數

編寫一個函數,該函數可以統計一個長度為3的字符串在另一個字符串中出現的次數。例如,假定輸入的字符串為:asdasasdfgasdaszx67asdmklo,字符串為:asd,則應輸出n=4

函數接口定義:

int fun(char *str,char *substr);

其中strsubstr是用戶傳入的參數。函數統計substr指針所指的字符串在str指針所指的字符串中出現的次數,並返回次數。

裁判測試程序樣例:

#include<stdio.h>
int fun(char *str,char *substr);
int main()
{ char str[81]="asdasasdfgasdaszx67asdmklo",substr[4]="asd";
 int n;
 n=fun(str,substr);
 printf("n=%d\n",n);
 return 0;
}


/* 請在這里填寫答案 */

輸出樣例:

n=4

1 設計思路

1> 定義循環變量i,j,統計次數變量count,判斷變量k
2> 遍歷字符串數組str,若找到與字符串數組substr開頭相同的字符,進行3>
3> 同時對str和substr進行長度為strlen(substr)的遍歷,若有不相同字符,則改變k的值,並退出該遍歷
4> 若3>執行完成后k的值未改變,則 令count的值加1;並從該位置返回2>繼續遍歷
5> 完成2>中遍歷后,將count的值返回主函數

流程圖

實驗代碼

int fun(char *str,char *substr)
{
	int i,j;
	int count=0;
	int k;
	for(i=0;*(str+i)!='\0';i++)
	{
		k=1;
		if(*(str+i)==*substr)
		{
			for(j=0;*(substr+j)!='\0';j++)
			{
				if(*(str+i+j)!=*(substr+j))
				{
					k=0;
					break;
				}
			}
		if(k==1)
		count++;
		}
	}
	return count;
}

錯誤信息1:返回值count出錯
錯誤原因:遍歷數組時將兩字符串比較后的循環變量i錯誤改變,以及判斷變量k的位置放錯
錯誤解決:逐個遍歷數組而非跳躍式遍歷數組;判斷變量k應該在兩字符串比較完成后就進行判斷而非在遍歷數組str時判斷

6-9 字符串中除首尾字符外的其余字符按降序排列

請編寫函數fun,對字符串中除首、尾字符外的其余字符按降序排列。例如,原來的字符串為CEAedca,排序后輸出為CedcEAa

函數接口定義:

int fun(char *s,int num);

其中snum 都是用戶傳入的參數。函數對字符指針 s 所指的字符串中除首、尾字符外的其余字符按降序排列。

裁判測試程序樣例:

#include <stdio.h>
int fun(char *s,int num);
int main()
{
 char s[10];
 gets(s);
 fun(s,7);
 printf("%s",s);
 return 0;
 }

/* 請在這里填寫答案 */

輸入樣例:

CEAedca

輸出樣例:

CedcEAa

1 設計思路

1> 找到字符串的首尾字符的位置
2> 將除首尾外的字符降序排序

流程


實驗代碼

int fun(char *s,int num)
{
    int i,j,k;
    for(i=1;i<num-1;i++)
    {
        for(j=num-2;j>i;j--)
        {
            if(*(s+j)>*(s+j-1))
            {
            	char t;
            	t=*(s+j),*(s+j)=*(s+j-1),*(s+j-1)=t;
	     }
        }
    }
}

錯誤信息1:排序結果錯誤
錯誤解決1:變量過多導致范圍確定錯誤,將程序簡化確定范圍
錯誤解決2:冒泡排序過程出錯,重新復習冒泡排序並改正

7-1 輸出學生成績

本題要求編寫程序,根據輸入學生的成績,統計並輸出學生的平均成績、最高成績和最低成績。建議使用動態內存分配來實現。

輸入格式:

輸入第一行首先給出一個正整數N,表示學生的個數。接下來一行給出N個學生的成績,數字間以空格分隔。

輸出格式:

按照以下格式輸出:

average = 平均成績
max = 最高成績
min = 最低成績

結果均保留兩位小數。

輸入樣例:

3
85 90 95

輸出樣例:

average = 90.00
max = 95.00
min = 85.00

設計思路

1> 定義個數變量N,雙精度各功能變量sum,max,min,avg,指針變量p
2> 輸入N,申請N個雙精度長度的空間並將首地址賦值給p
3> 通過循環輸入N個數,並將其相加得到sum
4> 將首地址的值賦給max,min,通過循環遍歷該動態內存空間來找到最大最小值
5> 計算avg,按題意輸出avg,max,min
6> 釋放該動態內存

流程圖

實驗代碼

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int N;
	double sum=0,max,min,avg,*p;
	int i;
	scanf("%d",&N);
	if((p=(double *)calloc(N,sizeof(double)))==NULL)
	{
		printf("Not able to allocate memory.\n");
		exit(1);
	}
	for(i=0;i<N;i++)
	{
		scanf("%lf",p+i);
		sum=sum+*(p+i);
	}
	max=*p,min=*p;
	for(i=0;i<N;i++)
	{
		if(*(p+i)>max)
		max=*(p+i);
		if(*(p+i)<min)
		min=*(p+i);
	}
	avg=sum*1.0/N;
	printf("average = %.2lf\nmax = %.2lf\nmin = %.2lf\n",avg,max,min);
	free(p);
}

錯誤信息1:編譯錯誤
錯誤改正:未引用stdlib.h庫,引用即可
錯誤信息2:答案錯誤
錯誤改正:輸入N個數為整形而非雙精度型,改為雙精度型即可

7-1 計算職工工資

給定N個職員的信息,包括姓名、基本工資、浮動工資和支出,要求編寫程序順序輸出每位職員的姓名和實發工資(實發工資=基本工資+浮動工資-支出)。

輸入格式:

輸入在一行中給出正整數N。隨后N行,每行給出一位職員的信息,格式為“姓名 基本工資 浮動工資 支出”,中間以空格分隔。其中“姓名”為長度小於10的不包含空白字符的非空字符串,其他輸入、輸出保證在單精度范圍內。

輸出格式:

按照輸入順序,每行輸出一位職員的姓名和實發工資,間隔一個空格,工資保留2位小數。

輸入樣例:

3
zhao 240 400 75
qian 360 120 50
zhou 560 150 80

輸出樣例:

zhao 565.00
qian 430.00
zhou 630.00

1 實驗思路

1> 定義結構體worker,元素分別為字符串數組name(用來存放姓名)、雙精度實數jb(基本工資)、fd(浮動工資)、zc(支出)、fee(實發工資)
2> 定義結構體變量w,整型N,i;N賦值
3> 按結構體要求輸入數據,計算實發工資fee,輸出姓名name與實發工資fee

流程圖

實驗代碼

#include<stdio.h>
struct worker
{
	char name[10];
	float jb,fd,zc;
	float fee;
};
int main()
{
	struct worker w;
	int N,i;
	scanf("%d",&N);
	for(i=0;i<N;i++)
	{
		scanf("%s %f %f %f",w.name,&w.jb,&w.fd,&w.zc);
		w.fee=w.jb+w.fd-w.zc;
		printf("%s %.2f\n",w.name,w.fee);
	} 
}

錯誤信息1:PTA上提示段錯誤
錯誤改正:先前是用結構體數組來實現題目要求,后改為輸入結束一次就輸出一次,PTA通過

7-2 計算平均成績

給定N個學生的基本信息,包括學號(由5個數字組成的字符串)、姓名(長度小於10的不包含空白字符的非空字符串)和成績([0,100]區間內的整數),要求計算他們的平均成績,並順序輸出平均線以下的學生名單。

輸入格式:

輸入在一行中給出正整數N(≤10)。隨后N行,每行給出一位學生的信息,格式為“學號 姓名 成績”,中間以空格分隔。

輸出格式:

首先在一行中輸出平均成績,保留2位小數。然后按照輸入順序,每行輸出一位平均線以下的學生的姓名和學號,間隔一個空格。

輸入樣例:

5
00001 zhang 70
00002 wang 80
00003 qian 90
10001 li 100
21987 chen 60

輸出樣例:

80.00
zhang 00001
chen 21987

設計思路

1> 定義結構體student,元素分別為字符串數組No(學號)、name(姓名),整型sore(成績)
2> 定義整型變量N(學生個數),i(循環變量),sum(成績總和),雙精度實數變量avg(平均成績),結構體數組s
3> sum賦初值0,N賦值
4> 通過循環給結構體數組賦值,並累加sum
5> 計算avg,輸出
6> 遍歷結構體數組找到低於平均值的成績,將其對應的姓名與學號輸出

流程圖

實驗代碼

#include<stdio.h>
struct student
{
	char No[6];
	char name[10];
	int sore;
};
int main()
{
	int N,i,sum=0;
	double avg;
	struct student s[10];
	scanf("%d",&N);
	for(i=0;i<N;i++)
	{
		scanf("%s %s %d",s[i].No ,s[i].name ,&s[i].sore );
		sum=sum+s[i].sore ;
	}
	avg=sum*1.0/N;
	printf("%.2lf\n",avg);
	for(i=0;i<N;i++)
	{
		if(s[i].sore<avg)
		printf("%s %s\n",s[i].name,s[i].No);
	}
}

錯誤信息1:輸出學號時會帶上對應姓名
錯誤分析:通過對數組的空間分配的分析發現,字符串數組No長度為5,最后結尾不為\0;其對應的字符串數組name所分配的空間是緊挨着No所分配的空間的,在輸出字符串(即%s)時,判斷字符串結尾的\0在name中,導致輸出No時將name的\0當作字符串結尾,因此輸出No后會再帶上對應的姓名
錯誤改正:將字符串數組No的長度改為6,即給\0申請個空間

6-1 按等級統計學生成績

本題要求實現一個根據學生成績設置其等級,並統計不及格人數的簡單函數。

函數接口定義:

int set_grade( struct student *p, int n );

其中p是指向學生信息的結構體數組的指針,該結構體的定義為:

struct student{
    int num;
    char name[20];
    int score;
    char grade;
};

n是數組元素個數。學號num、姓名name和成績score均是已經存儲好的。set_grade函數需要根據學生的成績score設置其等級grade。等級設置:85-100為A,70-84為B,60-69為C,0-59為D。同時,set_grade還需要返回不及格的人數。

裁判測試程序樣例:

#include <stdio.h>
#define MAXN 10

struct student{
    int num;
    char name[20];
    int score;
    char grade;
};

int set_grade( struct student *p, int n );

int main()
{   struct student stu[MAXN], *ptr;
    int n, i, count;

    ptr = stu;
    scanf("%d\n", &n);
    for(i = 0; i < n; i++){
       scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
    } 
   count = set_grade(ptr, n);
   printf("The count for failed (<60): %d\n", count);
   printf("The grades:\n"); 
   for(i = 0; i < n; i++)
       printf("%d %s %c\n", stu[i].num, stu[i].name, stu[i].grade);
    return 0;
}

/* 你的代碼將被嵌在這里 */

輸入樣例:

10
31001 annie 85
31002 bonny 75
31003 carol 70
31004 dan 84
31005 susan 90
31006 paul 69
31007 pam 60
31008 apple 50
31009 nancy 100
31010 bob 78

輸出樣例:

The count for failed (<60): 1
The grades:
31001 annie A
31002 bonny B
31003 carol B
31004 dan B
31005 susan A
31006 paul C
31007 pam C
31008 apple D
31009 nancy A
31010 bob B

設計思路

子函數:
1> 定義整型變量count用來統計不及格成績出現次數,整型變量i作為循環變量
2> 通過指針遍歷該結構體數組 ,將成績對應的等級賦值給對應的grade中
3> 函數返回count

流程圖

實驗代碼

int set_grade( struct student *p, int n )
{
	int count=0,i;
	for(i=0;i<n;i++)
	{
		if((p+i)->score>=85&&(p+i)->score<=100)
		(p+i)->grade = 'A';
		else if((p+i)->score>=70&&(p+i)->score<=84)
		(p+i)->grade = 'B';
		else if((p+i)->score>=60&&(p+i)->score<=69)
		(p+i)->grade = 'C';
		else if((p+i)->score>=0&&(p+i)->score<=59)
		{
			(p+i)->grade = 'D';
			count++;
		}
	}
	return count;
}

錯誤信息1:程序運行后,出現錯誤格式答案,且部分答案顯示錯誤
錯誤分析:在最初編程時,指針的使用未加括號導致編譯錯誤;在判斷時未循環判斷結構體數組中的各個元素導致其答案的格式錯誤
錯誤改正:判斷等級放在循環內完成

6-2 結構體數組按總分排序

有一組學生數據,每個數據中含有三門課成績,請按成績總和從高到低對這組數據進行排序。 編寫函數calc求出每名學生的總分。 編寫函數sort按每名學生的總分從高到低對這組數據進行排序

函數接口定義:

void calc(struct student *p,int n);	 
void sort(struct student *p,int n);

其中 pn 都是用戶傳入的參數。 函數calc求出p指針所指的結構體數組中 n 名學生各自的總分。 函數sortp指針所指的結構體數組的學生數據按總分降序排序。

裁判測試程序樣例:

#include <stdio.h>
struct student					
{
int num;
char name[15];
float score[3];
float sum;
};
void calc(struct student *p,int n);	 
void sort(struct student *p,int n);
int main()
{
struct student stu[5];
int i,j;
float f;
for(i=0;i<5;i++)
{
	scanf("%d%s",&stu[i].num,stu[i].name);
	for(j=0;j<3;j++)
	{ 
    	scanf("%f",&f);
		stu[i].score[j]=f;
	}
}
calc(stu,5);
sort(stu,5);
for(i=0;i<5;i++)
{
	printf("%5d%15s",stu[i].num,stu[i].name);
	printf("  %.1f  %.1f  %.1f  %.1f\n",stu[i].score[0],stu[i].score[1],stu[i].score[2], stu[i].sum);
}
return 0;

/* 請在這里填寫答案 */

輸入樣例:

1 zhang 89 87 85
2 liu  92 98 96
3 li 74 71 72
4 xion 95 98 99
5 liu 99 100 100

輸出樣例:

    5            liu  99.0  100.0  100.0  299.0
    4           xion  95.0  98.0  99.0  292.0
    2            liu  92.0  98.0  96.0  286.0
    1          zhang  89.0  87.0  85.0  261.0
    3             li  74.0  71.0  72.0  217.0

設計思路

子函數calc
1> 定義整型變量i作為循環變量
2> 將結構體數組中sum成員的值用指針p進行求和
子函數sort
1> 定義循環變量i,j;下標變量k
2> 通過選擇排序對結構體進行排序

流程圖

實驗代碼

#include<string.h> 
void calc(struct student *p,int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		(p+i)->sum=(p+i)->score[0]+(p+i)->score[1]+(p+i)->score[2];
	}
}
void sort(struct student *p,int n)
{
	int i,j,k,m;
	for(i=0;i<n-1;i++)
	{
		k=i;
		for(j=i+1;j<n;j++)
		{
			if((p+j)->sum>(p+k)->sum)
			{
				k=j;
			}
		}
		if(k!=i)
		{
			/*注釋
                        float t;
			t=(p+i)->num,(p+i)->num=(p+k)->num,(p+k)->num=t;
			t=(p+i)->sum,(p+i)->sum=(p+k)->sum,(p+k)->sum=t;
			for(m=0;m<2;m++)
			t=(p+i)->score[m],(p+i)->score[m]=(p+k)->score[m],(p+k)->score[m]=t;
			t=(p+i)->score[1],(p+i)->score[1]=(p+k)->score[1],(p+k)->score[1]=t;
			t=(p+i)->score[2],(p+i)->score[2]=(p+k)->score[2],(p+k)->score[2]=t;
			char T[15];
			strcpy(T,(p+i)->name),strcpy((p+i)->name,(p+k)->name),strcpy((p+k)->name,T);
                        */
			struct student t;
			t=*(p+i),*(p+i)=*(p+k),*(p+k)=t;
		}
	}
}

錯誤信息1:排序錯誤
錯誤分析:選擇排序內循環中,j=i+1錯寫成j=i+i
錯誤改正:j=i+i改為j=i+1
錯誤信息2:答案錯誤
錯誤分析:原始程序中的交換使用的是單個數據類型的相互交換(即實驗代碼中被注釋的部分),該過程中可能會有遺漏或其他問題
錯誤改正:直接定義結構體數據類型變量t,再用t實現兩個元素的交換

要求三

學習總結

代碼托管

托管界面

同學點評

辛靜瑤
李伍壹
梁聖然
袁中
申怡苗
姜健

學習記錄


免責聲明!

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



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