实验三(引用和结构体)

A. OOP 交换(指针+引用)

题目描述

首先使用传递指针参数的函数swap1()实现两数据的交换,

再使用传递引用参数的函数swap2()实现两数据的交换

输入

见样例

输出

见样例

 

#include<iostream>
using namespace std;

void swap1(int *p1,int *p2);
void swap2(int &r1,int &r2);
int main()
{
    int a,b;
    cin>>a>>b;
    swap1(&a,&b);
    cout<<"swap1:"<<a<<" "<<b<<endl;
    swap2(a,b);
    cout<<"swap2:"<<a<<" "<<b<<endl;
    return 0;
}
void swap1(int *p1,int *p2)
{
    int t;
    t=*p1,*p1=*p2,*p2=t;
}
void swap2(int &r1,int &r2)
{
    int t;
    t=r1,r1=r2,r2=t;
}

B. 三数论大小(引用)

题目描述

输入三个整数,然后按照从大到小的顺序输出数值。

要求:定义一个函数,无返回值,函数参数是三个整数参数的引用,例如int &a, int &b, int &c。在函数内通过引用方法来对三个参数进行排序。主函数调用这个函数进行排序。

要求:不能直接对三个整数进行排序,必须通过函数而且是引用的方法。

输入

第一行输入t表示有t个测试实例

第二行起,每行输入三个整数

输入t行

输出

每行按照从大到小的顺序输出每个实例,三个整数之间用单个空格隔开

 

#include<iostream>
using namespace std;
void sort(int &a,int &b,int &c);
int main()
{
    int j,k,l,t;
    cin>>t;
    while(t--)
    {
        cin>>j>>k>>l;
        sort(j,k,l);
        cout<<j<<" "<<k<<" "<<l<<endl;
    }
 } 
void sort(int &a,int &b,int &c)
{
    int t;
    if(a<b)
        t=a,a=b,b=t;
    if(b<c)
        t=b,b=c,c=t;
    if(a<b)
        t=a,a=b,b=t;
}

C. 求最大值最小值(引用)

题目描述

编写函数void find(int *num,int n,int &minIndex,int &maxIndex),求数组num(元素为num[0],num[1],...,num[n-1])中取最小值、最大值的元素下标minIndex,maxIndex(若有相同最值,取第一个出现的下标。)

输入n,动态分配n个整数空间,输入n个整数,调用该函数求数组的最小值、最大值下标。最后按样例格式输出结果。

改变函数find功能不计分。

输入

测试次数

每组测试数据一行:数据个数n,后跟n个整数

输出

每组测试数据输出两行,分别是最小值、最大值及其下标。具体格式见样例。多组测试数据之间以空行分隔。

#include<iostream>
using namespace std;
#include<cmath>
void find(int *num,int n,int &minIndex,int &maxIndex);

int main()
{
    int t,n,*a,i,minIndex,maxIndex;
    cin>>t;
    while(t--)
    {
        cin>>n;
        a=new int[n];
        for(i=0;i<n;i++)
            cin>>a[i];
        find(a,n,minIndex,maxIndex);
        cout<<"min="<<a[minIndex]<<" minIndex="<<minIndex<<endl;
        cout<<"max="<<a[maxIndex]<<" maxIndex="<<maxIndex<<endl;
        cout<<endl;
        delete []a;
    }
    return 1;
}
void find(int *num,int n,int &minIndex,int &maxIndex)
{
    int i;
    minIndex=maxIndex=0;
    for(i=1;i<n;i++)
    {
        if(num[i]>num[maxIndex])
            maxIndex=i;
        if(num[i]<num[minIndex])
            minIndex=i;
    }
}

 

D. 访问数组元素(引用)

题目描述

输入n,输入n个数,计算n个数的和并输出。

假设主函数定义如下,不可修改。请补齐put函数。

输入

测试次数

每组测试数据一行,正整数n(1~1000),后跟n个整数。

输出

每组测试数据输出一行,即n个整数的和。

 

#include<iostream>
using namespace std;
#include<cstring>

#define N 1000
int &put(int *num,int i);
int main()
{
    int num[N];
    int t,n,sum,i;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(i=0;i<n;i++)
            cin>>put(num,i);
        for(sum=0,i=0;i<n;i++)
            sum+=num[i];
        cout<<"sum="<<sum<<endl;
    }
    return 0;
}

int &put(int *num,int i)
{
    return num[i];
}

 

E. OOP 学生成绩排序(结构)

题目描述

有N个学生的数据,将学生数据按成绩由低到高排序,如果成绩相同则按姓名首字母序排序,如果首字母也相同则按照年龄排序,并输出N个学生排序后的信息。

输入

测试数据有多组,每组输入第一行有一个整数N(N<=1000),接下来的N行包括N个学生的数据。
每个学生的数据包括姓名(长度不超过100的字符串)、年龄(整型数)、成绩(小于等于100的正数)。

输出

将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。
然后输出学生信息,按照如下格式:
姓名 年龄 成绩

