题目二
【问题描述】
这是一个古老而又经典的问题。用给定的几种钱币凑成某个钱数,一般而言有多种方式。例如:给定了6种钱币面值为2、5、10、20、50、100,用来凑 15元,可以用5个2元、1个5元,或者3个5元,或者1个5元、1个10元,等等。显然,最少需要2个钱币才能凑成15元。
你的任务就是,给定若干个互不相同的钱币面值,编程计算,最少需要多少个钱币才能凑成某个给出的钱数。
【要求】(代码需加注释)
【数据输入】输入可以有多个测试用例。每个测试用例的第一行是待凑的钱数值M(1 <= M <= 2000,整数),接着的一行中,第一个整数K(1 <= K <= 10)表示币种个数,随后是K个互不相同的钱币面值Ki(1 <= Ki <= 1000)。输入M=0时结束。
【数据输出】每个测试用例输出一行,即凑成钱数值M最少需要的钱币个数。如果凑钱失败,输出“Impossible”。你可以假设,每种待凑钱币的数量是无限多的。
【样例输入】
1 //第一行是待凑的钱数值M
6 2 5 10 20 50 100 //第一整数为币种数,K个互不相同的钱币面值
1
1 2
0
【样例输出】
2
Impossible
二、运行环境:
本题采用C/C++编程语言编写
运行环境:在Windows7系统下,使用C-Free 5软件运行验证
三、算法设计的思想:
此题的实质是有m个钱币,找零n(任意大的整数)钱币,最少需要的钱币数。
本题可采用动态规划算法。此问题递推公式(也可以叫做动态转移方程):(注:v[i]表示可以使用的纸币的面额组成的数组,dp[m]表示要凑m元至少需要多少张纸币。)
dp[m] = min(dp[m-v[i] ]+1,dp[m])
DP(Dynamic Programing)的基本原理:首先,找到某个状态的最优解,然后在它的帮助下,找到下一个状态的最优解。
四、算法的流程图:
五、算法设计分析:
问题分析:规模化问题拆解
举例分析:用多少张纸币能凑够m(表示money)元(m<8)呢?
(假设有币种1元、3元、5元、7元)
用dp[m]=c来表示凑够m元最少需要c个硬币
钱数 | 纸币数 | 解题思路 |
m=0 | c=0 | dp[0]=0 |
m=1 | c=1(1元) | dp[1]=dp[1-1]+1=dp[0]+1=0+1=1 |
m=2 | c=2(1元、1元) | dp[2]=dp[2-1]+1=dp[1]+1=1+1=2 |
m=3 | c=3(1元3个) | dp[3]=dp[3-1]+1=dp[2]+1=2+1=3 |
m=3 | c=1(3元) | dp[3]=dp[3-3]+1=dp[0]+1=0+1=1 |
(最优解获得:dp[3]=min(dp[3-1]+1, dp[3-3]+1)) | ||
m=8 | c=1(1元8个) | dp[8]=dp[8-1]+1=……=8 |
m=8 | c=2(3元+5元) | dp[8]=dp[8-5]+1=dp[3]+1=2 |
m=8 | c=2(1元+7元) | dp[8]=dp[8-7]+1=dp[1]+1=2 |
(最优解获得:dp[8]=min(dp[8-1]+1,dp[8-5]+1,dp[8-7]+1)) |
由上面的分析可得出相应的递推公式中的重要概念:状态和状态转移方程
dp[m]表示凑够m元需要的最少硬币数量,我们将它定义为该问题的"状态"。
上述状态为:dp[8],即凑够8元最少需要多少个硬币。
状态转移方程用dp[m]表示状:dp[m] = min(dp[ m-v[i] ]+1,dp[m])
(m-v[i] >=0,v[i] 表示第i个硬币的面值,方程的含义是拿出一个面值为 v[i] 的硬币后,凑够 m-v[i] 元至少需要的硬币数目(dp[m-v[i] ])+1和凑够m元至少需要的硬币数目(dp[m])相比较,取较小的存入dp[m])
六、源代码:
/* coins.h
*/
#include <iostream>
#define Uint int
#define N_void void
using namespace std;
N_void Dpcount(N_void);
Uint MinValue(Uint src,Uint des);
N_void showWdget(N_void);
/* ExecMain.cpp
*/
#include "coins.h"
int main(int argc, char *argv[])
{
showWdget();
Dpcount();
return 0;
}
/* showWdget.cpp
*/
#include "coins.h"
N_void showWdget(N_void){
system("color 0c");
cout<<"\t\tPlease input data as follow example:"<<endl;
cout<<"\tFirst line:\n"<<"Input the money to be collected"<<endl;
cout<<"\tSecond line:\n"<<"First number is kend of the money,and follow is you except money value"<<endl;
}
/* MinValue.cpp
*/
#include "coins.h"
Uint MinValue(Uint src,Uint des){
return (src>des)?src:des;
}
/* Dpcount.cpp
*/
#include "coins.h"
N_void Dpcount(N_void){
Uint coins[10] = {0}; //硬币面值数组10种
Uint money = 0; //待凑钱的数值
Uint kind = 0; //钱币种类数目
while(1)
{
Uint i,j,k;
cin >> money;
if(0 == money)break; //结束标志
Uint dp[money+1]; //动态规划数组
dp[0] = 0; //初始化第一个元素为0,凑money元需要kind个钱币
cin >> kind; //硬币面值种类数
for(k=0; k<kind; k++)
{
cin >> coins[k]; //读入硬币面值,存入数组coins[]
}
for(i = 1; i <= money; i++) //初始化数组dp[],设置dp[i]等于无穷大
dp[i] = 99999;
for(i = 1; i <= money; i++) //从凑1元开始,一直算到money元为止。
{
for(j = 0; j < kind; j++)
{
if(i >= coins[j])
{
dp[i] = MinValue(dp[i- coins[j] ] + 1, dp[i]);
}
}
}
if( dp[money] == 99999 )
{
cout << "Impossible"<< endl;
}
else
{
cout << dp[money] << endl;
}
}
}
七、运行结果分析
本次运行模拟使用Windows 7操作系统,在VC++ 6.0软件上进行模拟。CPU采用Intel i3系列,主机内存4GB。
经过运行验证、测试,算法符合预期要求。经过本次设计我发现,自己对于DP算法掌握深入了解,加深自我理解,对以后的学习获益良多。
题目三
设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括
(1)删除一个字符;
(2)插入一个字符;
(3)将一个字符改为另一个字符。
将字符串A变换为字符串B所用的最少字符操作数称为字符串A到B的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。
例如,若A=“abcd” ,B=“def” ,则编辑距离为4。
二、运行环境:
本题采用C/C++编程语言编写
运行环境:在Windows7系统下,使用VC++ 6.0软件运行验证
三、算法设计的思想:
【】问题分析:
本题实质是求解编辑距离分为字符串A从0个字符逐渐增加到全部字符分别要变成字符串B该如何变化的问题。可以用动态规划思想解决。
假设选用str1存储字符串A,str2存储字符串B,distance矩阵表示两串运算结果
考虑三种情况:(假定字符串A、B的长度为n、m,则矩阵为distance[n][m])
1) A: (空)
B: abe
编辑距离为:m
2) A: abc
B: (空)
编辑距离为:n
3) A: abc
B: abe
编辑距离多种考虑
四、算法的流程图:
五、算法设计分析:
假定我们从distance[0][0]开始一直操作到了distance[i][j]位置,其中删除操作肯定是str1比str2长,插入操作str1比str2短,我们所要做的是对distance[i-1][j] 、distance[i][j-1]、distance[i-1][j-1]存的数进行比较,其中最小的就是当前str1和str2的编辑距离。
distance[n][m]矩阵编辑 | ||||
abe abc | abc | a | b | c |
abe | 0 | 1 | 2 | 3 |
a | 1 | A出0 | 1 | 2 |
b | 2 | B处1 | 0 | 1 |
e | 3 | C处2 | 1 | 1 |
(说明:)在A处,由于两个a相同,左上角为0,为左上角的0+0;
由以上分析得出其动态规划状态转移方程:
distance[i][j]=min(distance[i][j-1]+1,distance[i-1][j]+1),distance[i-1][j-1]+1)
六、源代码:
/* minval.cpp
*/
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
#define MAX 100
int minval(int a,int b,int c){ //求三者中的最小值
int zhi=min(a,b);
int minvalue=min(zhi,c);
return minvalue;
}
/* min.cpp
*/
int min(int a,int b){ //求二者中的最小值
return(a>b?b:a);
}
/* editDistance.cpp
*/
void editDistance(char *str1,char *str2){ //编辑距离函数,str1 str2为操作的字符串
int lenthofstr1=strlen(str1);
int lenthofstr2=strlen(str2);
int distance[MAX][MAX];
//变量用来遍历、初始化字符串
int i,j;
for(i=0;i<lenthofstr1;i++){
distance[i][0]=i;
}
for(i=0;i<lenthofstr2;i++){
distance[0][i]=i;
}
for(i=1;i<lenthofstr1;i++){
for(j=1;j<lenthofstr2;j++){
//如果对应的字符相等,原问题交给子问题处理,即不用任何操作
if(str1[i]==str2[j]){
distance[i][j]=distance[i-1][j-1];
}
else{
//否则的话,对左、右、左上角的值进行求最小值
distance[i][j]=minval(distance[i-1][j]+1,distance[i][j-1]+1,distance[i-1][j-1]+1);
}
cout<<distance[i][j]<<" ";
}
cout<<endl;
}
cout<<"最少的操作次数是:"<<distance[lenthofstr1-1][lenthofstr2-1];
}
/* main.cpp
*/
int main(){
string str1[MAX];
string str2[MAX];
cout<<”Input str1[] string,please”<<endl;
cin>>str1[MAX];
cout<<”Input str2[] string ,please”<<endl;
cin>>str2[MAX];
editDistance(str1,str2);
return 0;
}
七、运行结果分析:
本次运行模拟使用Windows 7操作系统,在C-Free 5软件上进行模拟。CPU采用Intel i3系列,主机内存4GB。
经过运行验证、测试,算法符合预期要求。经过本次设计我发现,自己对于最优解问题、规划算法掌握深入了解,加深自我理解,对以后的学习获益良多。
【测试数据】
字符串A:abend
字符串B:apple
字符串长度: 5
最小编辑距离:4
题目四
4.【任务描述】
参加运动会有n个学校,学校编号为1……n。比赛分成m个男子项目,和w个女子项目。项目编号为男子1……m,女子m+1……m+w。不同的项目取前五名或前三名积分;取前五名的得分分别为:7、5、3、2、1,前三名的得分分别为:5、3、2;哪些取前五名或前三名由学生自己设定。(m<=20,n<=20)
【功能要求】
1)可以输入各个项目的前三名或前五名的成绩。
2)能统计各学校总分。
3)可以按学校编号或名称、学校总分、男女团体总分排序输出。
4)可以按学校编号查询学校某个项目的情况;可以按项目编号查询取得前三或前五名的学校。
5)数据存入文件并能随时查询。
6)规定:输入数据形式和范围:可以输入学校的名称,运动项目的名称。
【输出形式】有合理的提示,各学校分数为整型。
【界面要求】有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。
【存储结构】学生自己根据系统功能要求自己设计,但是要求运动会的相关数据要存储在数据文件中。(数据文件的数据读写方法等相关内容在C /C++语言程序设计的书上,请自学解决)请在最后的上交资料中指明你用到的存储结构。
【测试数据】要求使用(1)全部合法数据;(2)整体非法数据;(3)局部非法数据分别进行程序测试,以保证程序的稳定。测试数据及测试结果请在上交的资料中写明。
二、运行环境:
本题采用C/C++编程语言编写
运行环境:在Windows7系统下,使用C-Free5软件上运行验证
三、算法设计的思想:
本题主要考察数据读取以及模块化编程思想,需要使用查找表技术与搜索算法实现部分功能。
四、算法的流程图:
五、算法设计分析:
【】设计概要
使用菜单函数(menu)作为显示窗口,将信息存储在文件中故设计文件的存储(savetofile)与读取函数(readfromfile),信息输入函数(input)在输入基本信息后由系统统计总分的内容并全部存入Spcfile.txt中,在接下来的函数中开始都需要读取文件中的信息,信息的输出(output)输出输入函数中统计后的各项信息,在排序输出(sortput)中使用冒泡排序法进行不同关键字的排序,查询函数(search)采用顺序表的查找来完成。
1、抽象数据类型定义
比赛项目数据表
typedef struct
{
int inum; /*比赛项目编号*/
int top; /*取名次的数目,前三或前五*/
int range[5]; /*各个名次的名称*/
int mark[5]; /*个名次对应的分数*/
}itemnode; /*存放比赛项目信息*/
学校信息表
typedef struct
{
int snum; /*学校编号*/
int score; /*学校总分*/
int mscore; /*男子项目团体总分*/
int wscore; /*女子项目团体总分*/
itemnode t[M+W]; /*项目数组*/
}snode; /*存储各个参数学校总体情况*/
snode a[N]; /*定义一个学校数组*/
2、函数模块
1)void menu(int n,int m,int w) //提供界面窗口
2)void savetofile() //保存输入的运动会信息到Spcfile.txt文件
3)void readfromfile() //从Spcfile.txt文件中读取运动会信息
4)void input(int n,int m,int w) //输入信息并统计
5)void output(int n,int m,int w) //按学校、项目输出统计信息
6)void sortput(int n,int m,int w) //按四种方法排序并输出结果
7)void search(int n,int m,int w) //按两种方法查询并输出结果
六、源代码:
/* MainHead.h
*/
#ifndef __MAINHEAD_H__
#define __MAINHEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <process.h> /*execl( ) getpid() _cexit() exit()*/
#define N 20 /*学校最大数目*/
#define M 20 /*男子项目最大数目*/
#define W 20 /*女子项目最大数目*/
//变量定义
typedef struct{
int inum; /*比赛项目编号,男子从1,2,3…m,女子从m+1…inum*/
int top; /*要取的名次,前三或前五*/
int range[5]; /*各个名次的名称*/
int mark[5]; /*各名次对应的分数*/
}itemnode; /*项目数据表*/
/*变量inum、top、range由终端用户输入,而mark由range、top决定*/
typedef struct{
int snum; /*学校的编号*/
int score; /*学校总分*/
int mscore; /*男子项目团体总分*/
int wscore; /*女子项目团体总分*/
itemnode t[M+W]; /*项目数组*/
}snode; /*存储各个参赛学校的总体情况*/
/*全局变量定义*/
snode a[N]; /*定义一个学校数组*/
int n,m,w;
//n表示学校个数,m表示男子项目个数,m表示女子项目个数
void menu(int n,int m,int w); //提供界面窗口
void input(int n,int m,int w); //信息输入
void savetofile( ); //保存输入的运动会信息到file文件
void readfromfile( ); //从file文件中读取运动会信息
void output( ); //按照学校、项目输出统计信息
void sortput(int n,int m,int w); //按照四种方法排序并输出结果
void search( int n,int m,int w); //按照两种方法查询并输出结果
#endif
#include "MainHead.h"
/*
File name: 运动运动会分数统计
Author:
Version:
Date:
Description: 实现分数查询,学校比赛项目排名
Function List:
*/
int main(int argc, char *argv[])
{
system("color 5A");
printf("\t\t\t欢迎使用\t\t\t\t\n\n");
printf("\t*******运动会分数统计系统*******\n\n");
printf("请输入运动会主要信息\n");
printf("输入学校个数:");
scanf("%d",&n);
printf("输入男子项目个数:");
scanf("%d",&m);
printf("输入女子项目个数:");
scanf("%d",&w);
menu(n,m,w);
return 0;
}
#include "MainHead.h"
/*
Function:菜单函数显示
Input:
Param: argu n,n表示学校个数
Param: argu m,m表示男子项目个数
Param: argu w,n表示女子项目个数
Output:
Return:
*/
void menu(int n,int m,int w)
{
int c;
printf("\t\t\t欢迎使用\t\t\t\n\n");
printf("\t****运动会分数统计系统****\n\n");
printf("\t\t*******1.信息输入*******\n");
printf("\t\t*******2.统计输出*******\n");
printf("\t\t*******3.排序输出*******\n");
printf("\t\t*******4.信息查询*******\n");
printf("\t\t*******0.退出系统*******\n\n");
printf("============================\n\n");
printf("请选择要实现步骤的编号(0--4):");
scanf("%d",&c);
switch(c)
{
case 1:
input(n,m,w);
break;
case 2:
output(n,m,w);
break;
case 3:
sortput(n,m,w);
break;
case 4:
search(n,m,w);
break;
case 0:
printf("谢谢使用,再见!\n");
exit(0);
default:
printf("输入错误,请重试!\n");
menu(n,m,w);
}
}
#include "MainHead.h"
/*
Function: 信息输入
Input:
param: argu n, n表示学校个数
Param: argu m, m表示男子项目个数
Param: argu w, m表示女子项目个数
Output:
Return:
*/
void input(int n,int m,int w)
{
int i,j,s,k,q=0;
for(i=0;i<n;i++)
{
printf("学校编号:");
scanf("%d",&a[i].snum); /*输入学校信息*/
for(j=0;j<m+w;j++)
{
printf("项目编号:");
scanf("%d",&a[i].t[j].inum);
printf("项目取前3名或前5名(3或者5):");
scanf("%d",&a[i].t[j].top);
if(a[i].t[j].top==3)
printf("获得名次个数(1--3):");
else
printf("获得名次个数(1--5):");
scanf("%d",&k); /*输入项目信息*/
for(s=0;s<k;s++)
{
if(a[i].t[j].top==3)
printf("所获名次(1--3):");
else
printf("所获名次(1--5):");
scanf("%d",&a[i].t[j].range[s]); /*输入所获名次信息*/
}
printf("\n");
}
}
for(i=0;i<n;i++)
{
a[i].score=0;
a[i].mscore=0;
a[i].wscore=0;
} /*初始化分数*/
for(i=0;i<n;i++)
for(j=0;j<m+w;j++)
for(s=0;s<5;s++)
{
if(a[i].t[j].top==3)
switch(a[i].t[j].range[s])
{
case 0: a[i].t[j].mark[s]=0;
break;
case 1: a[i].t[j].mark[s]=5;
break;
case 2: a[i].t[j].mark[s]=3;
break;
case 3: a[i].t[j].mark[s]=2;
break;
}
else if(a[i].t[j].top==5)
switch(a[i].t[j].range[s])
{
case 0: a[i].t[j].mark[s]=0;
break;
case 1: a[i].t[j].mark[s]=7;
break;
case 2: a[i].t[j].mark[s]=5;
break;
case 3: a[i].t[j].mark[s]=3;
break;
case 4: a[i].t[j].mark[s]=2;
break;
case 5: a[i].t[j].mark[s]=1;
break;
}
else
{
printf("信息有误!");
printf("\n");
exit(0);
}
a[i].score=a[i].score+a[i].t[j].mark[s]; /*记学校总分*/
if(j<=m-1)
a[i].mscore=a[i].mscore+a[i].t[j].mark[s]; /*记男子团体总分*/
else
a[i].wscore=a[i].wscore+a[i].t[j].mark[s]; /*记女子团体总分*/
}
printf("输入完毕!返回? 1是 2否\n"); /*返回菜单*/
scanf("%d",&q);
printf("\n");
if(q!=1)
printf("不能再添加信息!");
printf("\n");
savetofile(); /*将信息存入文件file*/
menu(n,m,w);
}
#include "MainHead.h"
/*
*/
void savetofile() /*信息存入文件file*/
{
FILE *fp;
int i;
if((fp=fopen("Spcfile.txt","w"))==NULL)
{
printf("cannot open the file\n");
return;
}
for(i=0;i<N;i++)
{
if(a[i].snum!='\0')
if(fwrite(&a[i],sizeof(snode),1,fp)!=1)
{
printf("file write error\n");
return;
}
}
fclose(fp);
}
#include "MainHead.h"
/*
*/
void readfromfile() /*信息从文件file中取出*/
{
int i;
FILE *fp;
if((fp=fopen("Spcfile.txt","rb"))==NULL)
{
printf("cannot open the file\n");
return;
}
for(i=0;i<N;i++)
fread(&a[i],sizeof(snode),1,fp);
fclose(fp);
}
#include "MainHead.h"
/*
Function: 信息输出
Input:
param: argu n, n表示学校个数
Param: argu m, m表示男子项目个数
Param: argu w, m表示女子项目个数
Output:
Return:
*/
void output(int n,int m,int w) /*2.统计输出*/
{
readfromfile();
int i,j,s,q=0;
for(i=0;i<n;i++) /*显示结果*/
{
printf("学校编号:%d 学校总分:%d 男团总分:%d 女团总分:%d\n",a[i].snum,a[i].score,a[i].mscore,a[i].wscore);
for(j=0;j<m+w;j++)
{
printf("项目编号:%d 所取名次数量:%d\n",a[i].t[j].inum,a[i].t[j].top);
for(s=0;s<5;s++)
{
if(a[i].t[j].range[s]!=0)
printf("名次:%d 分数:%d\n",a[i].t[j].range[s],a[i].t[j].mark[s]);
}
}
printf("\n");
}
printf("\n");
printf("统计完毕!返回? 1是 2否"); /*返回菜单*/
scanf("%d",&q);
printf("\n");
if(q!=1)
printf("统计已经结束!");
printf("\n");
menu(n,m,w);
}
#include "MainHead.h"
/*
Function: 排序后输出
Input:
param: argu n, n表示学校个数
Param: argu m, m表示男子项目个数
Param: argu w, m表示女子项目个数
Output:
Return:
*/
void sortput(int n,int m,int w) /*3.排序输出*/
{
readfromfile();
int c,i,j,k,q=0;
int temp[N];
printf("\t**************排序输出系统**************\n\n");
printf("\t\t****1.按学校编号输出****\n");
printf("\t\t****2.按学校总分输出****\n");
printf("\t\t****3.按男团总分输出****\n");
printf("\t\t****4.按女团总分输出****\n");
printf("=====================================\n\n");
do
{
printf("请选择要实现功能的编号(1--4):");
scanf("%d",&c);
switch(c)
{
case 1:
for(i=0;i<n;i++)
temp[i]=i;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
if(a[temp[i]].snum>a[j].snum)
{
k=temp[i];
temp[i]=temp[j];
temp[j]=k;
}
} /* 用冒泡排序方法排序*/
for(i=0;i<n;i++)
{
printf("学校编号:%d 学校总分:%d 男团总分:%d 女团总分:%d\n",a[temp[i]].snum,a[temp[i]].score,a[temp[i]].mscore,a[temp[i]].wscore);
} /*按学校编号输出*/
break;
case 2:
for(i=0;i<n;i++)
temp[i]=i;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
if(a[temp[i]].score<a[j].score)
{
k=temp[i];
temp[i]=temp[j];
temp[j]=k;
}
} /* 用冒泡排序方法排序*/
for(i=0;i<n;i++)
{
printf("学校编号:%d 学校总分:%d 男团总分:%d 女团总分:%d\n",a[temp[i]].snum,a[temp[i]].score,a[temp[i]].mscore,a[temp[i]].wscore);
} /*按学校总分输出*/
break;
case 3:
for(i=0;i<n;i++)
temp[i]=i;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
if(a[temp[i]].mscore<a[j].mscore)
{
k=temp[i];
temp[i]=temp[j];
temp[j]=k;
}
} /* 用冒泡排序方法排序*/
for(i=0;i<n;i++)
{
printf("学校编号:%d 学校总分:%d 男团总分:%d 女团总分:%d\n",a[temp[i]].snum,a[temp[i]].score,a[temp[i]].mscore,a[temp[i]].wscore);
} /*按男团总分输出*/
break;
case 4:
for(i=0;i<n;i++)
temp[i]=i;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
if(a[temp[i]].wscore<a[j].wscore)
{
k=temp[i];
temp[i]=temp[j];
temp[j]=k;
}
} /* 用冒泡排序方法排序*/
for(i=0;i<n;i++)
{
printf("学校编号:%d 学校总分:%d 男团总分:%d 女团总分:%d\n",a[temp[i]].snum,a[temp[i]].score,a[temp[i]].mscore,a[temp[i]].wscore);
} /*按女团总分输出*/
break;
default:
printf("输入错误,请重试!\n");
}
printf("请选择 1 返回主菜单 0继续"); /*返回菜单或继续排序*/
scanf("%d",&q);
printf("\n");
}
while(q==0);
printf("\n");
if(q!=0)
menu(n,m,w);
}
#include "MainHead.h"
/*
Function: 查询项目信息
Input:
param: argu n, n表示学校个数
Param: argu m, m表示男子项目个数
Param: argu w, m表示女子项目个数
Output:
Return:
*/
void search(int n,int m,int w) /*查询函数*/
{
readfromfile();
int c,i,j,k,d,l,q=0;
printf("\t****************查询系统****************\n\n");
printf("\t\t****1.按学校编号查询****\n");
printf("\t\t****2.按项目编号查询****\n");
printf("=====================================\n\n");
do
{
k=-1;d=-1;l=-1;
printf("请选择要实现功能的编号(1--2):");
scanf("%d",&c);
switch(c)
{
case 1:
printf("要查询的学校编号:"); /*查找学校编号下标*/
scanf("%d",&c);
for(i=0;i<n;i++)
{
if(a[i].snum==c)
k=i;
}
if(k==-1)
printf("错误:这个学校没有参加此次运动会!\n");
else
{
printf("要查询的项目编号:"); /*查找项目编号下标*/
scanf("%d",&c);
for(j=0;j<m+w;j++)
{
if(a[k].t[j].inum==c)
d=j;
}
if(d==-1)
printf("此次运动会没有这个项目\n");
else /*显示结果*/
{
printf("这个项目取前 %d名,该学校的成绩如下:\n", a[k].t[d].top);
for(i=0;i<5;i++)
if(a[k].t[d].range[i]!=0)
printf("名次:%d\n",a[k].t[d].range[i]);
}
}
break;
case 2:
printf("要查询的项目编号:"); /*查找项目编号下标*/
scanf("%d",&c);
for(i=0;i<n;i++)
for(j=0;j<m+w;j++)
if(a[i].t[j].inum==c)
l=j;
if(l==-1)
printf("此次运动会没有这个项目\n");
else /*显示结果*/
{
printf("该项目取前 %d名,取得名次的学校\n",a[0].t[l].top);
for(i=0; i<n;i++)
for(j=0;j<5;j++)
if(a[i].t[l].range[j]!=0)
printf("学校编号:%d,名次:%d\n",a[i].snum,a[i].t[l].range[j]);
}
break;
default:
printf("输入错误,请重试!\n");
}
printf("请选择:1.返回主菜单 0.继续"); /*返回菜单或继续查询*/
scanf("%d",&q);
printf("\n");
}
while(q==0);
printf("\n");
if(q!=0)
menu(n,m,w);
}
七、运行结果分析
本次运行模拟使用Windows 7操作系统,在VC++ 6.0软件上进行模拟。CPU采用Intel i3系列,主机内存4GB。
【】测试数据:
测试数据选择:
(说明:测试取学校个数为2,男子项目个数为2,女子项目个数为1)
学校 项目 名次(取前三) 名次(取前五)
1)学校1 男子项目一 3 1,4
男子项目二 2 2,5
女子项目 1 3,4
2)学校2 男子项目一 2 2,5
男子项目二 1 3
女子项目 3 2,5
【】展示页面效果:
输入数据,主页面展示:
1)全部合法数据,分数统计输出:
2)整体非法数据,输出现象:
3)局部非法数据分别进行程序测试:
经过整数测试,非法数据测试,均可以正常运行出结果,符合设计要求。经过本次设计我发现,自己对于最数据存储与文件操作、搜索算法掌握深入了解,加深自我理解,对以后的学习获益良多,同时也提高了个人的编程能力。