SZU面向对象程序设计OJ复盘|第二周结构体&引用|思路分享

A. 小票输入输出(结构体)

题目描述:

现在人的消费习惯大多是刷卡消费,商家会通过POS机回执一个小票,包含商家名称、终端号、操作员、发卡方、有效期、卡号、交易时间、消费金额等信息,把商家信息定义为一个Struct结构,按照要求输出相应的格式小票。

输入:

第一行输入消费次数(刷卡次数)

第二行以此输入小票包含的各种属性;

第三行与第二行类似,以此类推。。。

输出:

根据输入信息,依次输出各次刷卡信息$

输入样例:

2
TianHong 00001 01 CCB 21/06 6029071012345678 2016/3/13 1000.00
Cindy 00002 02 CCB 21/07 6029071055558888 2015/3/13 50.00

输出样例:

Name: TianHong
Terminal: 00001 operator: 01
Card Issuers: CCB Validity: 21/06
CardNumber: 6029********5678
Traded: 2016/3/13
Costs: $1000.00

Name: Cindy
Terminal: 00002 operator: 02
Card Issuers: CCB Validity: 21/07
CardNumber: 6029********8888
Traded: 2015/3/13
Costs: $50.00

 代码参考:

#include<iostream>
#include<string>
#include<iomanip>
using namespace std;

struct merchant{
	string name;
	string terminal;
	string op;
	string cardIssuers;
	string validity;
	string cardnum;
	string time;
	double money;
};

int main(){
	int t;
	cin >> t;
	while(t--){
		merchant m;
		cin >> m.name >> m.terminal >> m.op >> m.cardIssuers >> m.validity >> m.cardnum >> m.time >> m.money;
		cout << "Name: " << m.name << endl;
		cout << "Terminal: "<< m.terminal << " operator: " << m.op << endl;
		cout << "Card Issuers: " << m.cardIssuers << " Validity: " << m.validity << endl;
		cout << "CardNumber: " << m.cardnum.substr(0,4) + "********" << m.cardnum.substr(12,16) << endl;
		cout << "Traded: " << m.time << endl;
		cout << "Costs: " << "$" << fixed << setprecision(2) << m.money << endl;
		cout << endl;
		if (t!=0){
          cout << endl;
        }
	}
	return 0;
}

B. 三数论大小(引用)

题目描述

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

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

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

输入

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

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

输入t行

输出

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

输入样例:

 3
2 4 6
88 99 77
111 333 222

输出样例:

6 4 2
99 88 77
333 222 111

参考代码:

#include<iostream>
using namespace std;

void sort(int &a, int &b, int &c){
	if(a<b){
		swap(a,b);
		if(b<c){
			swap(b,c);
			if(a<b){
				swap(a,b);
			}
		}
	}
}

int main(){
	int t;
	cin >> t;
	while(t--){
		int num1, num2, num3;
		cin >> num1 >> num2 >> num3;
		sort(num1,num2,num3);
		cout << num1 << " " << num2 << " " << num3 << endl;
	}
	return 0;
}

tips: 之前传指针就像把数据的地址传过去,传引用就像传数据本身。(我是这么理解的qaq) 

 C. 谁是老二(结构体)

题目描述

定义一个结构体,包含年月日,表示一个学生的出生日期。然后在一群学生的出生日期中找出谁的出生日期排行第二

要求:出生日期的存储必须使用结构体,不能使用其他类型的数据结构。

要求程序全过程对出生日期的输入、访问、输出都必须使用结构。

输入

第一行输入t表示有t个出生日期

每行输入三个整数,分别表示年、月、日

依次输入t个实例

输出

输出排行第二老的出生日期,按照年-月-日的格式输出

输入样例:

6
1980 5 6
1981 8 3
1980 3 19
1980 5 3
1983 9 12
1981 11 23

输出样例:

1980-5-3

参考代码:

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

struct student{
	int year, month, day;
};

bool compare(const student &a, const student &b){
	if (a.year != b.year)
		return a.year < b.year;
	if (a.month != b.month)
		return a.month < b.month;
	return a.day < b.day;
}

int main(){
	int t;
	cin >> t;
	student s[t];
	for(int i=0;i<t;i++){
		cin >> s[i].year >> s[i].month>> s[i].day;
	}
	
	sort(s,s+t,compare);
	cout << s[1].year << "-" << s[1].month << "-" << s[1].day << endl;
	return 0;
}

tips: 比较可以通过sort函数实现,然后自定义比较规则    return x < y 即实现降序(大的在前面)

记得引进algorithm库

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

题目描述

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

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

注意:不能定义全局变量

输入

测试数据的组数 t

第一组第一个分数

第一组第二个分数

第二组第一个分数

第二组第二个分数

......

输出

第一组两个分数的和

第一组两个分数的差

第一组两个分数的积

第一组两个分数的商

第二组两个分数的和

第二组两个分数的差

第二组两个分数的积

第二组两个分数的商

......

输入样例:

3
1/2
2/3
3/4
5/8
21/23
8/13

输出样例:

7/6
-1/6
1/3
3/4

11/8
1/8
15/32
6/5

457/299
89/299
168/299
273/184

代码参考:

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

struct fraction{
	int fenzi, fenmu;
};

int getGCD(int a, int b){
	if(a<b){
		swap(a,b);
	}
	int r = a%b;
	while(r!=0){
		a = b;
		b = r;
		r = a%b;
	}
	return b;
}

fraction addFS(fraction &f1, fraction &f2){
	fraction result;
	if(f1.fenmu==f2.fenmu){
		result.fenmu = f1.fenmu;
		result.fenzi = f1.fenzi + f2.fenzi;
	}
	else{
		int t = getGCD(f1.fenmu, f2.fenmu);
		result.fenmu = (f1.fenmu * f2.fenmu) / t;
		result.fenzi = (f1.fenzi * f2.fenmu + f2.fenzi * f1.fenmu) /t;
		
	}
	return result;
}