#include<iostream>
using namespace std;
#include<algorithm>
#include<cstring>
struct student
{
    char name[20];
    int age,score;
};
int comp(student s1,student s2);
int main()
{
    int N,i;
    cin>>N;
    student *stu=new student[N];
    for(i=0;i<N;i++)
        cin>>stu[i].name>>stu[i].age>>stu[i].score;

    sort(stu,stu+N,comp);
    for(i=0;i<N;i++)
        cout<<stu[i].name<<" "<<stu[i].age<<" "<<stu[i].score<<endl;

    delete [] stu;
    return 0;
}

int comp(student s1,student s2)
{
    if(s1.score<s2.score)
        return 1;

    if(s1.score==s2.score && strcmp(s1.name,s2.name)<0)
        return 1;

    if(s1.score==s2.score && strcmp(s1.name,s2.name)==0 && s1.age>s2.age)
        return 1;

    return 0;
}

 

F. 分数四则运算(结构)

题目描述

分数的分子和分母可用一个结构类型来表示。

编写实现两个分数加(addFS),减(subFS),乘(mulFS),除(divFS)的函数(要求计算结果分数是简化的),以及打印一个分数(printFS),计算两个整数最大公约数的函数(getGCD)。

注意:不能定义全局变量

输入

测试数据的组数 t

第一组第一个分数

第一组第二个分数

第二组第一个分数

第二组第二个分数

......

输出

第一组两个分数的和

第一组两个分数的差

第一组两个分数的积

第一组两个分数的商

第二组两个分数的和

第二组两个分数的差

第二组两个分数的积

第二组两个分数的商

......

#include<iostream>
using namespace std;
#include<cmath>
struct FS
{
    int fz,fm;
};
int gcd(int a,int b);
FS addFS(FS f1,FS f2);
FS subFS(FS f1,FS f2);
FS mulFS(FS f1,FS f2);
FS divFS(FS f1,FS f2);
void printFS(FS f);
int main()
{
    int t;
    FS f1,f2,f;
    char ch;
    cin>>t;
    while(t--)
    {
        cin>>f1.fz>>ch>>f1.fm;
        cin>>f2.fz>>ch>>f2.fm;
        f=addFS(f1,f2);
        printFS(f);
        f=subFS(f1,f2);
        printFS(f);
        f=mulFS(f1,f2);
        printFS(f);
        f=divFS(f1,f2);
        printFS(f);
        cout<<endl;
    }
    return 1;
}
int gcd(int a,int b)
{
    int r=a%b;
    while(r)
    {
        a=b;
        b=r;
        r=a%b;
    }
    return b;
}
FS addFS(FS f1,FS f2)
{
    FS f;
    f.fm=f1.fm*f2.fm;
    f.fz=f1.fz*f2.fm+f1.fm*f2.fz;
    int t=gcd(abs(f.fm),abs(f.fz));
    if(t!=1)
    {
        f.fm=f.fm/t;
        f.fz=f.fz/t;
    }
    return f;
}
FS subFS(FS f1,FS f2)
{
    FS f;
    int t;
    f.fm=f1.fm*f2.fm;
    f.fz=f1.fz*f2.fm-f2.fz*f1.fm;
    if((t=gcd(abs(f.fm),abs(f.fz)))!=1)
    {
        f.fm=f.fm/t;
        f.fz=f.fz/t;
    }
    return f;
}
FS mulFS(FS f1,FS f2)
{
    FS f;
    int t;
    f.fm=f1.fm*f2.fm;
    f.fz=f1.fz*f2.fz;
    if((t=gcd(abs(f.fm),abs(f.fz)))!=1)
    {
        f.fm=f.fm/t;
        f.fz=f.fz/t;
    }
    return f;
}
FS divFS(FS f1,FS f2)
{
    FS f;
    int t;
    f.fz=f1.fz*f2.fm;
    f.fm=f1.fm*f2.fz;
    if((t=gcd(abs(f.fm),abs(f.fz)))!=1)
    {
        f.fm=f.fm/t;
        f.fz=f.fz/t;
    }
    return f;
}
void printFS(FS f)
{
    if(f.fm*f.fz>0)
        cout<<abs(f.fz)<<"/"<<abs(f.fm)<<endl;
    else
        cout<<"-"<<abs(f.fz)<<"/"<<abs(f.fm)<<endl;
}

G. 扑克牌排序(结构体)

题目描述

自定义结构体表示一张扑克牌,包含类型——黑桃、红桃、梅花、方块、王;大小——2,3,4,5,6,7,8,9,10,J,Q,K,A,小王(用0表示)、大王(用1表示)。输入n,输入n张扑克牌信息,从大到小输出它们的排序结果。

假设扑克牌的排序规则是大王、小王为第一大、第二大,剩余52张扑克牌按照先花色后大小排序。

花色:黑桃>红桃>梅花>方块。

大小: A>K>Q>J>>10>9>...>2。

提示:百度sort函数、strstr函数使用。

输入

测试次数t

每组测试数据两行:

第一行:n,表示输入n张扑克牌

