Lab12-动态分配与结构体
1. book类型的结构体【简单】
(结构体)101. 结构体和指针的练习,
请定义结构体类型Book包括了书名,价格,出版社等信息。
请定义结构体Book类型的指针,并用malloc函数分配结构体变量的内存空间
【输入】
第1行:一个字符串,表示书名,可能包含空格,长度不大于90个字符。
第2行,一个非负数,表示价格,不超过1000000。
第3行:一个字符串,表示出版社名,可能包含空格,长度不大于30个字符。
【输出】
一行,包含书名,价格,出版社的字符串,格式如下:
name is “书名”, price is $价格, press is “出版社”
价格保留两位小数。
【样例输入】
The C Programming Language, 2nd Edition
63.12
Prentice Hall
【样例输出】
name is “The C Programming Language, 2nd Edition”, price is $63.12, press is “Prentice Hall”
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct book
{
char name[99];
double price;
char press[33];
};
struct book *p = malloc(sizeof(struct book));
gets(p->name);//指针访问 or gets((*book).name);
scanf("%lf ",&p->price);
//或getchar();
gets(p->press);
printf("name is \"%s\", price is $%.2lf, press is \"%s\"",p->name,p->price,p->press);
free(p);
return 0;
}
2. 赶班车【中等】
(结构体数组)周一至周五,中山北路校区停车场开往闵行校区的校车的发车时间为
6:50、8:30、11:50、13:50、16:50、18:00、20:50
如果今天校车严格按上述时间表发车,告诉你现在的时间,
请问现在离今天的下一班校车发车还有多少分钟?
【输入】
现在的时间,格式为 HH:MM,其中 HH、MM 均为整数,
且满足 0 ≤ HH ≤ 23,00 ≤ MM ≤ 59。
【输出】
一个整数,表示现在离今天的下一班校车发车还有多少分钟。
如果今天已经没有下一班校车,则输出 -1。
如果现在时间刚好为发车时间,则输出 0。
行末无换行。
【样例输入1】
11:40
【样例输出1】
10
【样例输入2】
22:00
【样例输出2】
-1
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct time
{
int hour;
int min;
}timetable[7] =
{{6,50},{8,30},{11,50},{13,50},{16,50},{18,0},{20,50}};
int h,m;
scanf("%d:%d",&h,&m);
if((h>=20 && m>=51) || h>=21){
printf("-1");
}
else if(h<=6 && m<=50){
printf("%d",(6-h)*60+(50-m));
}
else{
for(int i=0; i<7; i++){
//timetable[i]是第i个数组结构体,再.hour取的是结构体里的东西
if(h==timetable[i].hour && m==timetable[i].min){
printf("0");break;
}
if(h>=timetable[i].hour && h<=timetable[i+1].hour){
printf("%d",timetable[i+1].hour*60+timetable[i+1].min-h*60-m);break;
}
}
}
return 0;
}
3. tb商品排序【中等】
(我心中的经典题目)
在tb店铺中,商品的信息有:货号、上架日期和售价。
请写一个程序,将商品按照上架日期降序排序;上架日期相同的商品,则按照售价升序排序;上架日期与售价均相同的商品,则按照货号升序排序,货号的排序规则符合字典序。
【Input】
第 1 行:一个整数 T (1≤T≤10) 为问题数。
对于每组测试数据:每组第一行包括一个整数n,(1≤n≤200),接下来的n行,每行表示一个商品信息,具体包括:(1)货号,由两个小写字母和四位数字组成,(2)日期,格式为YYYY-MM-DD, (3)商品售价(最大5位数)。
【Output】
对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等)
接下来的n行,是排序后的 n 个商品的信息,每个商品的信息占一行。
Example:
【input】
3
3
fk0129 2014-01-28 4575
fi9543 2011-12-01 1205
fu6507 2013-03-07 15790
4
al7157 2016-10-28 12678
ox6333 2014-03-16 4629
ip5447 2016-10-28 19332
jf2741 2013-10-21 12264
5
sm6988 2016-09-01 2486
ut8294 2014-10-24 17239
lt8864 2016-09-01 2486
bn4194 2015-12-07 15039
sc1937 2013-04-30 9144
【output】
case #0:
fk0129 2014-01-28 4575
fu6507 2013-03-07 15790
fi9543 2011-12-01 1205
case #1:
al7157 2016-10-28 12678
ip5447 2016-10-28 19332
ox6333 2014-03-16 4629
jf2741 2013-10-21 12264
case #2:
lt8864 2016-09-01 2486
sm6988 2016-09-01 2486
bn4194 2015-12-07 15039
ut8294 2014-10-24 17239
sc1937 2013-04-30 9144
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char id[7];
char date[11];
int price;
} item;
//itemcmp定义成const的指针是为了提高参数传递的效率;
//itemcmp也可以定义为简单传值的形式:int itemcmp(item item1, item item2);
//根据题意,*p1若排序后相对*p2靠前,则返回小于0,靠后则返回值大于0,相等返回0;
int itemcmp(const item * p1, const item *p2);
//根据题意进行选择排序
void sort(item items[], int n);
int main()
{
int t, i, j, n;
scanf("%d ", &t);
for(i = 0; i < t; i++)
{
scanf("%d ", &n);
item list[n];
//input
for(j = 0; j < n; j++)
scanf("%s %s %d", list[j].id, list[j].date, &list[j].price);
printf("case #%d:\n", i);
//排序
sort(list,n);
//output
for(j = 0; j < n; j++)
printf("%s %s %d\n", list[j].id, list[j].date, list[j].price);
}
}
//注意,这里些itemcmp有一个技巧(约定):
//根据题意:*p1若排序后相对*p2靠前,则返回值小于0
//根据题意:*p1若排序后相对*p2靠后,则返回值大于0
int itemcmp(const item * p1, const item *p2)
{
int n = strcmp(p2->date, p1->date);
if(n!=0)
return n;
n = p1->price-p2->price;
if(n!=0)
return n;
n = strcmp(p1->id, p2->id);
return n;
}
//排序
void sort(item items[], int n)
{
int j,k,min;
item temp;
for(j = 0; j < n; j++)
{
min = j;
for(k = j+1; k<n; k++)
{
if(itemcmp(&items[min], &items[k])>0)//返回值大于0,要更新min的位置
min = k;
}
temp = items[j];
items[j] = items[min];
items[min] = temp;
}
}
4. 字符串排序【中等】
(指针)97. 用指向指针的指针方法对输入的n个字符串进行排序。
定义函数Input,Sort,Free。
(1)在Input函数中输入n个字符串并用一个char的数组去指向这些字符串。
(2)每个字符串的存贮空间和char数组的存贮空间都在free store(heap)中申请。
(3)程序结束前需要在函数Free中释放在free store中申请的空间。
不完全释放就称为内存泄漏(Memory Leak)。
//********** Specification of Input **********
char** Input(int n);
/* PreCondition:
n is the count of strings
PostCondition:
input n strings, and return the address of the char* array
*/
//********** Specification of Free **********
void Free(char**a, int n);
/* PreCondition:
a points to a char* array in free store (heap),
n is a positive integer
PostCondition:
free ALL memory allocated in Input function
*/
//********** Specification of Sort **********
void Sort(char a, int n);
/ PreCondition:
a is pointer which points to an array of char pointers,
and n is a positive integer
PostCondition:
a is sorted satisfying to the specification
/
int main()
{ char* p; int n,i; scanf("%d",&n); getchar();
//********** Input is called here **********
p = Input(n);
//******************************************
//********** Sort is called here ***********
Sort(p,n);
//******************************************
for(i=0; i<n; i++) printf("%s\n",p[i]);
Free(p,n);
//******************************************
return 0;
}
【输入】
第1行:一个正整数n
第2至 n+1行,每行一个字符串,可能包含空格,长度不超过30个字符
【输出】
n行,为输入字符串按字典序升序排列
【样例输入】
3
Barack Obama
Vladimir Putin
David William Donald Cameron
【样例输出】
Barack Obama
David William Donald Cameron
Vladimir Putin
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** Input(int n)
{
char **p = malloc(sizeof(char *)*n);
for(int i=0; i<n; i++){
p[i] = malloc(sizeof(char)*33);
gets(p[i]);
}
return p;
}
void Free(char**a, int n)
{
for(int i=0; i<n; i++){
free(a[i]);
}
free((a));
}
void Sort(char **a, int n)
{
int i,j;
for(i=0; i<n; i++){
for(j=i+1; j<n; j++){
if(strcmp(a[i],a[j])>0){
char *temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
//a[i]和a[j]都是指针,可以和temp直接换,不用strcpy
}
}
}
}
int main()
{
char** p;
int n,i;
scanf("%d",&n);
getchar();
p = Input(n);
Sort(p,n);
for(i=0; i<n; i++)
printf("%s\n",p[i]);
Free(p,n);
return 0;
}
5. 统计考分【困难】
(循环,数组)
N名考生参加一场考试。这场考试共有M道题,每道题目分值不一,考生答对题目的总分达到或超过G则算通过考试。
告诉你每道题的分值,以及每名考生答对的题目的编号,
请按照总成绩降序的顺序,输出通过考试的考生号和分数。
【输入】
第1行有3个正整数,分别为参加考试的人数 N (1 ≤ N ≤ 10)、问题数M (1 ≤ M ≤ 10)、通过分数线G;
第2行有空格分隔的 M 个正整数,分别为第1题至第 M 题的分值
随后 N 行,每行给出一名考生的考生号、答对问题数量s、
以及这s道题的题号(问题从1开始编号),两两之间以一个空格隔开。
输入数据保证所有输入和输出整数在 int 范围内,考生号为长度不超过20的无空格字符串且不重复。
【输出】
第1行输出一个整数X,表示通过考试的考生数量,
接下来的X行,按总分降序输出通过考试的每位考生的考生号与总分,用空格隔开。
如果有考生的答对题目的总分相等,则考生号字符串的字典序较小的排在前面。
【样例输入】
4 5 25
10 10 12 13 15
SE004 3 5 1 3
SE003 5 2 4 1 3 5
SE002 2 1 2
SE001 3 2 3 5
【样例输出】
3
SE003 60
SE001 37
SE004 37
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct inf
{
char stuNo[51];
int amount;
int qNo[11];
int score;
};
void Sort(struct inf *a, int n)
{
int i,j,first;
struct inf temp;
for(i=0; i<n-1; i++)
{
first = i;
for(j=i+1; j<n; j++)
{
if(stucmp(&a[first], &a[j]) > 0)
{
first = j;
}
}
temp = a[i];
a[i] = a[first];
a[first] = temp;
}
}
int stucmp(struct inf *p1, struct inf *p2)
{
int n = p1->score - p2->score;
if(n < 0)
return 1;
if(n > 0)
return -1;
if(strcmp(p1->stuNo, p2->stuNo) > 0)
return 1;
if(strcmp(p1->stuNo, p2->stuNo) < 0)
return -1;
return 0;
}
int main()
{
int N,M,G;
int i,j;
scanf("%d %d %d",&N,&M,&G);
//每道题的分值
int standard[M];
for(i=0; i<M; i++)
{
scanf("%d",&standard[i]);
}
struct inf stu[N];
//输入学生信息
for(i=0; i<N; i++)
{
scanf("%s",stu[i].stuNo);
scanf("%d",&stu[i].amount);
for(j=0; j<stu[i].amount; j++)
scanf("%d",&stu[i].qNo[j]);
}
//计算分数
for(i=0; i<N; i++)
{
j=0;
stu[i].score = 0;
while(j != stu[i].amount)
{
int s = stu[i].qNo[j]-1;
stu[i].score += standard[s];
j++;
}
}
Sort(stu, N);
//统计合格人数
int cnt=0;
for(i=0; i<N; i++)
{
if(stu[i].score>=G)
{
cnt++;
}
}
printf("%d\n",cnt);
for(i=0; i<cnt; i++)
{
printf("%s %d\n",stu[i].stuNo,stu[i].score);
}
return 0;
}