fraction subFS(fraction &f1, fraction &f2){
	fraction result;
	if(f1.fenmu==f2.fenmu){
		result.fenmu = f1.fenmu;
		result.fenzi = f1.fenzi - f2.fenzi;
	}
	else{
		int t = getGCD(f1.fenmu, f2.fenmu);
		result.fenmu = (f1.fenmu * f2.fenmu) / t;
		result.fenzi = (f1.fenzi * f2.fenmu - f2.fenzi * f1.fenmu) / t;
		
	}
	return result;
}

fraction mulFS(fraction &f1, fraction &f2){
	fraction result;
	int t = getGCD(f1.fenmu * f2.fenmu, f1.fenzi * f2.fenzi);
	result.fenmu = (f1.fenmu * f2.fenmu) / t;
	result.fenzi = (f1.fenzi * f2.fenzi) / t;
		
	return result;
}

fraction divFS(fraction &f1, fraction &f2){
	fraction result;
	int t = getGCD(f1.fenmu * f2.fenzi, f1.fenzi * f2.fenmu);
	result.fenmu = (f1.fenmu * f2.fenzi) / t;
	result.fenzi = (f1.fenzi * f2.fenmu) / t;
	
	return result;
}

void printFS(fraction &f){
	cout << f.fenzi << "/" << f.fenmu << endl;
}

int main(){
	int t;
	cin >> t;
	while(t--){
		char ch;	
		fraction a, b;
		cin >> a.fenzi >> ch >> a.fenmu;
		cin >> b.fenzi >> ch >> b.fenmu;
		fraction add = addFS(a,b);
		fraction sub = subFS(a,b);
		fraction mul = mulFS(a,b);
		fraction div = divFS(a,b);
		printFS(add);
		printFS(sub);
		printFS(mul);
		printFS(div);
	}
	return 0;
}

tips:又是辗转相除法,每次写都忘完了...:求两数a、b的最大公约数可采用辗转相除法,又称欧几里得算法,其步骤为:1. 交换a, b使a > b;2. 用a除b得到余数r,若r=0,则b为最大公约数,退出;3. 若r不为0,则用b代替a, r代替b,此时a,b都比上一次的小,问题规模缩小了;4. 继续第2步。

E. 抄袭查找(结构体+指针+函数) 

题目描述

已知一群学生的考试试卷,要求对试卷内容进行对比,查找是否有抄袭。

每张试卷包含:学号(整数类型)、题目1答案(字符串类型)、题目2答案(字符串类型)、题目3答案(字符串类型)

要求:使用结构体来存储试卷的信息。定义一个函数,返回值为一个整数,参数是两个结构体指针,函数操作是比较两张试卷的每道题目的答案,如果相同题号的答案相似度超过90%,那么就认为有抄袭,函数返回抄袭题号,否则返回0。相似度是指在同一题目中,两个答案的逐个位置上的字符两两比较,相同的数量大于等于任一个答案的长度的90%,就认为抄袭。

输入

第一行输入t表示有t张试卷

第二行输入第1张试卷的学生学号

第三行输入第1张试卷的题目1答案

第四行输入第1张试卷的题目2答案

第五行输入第1张试卷的题目3答案

每张试卷对应4行输入

依次输入t张试卷的数据

输出

在一行中,把发现抄袭的两个学号和题目号,数据之间用单个空格隔开

如果发现是题目1抄袭,题目号为1,以此类推

输出顺序按照输入的学号顺序进行输出

输入样例:

5
2088150555
aabcdef11
ZZ887766dd
cc33447799ZZ
2088150333
abcdef00
AABBCCDDEE
ZZ668899cc
2088150111
AABBCCDDEE
ZZ668899cc
abcdef00
2088150222
AABBCFDDeE
ZZ889966dd
abcdef000
2088150444
aabcdef00
AABBCDDDEE
cc668899ZZ

输出样例:

2088150333 2088150444 2
2088150111 2088150222 3

 参考代码:

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

struct paper{
	int id;
	string ans1;
	string ans2;
	string ans3;
};

double calculateSimilarity(const string& str1, const string& str2) {
    int len1 = str1.length();
    int len2 = str2.length();
    int len = len1 < len2 ? len1:len2;
    int count = 0;
    for (int i = 0; i < len; i++) {
        if (str1[i] == str2[i]) {
            count++;
        }
    }

    return double(count) / len;
}

int check(const paper* paper1, const paper* paper2) {
    double similarity1 = calculateSimilarity(paper1->ans1, paper2->ans1);
    double similarity2 = calculateSimilarity(paper1->ans2, paper2->ans2);
    double similarity3 = calculateSimilarity(paper1->ans3, paper2->ans3);

    if (similarity1 >= 0.9) {
        return 1;
    } else if (similarity2 >= 0.9) {
        return 2;
    } else if (similarity3 >= 0.9) {
        return 3;
    } else {
        return 0;
    }
}

int main(){
	int t;
	cin >> t;
	paper p[t];
	for(int j=0;j<t;j++){	
		cin >> p[j].id;
		cin >> p[j].ans1 >>p[j].ans2 >> p[j].ans3;
		cout << p[j].ans1 <<p[j].ans2 << p[j].ans3;
	}
	
	for (int i = 0; i < t; ++i) {
		for (int j = i + 1; j < t; ++j) {
			int plagiarism = check(&p[i], &p[j]);
			if (plagiarism) {
				cout << p[i].id << " " << p[j].id << " " << plagiarism << endl;
			}
		}
	}
	
	return 0;
}

tips: 有点意思,不过题目写的也很明白了,照着做就行。

  • 53
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值