第二行:n张扑克牌信息,格式见样例

输出

对每组测试数据,输出从大到小的排序结果

#include<iostream>
using namespace std;
#include<algorithm>
#include<string>
struct card
{
	string face;
    int num;
};
bool compCard(card c1,card c2);
int main()
{
	string num[13]={"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
	string type[6]={"方块","梅花","红桃","黑桃","小王","大王"};
	string str;
	card poker[54];
	int t,n,i,j;
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(i=0;i<n;i++)
		{
			cin>>str;
			poker[i].face=str;
			poker[i].num=0;
			for(j=0;j<6;j++)
				if((int)str.find(type[j])!=-1)
				{	poker[i].num+=j*13;break;}
			for(j=0;j<13;j++)
				if((int)str.find(num[j])!=-1)
				{	poker[i].num+=j;break;}
		}
		sort(poker,poker+n,compCard);
		for(i=0;i<n-1;i++)
			cout<<poker[i].face<<" ";
		cout<<poker[i].face<<endl;
	}
	return 0;
}
bool compCard(card c1,card c2)
{
	return c1.num>c2.num;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言程序设计 "实"1.掌握结构类型的概念和说明方法 " "验"2.掌握结构变量的定义和引用结构类型变量成员的使用。 " "目"3.掌握结构数组的定义和使用方法。 " "的"4.掌握指向结构变量的指针变量的概念和应用。 " " "5.掌握结构变量与指向结构的指针作为函数参数实现函数的调用。 " " "6.掌握共用的概念和说明方法。 " " "7.掌握共用变量的定义和引用。共用类型变量成员的使用 " " "8.掌握位运算的概念和方法。 " " "9.掌握位运算符(&,", ,~)的使用方法。 " " "10.了解有关位运算的算法。 " " "11.掌握枚举类型概念和说明方法 " " "12.掌握枚举类型变量的定义以及枚举类型变量的使用。 " " "1.建立一个学生的简单信息表,其中包括学号、年龄" " " "、性别及一门课的成绩。要求从键 " " " "盘输入数据,并显示出来。上机运行以下程序。 " " " "分析:一个学生信息表可以由结构来定义,表中的 " " " "内容可以通过结构中的成员来 " " " "表示。结构成员的点运算符引用方法。 " " " "#include"stdio.h" " " "实"void main() " " " "{ " " "验"struct st " " " "{ " " "内"int num; " " " "int age; " " "容"char sex; " " " "float score; " " "与"}; " " " "struct st info; " " "步"printf("input number:"); " " " "scanf("%d",&info.num); " " "骤"printf("input age:"); " " " "scanf("%d",&info.age); " " " "getchar(); " " " "printf("input sex:"); " " " "scanf("%c",&info.sex); " " " "printf("input score:"); " " " "scanf("%f",&info.score); " " " "printf("number=%d\n",info.num); " " " "printf("age=%d\n",info.age); " " " "printf("sex=%c\n",info.sex); " " " "printf("score=%f\n",info.score); " " " "} " " " "2.建立 5 " " " "名学生的信息表,每个学生的数据包括学号、姓名及 " " " "一门课的成绩。要求从键盘 " " " "输入这 5 名学生的信息,并按照每一行显示一名学 " " " "生信息的形式将 5 名学生的信息显示出 " " " "来。上机运行以下程序。 " " " "分析:每个学生的数据学号、姓名及一门课的成绩用 " " " "结构表示,5 名学生的信息表 " " " "用结构数组表示,结构数组元素的引用方法 " " " "。 " " " "#include"stdio.h" " " " "#define N 5 " " " "struct stud " " " "{ " " " "int num; " " " "char name [20]; " " "实"float score; " " " "}; " " "验"struct stud s[N]; " " " "void main() " " "内"{ " " " "int i; " " "容"for (i=0;i<N;i++) " " " "{ " " "与"printf("input number:"); " " " "scanf("%d",&s[i].num); " " "步"printf("input name:"); " " " "scanf("%s",s[i].name); " " "骤"printf("input score:"); " " " "scanf("%f",&s[i].score); " " " "} " " " "for (i=0;i<N;i++) " " " "{ " " " "printf("%d ",s[i].num); " " " "printf("%s ",s[i].name); " " " "printf("%f\n",s[i].score); " " " "} " " " "} " " " "3.显示某人工资信息的程序如下,分析显示结果。上 " " " "机运行以下程序。 " " " "分析:某人工资信息可以由结构来定义,表中的内 " "
1 、结构与类的编写: (A)利用struct关键字定义一个学生结构(包括学号、姓名、性别):类名:student, num、name、sex,在主函数定义两个对象stud1,stud2,对stud1对象赋值并输出,对第2个对象stud2赋值输出; (B)利用class关键字将1改成类的编写,其它不变 (C)将输出封装成display,输入封装成setdata函数,分别在类里面定义2函数,在主函数中输入输出; (D)将上面两成员函数移至类外定义并输出 (E)将setdata函数利用对象的引用做函数参数,在主函数中输入输出 2、(1)定义一个时间类,属性包括小时、分、秒,定义两成员函数:settime,showtime,分别以两种方式、类内定义成员函数和内外定义成员函数 (2)对1两成员函数分别利用对象的引用做参数、默认参数做参数进行编写与调用并输出。属性 3、编写一个程序,模拟电梯的功能。功能接口包括电梯上行按钮、下行按钮、楼层选择和电梯在行驶过程中的楼层显示。 要求: (1)、由用户选择按上行按钮还是下行按钮,选择操作后再由用户输入要进入的楼层,进而电梯开始运行,显示所到的每一楼层层数。 (2).如果是上行,则选择输入的楼层号不能比当前楼层号小,否则应给出不合法提示。 (3). 如果是下行,则选择输入的楼层号不能比当前楼层号大,否则应给出不合法提示。 (4).电梯一旦开始运作就会始终运行,直到窗口关闭。 (5).电梯在经过不同楼层时,最好每个楼层的显示之间能有延迟,最终停靠的楼层的输出形式能更加醒目。如果可以,在电梯最初开始运行时,能在电梯由内部显示当前日期(提示:实现这些功能时,需要调用系统api,实现时间显示功能可以使用CDate类)。
1基础题_2.由计算机生成简单的四则运算题 1.1 需求分析: 本题主要是要求设计一个可以自动生成四则运算的测试器,并且完全由用户决定出加、减、乘、除哪一种运算题,以及出一位数还是两位数的运算题,同时还要对用户给出的答案的对错进行判断。在程序运行过程中,用户可以选择何时结束程序,并在结束程序时给出一个某种形式的成绩。 ///////////////////////////////////////////// 程序执行的结果://///////////////////////////////////////////////// 1.2 概要设计: 在对题目理解的基础上,并针对几个特别的技术环节,我认为程序可分为三个部分: 1) 程序的欢迎界面,主要通过一些特殊制表符来完成。其中运行,退出程序可以通过一个while循环来判定同时还要考虑用户输入信号量的正误; 2) 出题函数,也是本程序最关键的一个函数,通过使用“rand()%10”或“rand()%100”来获得一个0到9的一位整数随机值或得到0到99的两位整数随机值来为用户出题,并判断用户答案的对错; 3) 评分系统,是在用户选择退出后对用户所答题情况给出的成绩评价。 /////////////////////////////////////////////////// 程序流程图: 1.3 详细设计与编码: 为了使程序更加简洁与工整,且容易修改和阅读,我采用头文件的方式将Exam()函数放在了Exam .h中。Exam()函数主要负责程序的出题和结果的判断,其输入接口为运算符号,位数,即只需向其输入四则运算的一种符号和运算的位数,函数便自动生成题目并自动判断结果的正误,结果以1,0返回。而主程序则是完成了程序的开始、结束,用户成绩的判定。 /////////////////////////////////////////////////// 具源程序如下: ---------------------------------------------------------------------------------------------------------------------- int Exam(int figure, int sign) {//本函数负责给用户出题 if (figure!=1&&figure!=2&&sign<1&&sign>4) return 0; //判断函数的输入是否符合要求 int a, b; if (figure==1) a=rand()%10; b=rand()%10; if (figure==2) a=rand()%100; b=rand()%100; switch(sign) { case(1): { cout<<" "<<a<<'+'<<b<<'='; int r; cin>>r; if(r!=a+b) { cout<<" "<<"╳ 很遗憾,回答错误! X﹏X "<<endl; return -1; } else { cout<<" "<<"√ 恭喜你回答正确!↘(^ω^)↙"<<endl; return 1; } } case(2): { cout<<" "<<a<<'-'<<b<<'='; int r; cin>>r; if(r!=a-b) { cout<<" "<<"╳ 很遗憾,回答错误! X﹏X "<<endl; return -1; } else { cout<<" "<<"√ 恭喜你回答正确!↘(^ω^)↙"<<endl; return 1; } } case(3): { cout<<" "<<a<<'*'<<b<<'='; int r; cin>>r; if(r!=a*b) { cout<<" "<<"╳ 很遗憾,回答错误! X﹏X "<<endl; return -1; } else { cout<<" "<<"√ 恭喜你回答正确!↘(^ω^)↙"<<endl; return 1; } } case(4): { while(b==0) b=rand()%10; cout<<" "<<a<<'/'<<b<<'='; int r; cin>>r; if(r!=a/b) { cout<<" "<<"╳很遗憾,回答错误! X﹏X "<<endl; return -1; } else { cout<<" "<<"√ 恭喜你回答正确!↘(^ω^)↙"<<endl; return 1; } } } return 0; } ---------------------------------------------------------------------------------------------------------------------- main() 见上传程序 Arithmetic . cpp文件 1.4 调试分析: 为了使程序的欢迎界面更加的友好,我采用了制表符来美化程序界面,让整个程序不会显得那么的单调和无趣。在调试过程中,为了使界面好看确实下了很大的功夫。 在调试过程中程序使用"rand()%10"或"rand()%100" 获得的随机数往往不随机,即获得的随机数不变,经过查阅资料和详细分析,原来它需要初始化。 1.5 用户使用说明: 友好的程序界面给人一种亲切感,整个程序使用起来并不是十分的复杂,只需要根据每步的提示进行即可。至于在进行除法运算时,面对无法除尽的数用户只需要保留小数点后一位数字即可。 1.6 设计心得: 设计制作类似的程序已经不是第一次了,但这次却是比以前各次都下了大功夫。虽然整个题目并不是很难,出题函数也比较容易实现,但我抓住了程序界面的设计,让整个程序变得友好而吸引人。然原本枯燥的四则运算测试变得有意思。而且通过这次的编程,使我对设计一个程序的步骤更加的熟悉,为后面的加强题打下了坚实的基础。 运行程序后,看到自己完全独立设计制作的程序,一种无比的自豪感油然而生,内心掩饰不住的喜悦。特别是听到在同学们看到我的程序界面时发出的感叹声时,心里也是无比的开心。 2基础题_6.钱币兑换问题(贪心算法) 2.1 需求分析: 本题主要是要求设计一个程序,让用户输入正整数m ,它代表一个人民币钱数(元数),由程序计算一个最有方法,使人民币纸币的张数最少,并凑成上述的钱数m 。 ///////////////////////////////////////////// 程序执行的结果://///////////////////////////////////////////////// 2.2 概要设计: 在对题目理解的基础上,以及题目中所给出的要求,我认为此问题最好还是选用贪心算法会比较方便。而且由于此问题也恰巧是贪心算法的最典型应用,即所求问题的整最优解可以通过一系列局部最优的选择来达到。 /////////////////////////////////////////////////// 程序流程图: 2.3 详细设计与编码: 根据上面的流程图可以看到如果是一步一步的写程序,势必会让程序变得冗长且不易阅读,因而我想到使用循环的方法,将流程图中类似的结构做成一个循环来实现,使程序源代码变得十分的简洁,且容易被阅读和修改。 /////////////////////////////////////////////////// 具源程序如下: ---------------------------------------------------------------------------------------------------------------------- void main() { cout<<"请输入总钱数 m"; int m=0; cin>>m; int N[7]={0,0,0,0,0,0,0}; //用来存储每种面值纸币所需的数目 int Money[7]={100,50,20,10,5,2,1}; //存放7种纸币的面值 for (int i=0; i<7; i++) { while (m>=Money[i]) { m-=Money[i]; N[i]++; } } cout<<"最少使用"<<endl; for (i=0; i<7; i++) { cout<<"\t面值"<<setw(3)<<Money[i] <<"的纸币"<<N[i]<<"张"<<endl; } } ---------------------------------------------------------------------------------------------------------------------- 2.4 调试分析: 本程序的调试工作显得非常的简单,只需要对几个特殊的值进行检查就行了。程序输出也是十分的清晰,容易查错。这主要是由于问题并不是十分复杂,再加上贪心算法的简便性。使得整个程序浑然一。 2.5 用户使用说明: 在程序运行后需要用户输入需要兑换的总钱数,回车后系统便自动将各种纸币所需要的张数输出来。供用户参考。且输出的结果是张数最少的情况。 2.6 设计心得: 钱币兑换问题是个非常简单的题目,完成本题所需的编程技巧并不多,但却巩固了我在算法设计与分析课上所学到的很多知识。特别是对于贪心算法,不但让我对其有了更进一步的了解,而且使我能够更好的掌握在分析问题时,首先对问题的解决算法进行分析的能力。 3基础题_9.约瑟环问题(使用数组存放人员编号) 3.1 需求分析: 本题主要是要求设计一种算法,使用数组来存放n个人,而后从1号人员开始报数(顺时针方向),当数到k时(其中k>1由用户通过cin输入指定),则该号人员被“淘汰出局”;接着仍沿顺时针方向从被淘汰出局者的下一人员又重新从1开始数起,数到k后,淘汰第2个人;如此继续,直到最后剩下一个人时停止。请输出最后所剩那一个人的编号,并输出淘汰过程的某种“中间结果数据”。 ///////////////////////////////////////////// 程序执行的结果://///////////////////////////////////////////////// 3.2 概要设计: 在对题目理解的基础上,以及题目中所给出的要求,我认为此问题可以通过模拟指针循环查找的方法来实现题目所给的限定。在淘汰人员时,我准备利用一个布尔数组来存放这n个人的状态(是否被淘汰),然后通过一个point"指针"对其进行循环查找。而另定义一个j变量来进行报数操作。不但可以实现在时下最后一个人时输出这个人的编号,还可以在每次淘汰人员时,输出被淘汰人员的编号。 /////////////////////////////////////////////////// 程序流程图: 3.3 详细设计与编码: 因为总人数是由用户所给定的,所以主函数内的所有涉及n的数组都需要使用动态数组来进行定义。整个报数环节在主函数中现在一个while循环上,而跳出这个循环的条件便是对队列中人数的判断,即当队列中的人数只剩下一个时,跳出此循环。 /////////////////////////////////////////////////// 具源程序如下: ---------------------------------------------------------------------------------------------------------------------- void main() { int n, k; cout<<"请输入总人数 n:"; cin>>n; cout<<"请输入报数的最大值 k:"; cin>>k; bool *p=new bool[n+1]; //布尔 p 数组用来存放 n 个人的状态 for (int i=1; i<=n; i++) p[i]=1;//1 状态在队列里 0 被淘汰了 int point=0, j=0, m=n; //point 编号指针 j 报数 m 队列里剩有的人数 while (true) { j++; point++; if (point==n+1) point=1; //point 指向 n+1 是转到1 while (p[point]==0) { point++; if (point==n+1) point=1; } if (j==k) //报数报到 k { p[point]=0; cout<<"编号为 "<<point<<" 的人被淘汰了。"<<endl; m--; j=0; } if (m==1) break; //队列只剩下1个人时跳出循环 } point=1; while (p[point]==0) point++; cout<<"最后剩下的人的编号为 "<<point<<" 。"<<endl; } ---------------------------------------------------------------------------------------------------------------------- 3.4 调试分析: 本程序的调试并不怎么复杂,但却有点麻烦。因为为了测得程序运行的正确性,在输入n之前,我总是要先把正确的答案计算出来,再对程序的结果进行比较。其中也难免自己计算错误的时候,况且n的值越大,其产生的结果也就越繁多,因而比较耗时。 在整的调试下,本程序并没有出现错误,在对每步输出上也是比较完美的,达到了预先设定的效果。 3.5 用户使用说明: 在程序运行后需要用户输入排成一圈的总人数n,接着会让用户输入报数的最大值k,这两个数理论上在大小上没有限制,但输入的必须是整型正整数,否则系统会报错。在程序输出时,每一步所淘汰的成员编号都会被输出,因而用户可以清晰地看到整个的淘汰过程。并可由最后输出的结果知道最后会剩下哪个编号的成员。 3.6 设计心得: 约瑟环问题是一个比较老的问题了,在刚接触C++语言时就做过类似的题目,因而完成起来并没有太大难度。虽然在题目中对设计时所使用的数据结构进行了限制,但这并不是本题的难点,我认为关键在于超越自我,设计出与我过去编程时所设计出的程序有所不同。我觉得我做到了,这次的程序是我完全重新设计的,从算法到数据结构的使用均是独立完成,感到很有成就感。 4基础题_11.猜扑克牌问题 4.1 需求分析: 本题主要是要求设计一个程序,能让计算机来猜测用户“暗记”的某张扑克牌:计算机从一副扑克牌(54张)中任意抽出27张,摆放在不同的三行上(每行9张),用户“暗记”某张纸牌,而后告诉计算机所“暗记”的那张纸牌处于哪一行中;之后计算机再两次将纸牌重新摆放,并让用户再回答两次相同的提问(那张纸牌在重新摆放后又处在哪一行上);此时计算机会将用户所“暗记”的那张纸牌给挑出来。 ///////////////////////////////////////////// 程序执行的结果://///////////////////////////////////////////////// 4.2 概要设计: 在对题目理解的基础上,以及题目中所给出的要求,我认为此问题有以下两个重点: 1)要从一副54张的扑克牌中任意抽出27张,可通过“rand()%54”所产生的随机值来确定。但注意,一旦随机抽走哪张,下次牌中就没有这张了。 2)程序总按照一种策略将三行纸牌重新“摆放”,而后进一步让用户进行指定。上述所谓的策略指的是,总将纸牌“一分为三”:第一次要将每一行的9张分散到不同的3行上(每行仅“剩”3张),而第二次则要将上次“确定”出的某3张进一步分散到不同的3行上(每行只“剩”1张。此时靠用户再指定一次行号则可唯一确定所“暗记”的那张纸牌)。 /////////////////////////////////////////////////// 程序流程图: 4.3 详细设计与编码: 题目中有很多地方都涉及到无序排列的问题,再加上一旦随机抽走哪张,下次牌中就没有这张了,而且在分组完成后数据的存放都是一个问题。所以我采用布尔变量数组来存放牌的状态(抽走了为0,未抽走为1)。而使用string数组来存放每一张牌。在输出的问题上,我将无须输出和有序输出函数单独做成一个头文件:OutWay.h ,以方便函数的调用于阅读。为解决题目的最终问题,在流程图中的交换操作需要下一些功夫才能很好的完成。 /////////////////////////////////////////////////// 具源程序如下: ---------------------------------------------------------------------------------------------------------------------- void main() { srand(GetTickCount()); //使rand()函数每次所取得随机数不同 string squeezer[54]={"\3- A","\3- 2","\3- 3","\3- 4","\3- 5","\3- 6","\3- 7","\3- 8","\3- 9", "\3-10","\3- J","\3- Q","\3- K","\4- A","\4- 2","\4- 3","\4- 4","\4- 5", "\4- 6","\4- 7","\4- 8","\4- 9","\4-10","\4- J","\4- Q","\4- K","\5- A", "\5- 2","\5- 3","\5- 4","\5- 5","\5- 6","\5- 7","\5- 8","\5- 9","\5-10", "\5- J","\5- Q","\5- K","\6- A","\6- 2","\6- 3","\6- 4","\6- 5","\6- 6", "\6- 7","\6- 8","\6- 9","\6-10","\6- J","\6- Q","\6- K","KING1","KING2"}; //顺序列出54张牌 cout<<"The 54 cards aring in proper order is arranged as follows: "<<endl; Order_Out(squeezer, 54); string draw[27]; //存放随机抽取出来的27张牌 string line1[9], line2[9], line3[9]; //分别存放从27张牌中抽取出的9张牌 bool a1[54], a2[27]; //状态参数,a1用来存放第一次随机抽取时54张牌的状态 //a2用来存放第二次随机抽取时27张牌的状态 for (int i=0; i<54; i++) a1[i]=true;//状态初始化 for (i=0; i<27; i++) a2[i]=true;//状态初始化 int b; //用来产生随机数 for (i=0; i<27; i++) { b=rand()%54; //产生0~53之间的随机数 while(a1[b]==false) b=rand()%54; //产生0~53之间的随机数 a1[b]=false; draw[i]=squeezer[b]; } cout<<"The 27 cards sampled are arranged as follows: "<<endl; Order_Out(draw, 27); //顺序列出抽取出的27张牌 for (i=0; i<9; i++) { b=rand()%27; //产生0~27之间的随机数 while(a2[b]==false) b=rand()%27; //产生0~27之间的随机数 a2[b]=false; line1[i]=draw[b]; } for (i=0; i<9; i++) { b=rand()%27; //产生0~27之间的随机数 while(a2[b]==false) b=rand()%27; //产生0~27之间的随机数 a2[b]=false; line2[i]=draw[b]; } for (i=0; i<9; i++) { b=rand()%27; //产生0~27之间的随机数 while(a2[b]==false) b=rand()%27; //产生0~27之间的随机数 a2[b]=false; line3[i]=draw[b]; } cout<<"-------------------------------------"<<endl <<"line1:"; Orderless_Out(line1, 9); //无序输出line1 cout<<"line2:"; Orderless_Out(line2, 9); //无序输出line2 cout<<"line3:"; Orderless_Out(line3, 9); //无序输出line3 cout<<"-------------------------------------"<<endl <<"Remember a card, and tell me what line it reside in (1/2/3): "; int c; //用户输入的信号量 cin>>c; while (c<1||c>3) { cout<<"Sorry, your importation contain mistake, please reinput: "; cin>>c; } switch(c) {//将用户选出的一行分成3份,分布到每一行 case 1: { for (i=3; i<6; i++) swap(line1[i], line2[i]); for (i=6; i<9; i++) swap(line1[i], line3[i]); break; } case 2: { for (i=0; i<3; i++) swap(line2[i], line1[i]); for (i=6; i<9; i++) swap(line2[i], line3[i]); break; } case 3: { for (i=0; i<3; i++) swap(line3[i], line1[i]); for (i=3; i<6; i++) swap(line3[i], line2[i]); break; } } cout<<"-------------------------------------"<<endl <<"line1:"; Orderless_Out(line1, 9); //无序输出line1 cout<<"line2:"; Orderless_Out(line2, 9); //无序输出line2 cout<<"line3:"; Orderless_Out(line3, 9); //无序输出line3 cout<<"-------------------------------------"<<endl <<"What line the card you remenbered reside in now (1/2/3): "; cin>>c; while (c<1||c>3) { cout<<"Sorry, your importation contain mistake, please reinput: "; cin>>c; } switch(c) {//将用户选出的一行中的3个可能值,分布到每一行的首位 case 1: { swap(line1[1], line2[0]); swap(line1[2], line3[0]); break; } case 2: { swap(line2[3], line1[0]); swap(line2[4], line2[0]); swap(line2[5], line3[0]); break; } case 3: { swap(line3[6], line1[0]); swap(line3[7], line2[0]); swap(line3[8], line3[0]); break; } } cout<<"-------------------------------------"<<endl <<"line1:"; Orderless_Out(line1, 9); //无序输出line1 cout<<"line2:"; Orderless_Out(line2, 9); //无序输出line2 cout<<"line3:"; Orderless_Out(line3, 9); //无序输出line3 cout<<"-------------------------------------"<<endl <<"What line the card you remenbered reside in now (1/2/3): "; cin>>c; while (c<1||c>3) { cout<<"Sorry, your importation contain mistake, please reinput: "; cin>>c; } //用户所输入的行数的第一张牌即用户一开始就“暗记”的牌 if (c==1) cout<<"Your remenber card is: "<<line1[0]<<endl; else if (c==2) cout<<"Your remenber card is: "<<line2[0]<<endl; else cout<<"Your remenber card is: "<<line3[0]<<endl; } ---------------------------------------------------------------------------------------------------------------------- 其余函数请查看头文件OutWay.h ---------------------------------------------------------------------------------------------------------------------- 4.4 调试分析: 本程序是一个比较有意思的程序,在调试的过程中,确认结果比较容易,但要想完全检测程序是否有误,还是比较繁的。不过整个程序调试下来,还是挺好玩的,看到自己心里“暗记”的牌最后可以被计算机找出来。不过我的程序还有很大的改进空间,如将switch语句进行调整,或合并成一个大循环等。 4.5 用户使用说明: 在程序运行后需要用户根据程序的提示,在抽出的27张牌中“暗记”一张牌,然后3次回答程序“暗记”的那张牌的行数,程序便能够自动将用户所“暗记”的牌显示出来。 4.6 设计心得: 这一题是这么多题目中最有意思的一道题,向变魔术一般,将用户“暗记”的牌展示出来。整个程序还是比较复杂的,特别是我在设计输出函数时,无序排列确实让我费了一番周折。而且在这3个switch语句的case语句中的交换也是比较容易弄混的,我就在编程序是忘了在case语句后加上break而导致程序一直调试不成功,好不容易才改正过来。 5基础题_13. 找出整数的前第n位和后第n位 5.1 需求分析: 本题主要是要求设计具有如下原型的函数:int f(unsigned long x, int n, int& Lxn); 它负责将整数x的第n位(从左边数第n位,n>0)的数值放到引用Lxn之中(将作为结果返回到主调函数的对应实参变量中),并将倒数第n位(从右边数第n位,n>0)的数值作为函数结果返回去。并编制主函数对它进行调用以验证其正确性。 ///////////////////////////////////////////// 程序执行的结果://///////////////////////////////////////////////// 5.2 概要设计: 在对题目理解的基础上,以及题目中所给出的要求,我认为此问题有以下两个重点: 1)将用户输入的这个长整型的数按位存储在一个数组里; 2)通过循环输出这个数组的第n-1项和倒数第n-1项。 /////////////////////////////////////////////////// 程序流程图: 5.3 详细设计与编码: 当x=123456789,n=7时,执行语句“Rxn=f(x, n, Lxn);”将使返回的Lxn为7,并使Rxn变为3;而执行语句“Rxn=f(12345, 6, Lxn);”将使Lxn与Rxn都变为为0(超出数的“长度”即总位数时返回0)。 /////////////////////////////////////////////////// 具源程序如下: ---------------------------------------------------------------------------------------------------------------------- int f(unsigned long x, int n, int&Lxn) {//题目所要求的函数f int N=1; //用来记录无符长整数x的位数 unsigned long IM=x/10; while (IM!=0) { IM=IM/10; N++; } if (n>N) {//用来判断n是否超出x的长度 Lxn=0; return 0; } int *p=new int[N+1]; //用来存放x的每一位数 for (int i=N; i>0; i--) {//将x的每一位数字倒序的输入到数组p中 int j=pow(10,(N-i+1)); p[i]=(x%j-x%(j/10))/(j/10); } Lxn=p[n]; //返回引用Lxn的值 return p[N-n+1]; //函数返回的值 } ---------------------------------------------------------------------------------------------------------------------- main()函数见test_Main .cpp ---------------------------------------------------------------------------------------------------------------------- 5.4 调试分析: 本程序在调试的过程中,可能会遇到由于长整型数位数的限制,用户如果输入的x太大的话便会产生程序的溢出错误,造成程序进入死循环。所以在输入时,x的大小因有所限制。 5.5 用户使用说明: 在程序运行后需要用户根据程序的提示输入一个长整型的x,在输入要显示的位数n即可让程序将x的第n位和从后数第n位显示出来。 5.6 设计心得: 这道题重点便是怎样将用户输入的长整型数分位存储,当然,我们也可以选用getchar()的方式,但我个人认为还是使用数组来通过取余的方式将x的每一位村与数组中比较好。 在完成程序后,调试是发现了很多的错误,其中取余的地方就一直通不过,在反复调试后才最终将程序改好。通过这次编程使我懂得即使是非常有把握的程序,如果不细心的话,一样会碰钉子。 6基础题_14.整数组前n项是否按降序排列 6.1 需求分析: 本题主要是要求编出两种算法,一种递归一种非递归两种函数f,负责判断数组a的前n个元素是否从大到小完全有序了,是则返回true,否则返回false。 ///////////////////////////////////////////// 程序执行的结果://///////////////////////////////////////////////// 6.2 概要设计: 1)非递归函数中只需逐对地判断各a[i] 与a[i+1]是否都已从大到小有序排列(i = 0,1,…,n-2)。 2)递归函数中将问题分解处理为:若n=1(即只有1个元素时)则返回true而递归出口;n>1时,若最后一对元素不顺序则返回false,否则进行递归调用(传去实参a与 n-1,去判断前n-1个元素的顺序性),并返回递归调用的结果(与前n-1个元素的是否顺序性相同)。 /////////////////////////////////////////////////// 程序流程图:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值