首页 > 其他分享 >结对项目-四则运算

结对项目-四则运算

时间:2024-09-25 18:01:15浏览次数:1  
标签:std 结对 const string 项目 int 四则运算 Fraction return

github链接

这个作业属于哪个课程 班级的链接
这个作业要求在哪里 作业要求的链接
这个作业的目标 实现四则运算自动生成程序,结对协作开发
姓名 学号
柳浩 3122004444
洪吉潮

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 25
Estimate 估计这个任务需要多少时间 60 65
Development 开发 200 200
Analysis 需求分析 (包括学习新技术) 20 30
Design Spec 生成设计文档 50 45
Design Review 设计复审 30 30
Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 20
Design 具体设计 30 35
Coding 具体编码 150 160
Code Review 代码复审 30 35
Test 测试(自我测试,修改代码,提交修改) 30 35
Reporting 报告 50 60
Test Repor 测试报告 20 25
Size Measurement 计算工作量 10 10
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 30 30
合计 750 805
  • 设计实现过程
    代码功能通过三个类去实现:Fraction,Question,Generator

    三个类的大致结构如下图:
  • Fraction类:
    Fraction类主要作用是对分数进行管理,提供分数的自动调整和计算接口给上层类调用,如:约分,格式转化(字符流转化为数字存储以及已有分数转化为字符串便于写入文件等),以及分数 之间的运算的实现等,
    Fraction类大致结构如下:
class Fraction //分数管理类
{
private:
	int numerator; // 分子
	int denominator; // 分母
	int gcd(int a, int b);// 计算最大公约数,用于约分
	void reduce();// 约分分数
public:
	std::string get_str_fra();//得到分数的字符串形式
	float get_frac()const;//得到分数的浮点数形式
	Fraction(int n = 0, int d = 1);//通过传入分子和分母构造Fraction
	Fraction(std::string& s);//通过传入string字符串生成分数
	Fraction operator+(const Fraction& other) const;//分数加法
	Fraction operator-(const Fraction& other) const;//分数减法
	Fraction operator*(const Fraction& other) const;//分数乘法
	Fraction operator/(const Fraction& other) const;//分数除法

	bool operator>(const Fraction& other) const;//重载大于比较
	bool operator<(const Fraction& other) const;//重载小于比较
	bool operator!=(const Fraction& other) const;//重载不等比较
	bool operator==(const Fraction& other) const;//重载等于比较
	friend std::ostream& operator<<(std::ostream& os, const Fraction& f);//重载分数的流提取运算符
	friend std::istream& operator>>(std::istream& is, Fraction& f);//重载分数的流插入运算符

};
  • Question类:
    Question类主要作用是对单个题目进行管理,提供比较两个题目是否相同的接口便于上层类进行查重,对读取的字符流转化为相应数据结构进行计算以及将题目转化为字符流便于写入文件。还有单个题目的随机实现接口。
    Question类大致结构如下:
class Question //管理一个计算题的类
{
private:
	int range;//数值的范围
	int num;//计算数字的个数(两个或三个)
	bool par_flag;//有无括号
	int par_pos;//括号的位置
	std::vector<Fraction> data;//存储每个数据
	std::vector<int> oper;//存储运算符
	std::vector<int> step;//存储运算步骤,用于查重
	Fraction result;//存储结果以Fraction类形式
	std::vector<std::string> que;//存储题目,以string字符串数组的方式
	std::string res;//存储结果,以string的形式
public:
	friend std::ostream& operator<<(std::ostream& os, const Question& q);//重载流插入运算符,实现向文件中打印题目
	Question(int _range, int _num);//以数据范围和个数生成一个题目
	Question(std::vector<std::string>& vs);//从文件中读到的一个题目拆分成的字符串数组构建一个题目
	void get_DataOper(std::vector<std::string>& vs);//第二种构造下用于得到数据和运算符
	int get_oper(std::string& v);//用于将运算符转化为数字记录
	void get_str();//根据题目生成字符串数组que
	bool operator==(const Question& other) const;//重载“==”符号用于比较两个题目是否重复
	void ran_oper();//生成随机运算符,用于第一种构造
	void ran_data();//生成随机数据,用于第二种构造
	int GetPri(int ope);//得到运算符的优先级
	void get_result();//得到本题结果
	void calculate();//生成运算先后步骤,被get_result()调用
	Fraction _calculate(Fraction& tmp1, Fraction& tmp2, int st);//计算两个分数的运算结果,被calculate调用
	Fraction get_fra_res();
	std::string get_str_res();
	std::vector<std::string> infixToPostfix(const std::string& infix)const;
	bool areEquivalent(const std::string& expr1, const std::string& expr2)const;
	int precedence(char op)const;
};
  • Generator类
    Generator类的主要作用是决定随机生成的题目的数量以及对题目进行判重,对从文件中读取到的内容预处理并交给下层类进行处理,最后得到准确率。将生成的题目和得到的准确度写入文件
    Generator类大致结构如下:
class Generator//计算题生成器
{
private:
	int number;//题目数量
	int range;//题目数据的范围
	std::vector<Question> questions;//存档所有题目
	std::unordered_multimap<Fraction, Question, MyHash> record;//记录已生成题目,用于查重
	std::string qFile;//目标题目写入/读取文件
	std::string aFile;//目标答案写入/读取文件
public:
	Generator(int _num, int _range, const char* _qfile = "Exercises.txt", const char* _afile = "Answers.txt");//构造函数用于生成题目
	Generator(const char* _qfile, const char* _afile, const char* _rfile = "Grade.txt");//构造函数二用于检查错误题目数量
	~Generator();//析构函数
	void Create();//创建题目
	bool judge(Question& q);//判断题目是否已有重复
	void Write();//写入目标文件
	void Accuracy(const char* rfile);//处理文件读取的内容生成题目计算结果,调用_accuracy()得到精确度
	void _accuracy(std::vector<Question>& que, std::vector<Fraction>& ans, const char* rfile);//计算得到精确度
};

main函数:

点击查看代码
#include"arith.h"


int main(int argc, char* argv[])
{
	try {
		if (argc != 5)
		{
			std::cout << "输入参数不完整" << std::endl;
			return 1;
		}
		std::vector<std::string> args;
		for (int i = 0; i < argc; ++i)
		{
			args.push_back(std::string(argv[i]));
		}

		if (args[1] == "-n" || args[1] == "-r")
		{
			int num, range;
			if (args[1] == "-n" && args[3] == "-r")
			{
				num = std::stoi(args[2]);
				range = std::stoi(args[4]);

			}
			else if (args[3] == "-n" && args[1] == "-r")
			{
				num = std::stoi(args[4]);
				range = std::stoi(args[2]);
			}
			else
			{
				std::cout << "输入参数不完整" << std::endl;
				return 1;
			}
			Generator gen(num, range);
			std::cout << "生成成功" << std::endl;
		}
		else if (args[1] == "-e" || args[1] == "-a")
		{
			int epos, apos;
			if (args[1] == "-e" && args[3] == "-a")
			{
				epos = 2;
				apos = 4;
			}
			else if (args[3] == "-e" && args[1] == "-a")
			{
				apos = 2;
				epos = 4;
			}
			else
			{
				std::cout << "输入参数不完整" << std::endl;
				return 1;
			}

			Generator gen(args[epos].c_str(), args[apos].c_str());
			std::cout << "判题成功" << std::endl;

		}
		else
		{
			std::cout << "输入参数不完整" << std::endl;
			return 1;
		}

		return 0;
	}
	catch (const std::exception& e)
	{
		std::cerr << "Exception caught:" << e.what() << std::endl;
	}
}
main函数中对命令行参数进行分析,参数不符合条件时打印错误信息,参数符合条件时,对于两种功能(生成题目和判断答案)都进行了实现。

代码流程图如下:

  • 性能分析
    使用Visual studio内置的性能分析工具得到结果如下:


    改进思路:利用生成器,多线程与多进程,异步编程,编译器优化,使用RAII等等方法可以多角度对代码进行优化

  • 测试
    功能测试:
    1.命令行参数不全测试,对于参数缺失的情况进行反馈

    2.生成题目测试



    3.判断题目正确率测试,第一题为设置的错误答案,结果无误



使用Microsoft测试框架进行单元测试测试:

如图,测试均通过。测试代码如下:
对Fraction类进行测试
4.测试Fraction类自动管理分数能力

TEST_METHOD(TestMethod_get_str_fra)
		{
			Fraction f(25, 4);
			Assert::AreEqual(std::string("6'1/4"), f.get_str_fra());
		}

5.测试Fraction类的数值管理正确性

TEST_METHOD(Test_get_frac)
		{
			int num = 6;
			int den = 5;
			Fraction f(num, den);
			float res = (float)num / (float)den;
			Assert::AreEqual(res, f.get_frac());
		}

Question类的测试
6.测试自动生成题目能力

TEST_METHOD(TestMethod_ConstructorQuestion1)
		{
			Question q(10, 3);
			Assert::AreEqual(q.range, 10);
			Assert::AreEqual(q.num, 3);
			Assert::AreEqual((int)q.data.size(), 3);

		}

7.测试加减乘除运算的正确性

TEST_METHOD(TestMethod_ADD)
		{
			std::string s("1. 1/2 + 2/3 =");
			std::istringstream iss(s);
			std::vector<std::string> words;
			std::string word;
			while (iss >> word)
			{
				words.push_back(word);
			}
			Question q(words);
			std::string res("1'1/6");
			Fraction f(7, 6);
			Assert::IsTrue(res == q.res);
			Assert::IsTrue(f == q.result);
		}
TEST_METHOD(TestMethod_SUB)
		{
			std::string s("1. 2/3 - 1/2 =");
			std::istringstream iss(s);
			std::vector<std::string> words;
			std::string word;
			while (iss >> word)
			{
				words.push_back(word);
			}
			Question q(words);
			std::string res("1/6");
			Fraction f(1, 6);
			Assert::IsTrue(res == q.res);
			Assert::IsTrue(f == q.result);
		}
TEST_METHOD(TestMethod_MUL)
		{
			std::string s("1. 1/2 × 2/3 =");
			std::istringstream iss(s);
			std::vector<std::string> words;
			std::string word;
			while (iss >> word)
			{
				words.push_back(word);
			}
			Question q(words);
			std::string res("1/3");
			Fraction f(1, 3);
			Assert::IsTrue(res == q.res);
			Assert::IsTrue(f == q.result);
		}
TEST_METHOD(TestMethod_DIV)
		{
			std::string s("1. 1/2 ÷ 2/3 =");
			std::istringstream iss(s);
			std::vector<std::string> words;
			std::string word;
			while (iss >> word)
			{
				words.push_back(word);
			}
			Question q(words);
			std::string res("3/4");
			Fraction f(3, 4);
			Assert::IsTrue(res == q.res);
			Assert::IsTrue(f == q.result);
		}

项目总结:
本次结对项目提升了合作开发的能力,是一次令人受益匪浅的开发经历

具体各方法的实现如下:

Fraction类内方法:

点击查看代码
// 计算最大公约数,用于约分
int Fraction::gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}

// 约分分数
void Fraction::reduce() {
	int divisor = gcd(numerator, denominator);
	numerator /= divisor;
	denominator /= divisor;
	// 确保分母总是正数
	if (denominator < 0) {
		numerator = -numerator;
		denominator = -denominator;
	}
}

std::string Fraction::get_str_fra()
{
	std::string fra;
	if (numerator > denominator)
	{
		fra += std::to_string(numerator / denominator);
		fra.push_back('\'');
	}
	if (numerator % denominator == 0)
	{
		if (numerator == denominator)
		{
			return std::string("1");
		}
		fra.erase(fra.size() - 1);
		return fra;
	}
	fra += std::to_string(numerator % denominator);
	fra.push_back('/');
	fra += std::to_string(denominator);
	return fra;
}

float Fraction::get_frac()const
{
	return (float)numerator / (float)denominator;
}

// 构造函数
Fraction::Fraction(int n , int d ) : numerator(n), denominator(d) {
	if (d == 0) {
		throw std::invalid_argument("Denominator cannot be zero.");
	}
	reduce();
}
Fraction::Fraction(std::string& s) : numerator(0), denominator(1)
{
	int inte = 0;
	size_t pos1 = s.find('\'');
	size_t pos2 = s.find('/');

	if (pos1 == std::string::npos && pos2 == std::string::npos)
	{
		std::string integer = s.substr(0);
		inte = std::stoi(integer);
		numerator += inte * denominator;
	}
	else if (pos2 != std::string::npos)
	{
		int begin = 0;
		int len = 0;
		if (pos1 != std::string::npos)
		{
			begin = pos1 + 1;
			len = pos2 - pos1;
			std::string integer = s.substr(0, pos1);
			inte = std::stoi(integer);
		}
		else
		{
			len = pos2;
		}
		std::string integer = s.substr(begin, len);
		numerator = std::stoi(integer);

		integer = s.substr(pos2 + 1);
		denominator = std::stoi(integer);
		
		numerator += inte * denominator;
	}

	
}

// 重载加法运算符
Fraction Fraction::operator+(const Fraction& other) const {
	if (numerator == 0)
	{
		return other;
	}
	if (other.numerator == 0)
	{
		return *this;
	}
	return Fraction(numerator * other.denominator + other.numerator * denominator,
		denominator * other.denominator);
}

// 重载减法运算符
Fraction Fraction::operator-(const Fraction& other) const {
	return Fraction(numerator * other.denominator - other.numerator * denominator,
		denominator * other.denominator);
}

// 重载乘法运算符
Fraction Fraction::operator*(const Fraction& other) const {
	if (numerator == 0 || other.numerator == 0)
	{
		return Fraction(0);
	}

	return Fraction(numerator * other.numerator, denominator * other.denominator);
}

// 重载除法运算符
Fraction Fraction::operator/(const Fraction& other) const {
	return Fraction(numerator * other.denominator, denominator * other.numerator);
}

//比较两个分数大小
bool Fraction::operator>(const Fraction& other) const {
	return numerator * other.denominator > denominator * other.numerator;
}

//比较两个分数大小
bool Fraction::operator<(const Fraction& other) const {
	return !(*this > other);
}

//判断相等
bool Fraction::operator==(const Fraction& other) const {
	if (numerator == 0 && other.numerator == 0)
		return true;
	else
	{
		return (numerator == other.numerator) && (denominator == other.denominator);
	}
}
bool Fraction::operator!=(const Fraction& other) const {
	return !(*this == other);
}

// 输出流运算符重载
std::ostream& operator<<(std::ostream& os, const Fraction& f) {
	os << f.numerator << "/" << f.denominator;
	return os;
}

// 输入流运算符重载
std::istream& operator>>(std::istream& is, Fraction& f) {
	is >> f.numerator >> f.denominator;
	f.reduce();
	return is;
}
Question类内方法:
点击查看代码
std::ostream& operator<<(std::ostream& os, const Question& q) {
	for (auto it : q.que)
	{
		os << it << " ";
	}
	return os;
}

Question::Question(int _range, int _num)
	:range(_range), num(_num), par_flag(false)
{
	ran_data();//生成数字
	ran_oper();//生成运算符
	get_result();//得到结果
	get_str();//生成字符串
}
Question::Question(std::vector<std::string>& vs)
{
	if (vs.size() == 5)
	{
		num = 2;
		Fraction d1(vs[1]);
		Fraction d2(vs[3]);
		data.push_back(d1);
		data.push_back(d2);
		oper.push_back(get_oper(vs[2]));
	}
	else
	{
		num = 3;
		get_DataOper(vs);
	}

	get_result();//得到结果
	get_str();//生成字符串

}


void Question::get_DataOper(std::vector<std::string>& vs)
{
	int dp1, dp2, dp3, oper1, oper2;

	if (vs[1] == "(")
	{
		par_flag = true;
		par_pos = 0;
	}
	else if (vs[3] == "(")
	{
		par_flag = true;
		par_pos = 1;
	}
	else
	{
		par_flag = false;
		par_pos = 2;
	}

	if (par_pos == 0)
	{
		dp1 = 2;
		dp2 = 4;
		dp3 = 7;
		oper1 = 3;
		oper2 = 6;
	}
	else if (par_pos == 1)
	{
		dp1 = 1;
		dp2 = 4;
		dp3 = 6;
		oper1 = 2;
		oper2 = 5;
	}
	else{
		dp1 = 1;
		dp2 = 3;
		dp3 = 5;
		oper1 = 2;
		oper2 = 4;
	}

	data.push_back(Fraction(vs[dp1]));
	data.push_back(Fraction(vs[dp2]));
	data.push_back(Fraction(vs[dp3]));
	oper.push_back(get_oper(vs[oper1]));
	oper.push_back(get_oper(vs[oper2]));
}
int Question::get_oper(std::string& v)
{
	if (v == "+")
		return 0;
	if (v == "-")
		return 1;
	if (v == "×")
		return 2;
	if (v == "÷")
		return 3;
}
void Question::get_str()
{
	if (result == Fraction(0))
	{
		res = std::string("0");
	}
	else
		res = result.get_str_fra();

	for (auto e : data)
	{
		if (e == Fraction(0))
			que.push_back(std::string("0"));
		else
			que.push_back(e.get_str_fra());
	}
	auto pos = que.begin() + 1;
	for (auto it : oper)
	{
		switch (it)
		{
		case ADD:que.insert(pos, std::string("+")); break;
		case SUB:que.insert(pos, std::string("-")); break;
		case MUL:que.insert(pos, std::string("×")); break;
		case DIV:que.insert(pos, std::string("÷")); break;
		default:
			break;
		}
		pos = que.begin() + 3;
	}
	if (par_flag)
	{
		int left_par, right_par;
		if (par_pos == 0)
		{
			left_par = 0;
			right_par = 4;
		}
		else
		{
			left_par = 2;
			right_par = 6;
		}
		que.insert(left_par + que.begin(), std::string("("));
		que.insert(right_par + que.begin(), std::string(")"));

	}
	que.emplace(que.end(), std::string("="));
}

//判断相等
bool Question::operator==(const Question& other) const {
	std::string q1, q2;
	for (int i = 1; i < que.size()-1; ++i)
	{
		q1 += que[i];
	};
	for (int i = 1; i < other.que.size() - 1; ++i)
	{
		q2 += other.que[i];
	}
	return areEquivalent(q1, q2);
	
}


std::vector<std::string> Question::infixToPostfix(const std::string& infix) const{
	std::stack<char> operators;
	std::vector<std::string> postfix;
	for (char ch : infix) {
		if (isdigit(ch)) {
			std::string num(1, ch);
			postfix.insert(postfix.end(), num);
		}
		else if (ch == '(') {
			operators.push(ch);
		}
		else if (ch == ')') {
			while (!operators.empty() && operators.top() != '(') {
				postfix.push_back(std::string(1, operators.top()));
				operators.pop();
			}
			operators.pop(); // Remove '(' from the stack
		}
		else {
			while (!operators.empty() && precedence(operators.top()) >= precedence(ch)) {
				postfix.push_back(std::string(1, operators.top()));
				operators.pop();
			}
			operators.push(ch);
		}
	}
	while (!operators.empty()) {
		postfix.push_back(std::string(1, operators.top()));
		operators.pop();
	}
	return postfix;
}

// 比较两个表达式是否等价
bool Question::areEquivalent(const std::string& expr1, const std::string& expr2) const{
	auto postfix1 = infixToPostfix(expr1);
	auto postfix2 = infixToPostfix(expr2);
	return postfix1 == postfix2;
}

// 定义运算符的优先级
int Question::precedence(char op) const{
	if (op == '+' || op == '-') return 1;
	if (op == '*' || op == '/') return 2;
	return 0;
}

void Question::ran_oper()
{
	std::mt19937 rng(std::random_device{}());
	std::uniform_int_distribution<int> dist(0, range);

	if (num == 3 && dist(rng) % 2 == 0)
	{
		par_flag = true;
		par_pos = dist(rng) % 2;
	}
	int _num = num;
	while (--_num != 0)
	{
		int choice = dist(rng) % 4;
		oper.push_back(choice);
	}
}

void Question::ran_data()
{
	std::mt19937 rng(std::random_device{}());
	std::uniform_int_distribution<int> dist(0, range);
	std::uniform_int_distribution<int> dist1(1, range);

	int _num = num;
	while (_num-- != 0)//随机出数字
	{

		int numerator = dist(rng);
		int denominator = dist1(rng);
		Fraction f(numerator, denominator);
		data.push_back(f);

	}
}

int Question::GetPri(int ope)
{
	if (ope == ADD || ope == SUB)
		return 1;
	else
		return 2;
}

void Question::get_result()
{
	if (num == 2)
	{
		step.push_back(0);
	}
	else
	{
		int prev_step, next_step;

		if (par_flag)
		{
			prev_step = par_pos;
		}
		else
		{
			if (GetPri(oper[0]) < GetPri(oper[1]))
			{
				prev_step = 1;
			}
			else
			{
				prev_step = 0;
			}
		}
		next_step = (prev_step + 1) % 2;
		step.push_back(prev_step);
		step.push_back(next_step);
	}
	calculate();
}

void Question::calculate()
{
	if (num == 2)
	{
		result = _calculate(data[0], data[1], 0);
	}
	else if (num == 3) {
		std::stack<Fraction> inter;
		int i = 0;
		inter.push(data[i++]);
		inter.push(data[i++]);

		if (step[0] == 1)
		{
			inter.push(data[i++]);
		}
		Fraction tmp2 = inter.top();
		inter.pop();
		Fraction tmp1 = inter.top();
		inter.pop();
		tmp1 = _calculate(tmp1, tmp2, 0);
		inter.push(tmp1);
		if (i < num)
		{
			inter.push(data[i++]);
		}

		tmp2 = inter.top();
		inter.pop();
		tmp1 = inter.top();
		inter.pop();
		result = _calculate(tmp1, tmp2, 1);
	}

}
Fraction Question::_calculate(Fraction& tmp1, Fraction& tmp2, int st)
{
	if (oper[step[st]] == SUB)
	{
		if (tmp2 > tmp1)
		{
			oper[step[st]] = ADD;
		}
	}
	if (oper[step[st]] == DIV)
	{
		if (tmp2 == Fraction(0))
		{
			oper[step[st]] = MUL;
		}
	}
	switch (oper[step[st]])
	{
	case ADD:return tmp1 + tmp2;
	case SUB:return tmp1 - tmp2;
	case MUL:return tmp1 * tmp2;
	case DIV:return tmp1 / tmp2;
	default:
		break;
	}
}
Fraction Question::get_fra_res()
{
	return result;
}
std::string Question::get_str_res()
{
	return res;
}


float MyHash::operator()(const Fraction& res) const {
float result = res.get_frac();
return result;
}
Generator类内方法:
点击查看代码
Generator::Generator(int _num, int _range, const char* _qfile, const char* _afile)
	:number(_num), range(_range), qFile(_qfile), aFile(_afile)
{
	Create();
}
Generator::Generator(const char* _qfile, const char* _afile, const char* _rfile)
	:qFile(_qfile), aFile(_afile)
{
	Accuracy(_rfile);
}
Generator::~Generator()
{}


//生成题目和答案
void Generator::Create()
{
	int num = number;
	while (num-- != 0)
	{
		std::mt19937 rng(std::random_device{}());
		std::uniform_int_distribution<int> dist(2, 3);
		int count = dist(rng);
		Question q(range, count);
		if (judge(q))
		{
			num++;
			continue;
		}
		else
		{
			questions.push_back(q);
			record.insert({ q.get_fra_res(), q});
		}
	}
	Write();
}

//判断有无相同的题目
bool Generator::judge(Question& q)
{
	if (record.count(q.get_fra_res()) != 0)
	{
		auto range = record.equal_range(q.get_fra_res());
		for (auto it = range.first; it != range.second; it++)
		{
			if (it->second == q)
			{
				return true;
			}
		}
	}

	return false;

}

//将题目和答案写入文件
void Generator::Write()
{
	std::ofstream QueFile;
	QueFile.open(qFile);
	for (int i = 0; i < questions.size(); i++)
	{
		QueFile << std::to_string(i + 1) << ".   " << questions[i] << std::endl;

	}
	std::ofstream AnsFile;
	AnsFile.open(aFile);
	for (int i = 0; i < questions.size(); i++)
	{
		AnsFile << std::to_string(i + 1) << ".   " << questions[i].get_str_res() << std::endl;
	}
}
//根据题目和答案判断正确率
void Generator::Accuracy(const char* rfile)
{

	std::ifstream QueFile(qFile);
	std::ifstream ResFile(aFile);
	std::string line;
	std::vector<Fraction> answers;
	while (getline(QueFile, line))
	{
		std::istringstream iss(line);
		std::vector<std::string> words;
		std::string word;
		while (iss >> word)
		{
			words.push_back(word);
		}
		Question q(words);
		questions.push_back(q);
	}
	while (getline(ResFile, line))
	{
		std::istringstream iss(line);
		std::vector<std::string>words;
		std::string word;
		while (iss >> word)
		{
			words.push_back(word);
		}
		Fraction ans(words[1]);
		answers.push_back(ans);
	}
	return _accuracy(questions, answers, rfile);

}
void Generator::_accuracy(std::vector<Question>& que, std::vector<Fraction>& ans,const char* rfile)
{
	int right = 0;
	int wrong = 0;
	std::string rs("(");
	std::string ws("(");
	for (int i = 0; i < que.size(); i++)
	{
		std::stringstream ss;
		if (que[i].get_fra_res() != ans[i])
		{
			wrong++;
			ss << i + 1;
			ws += ss.str();
			ws += ",";
		}
		else
		{
			right++;
			ss << i + 1;
			rs += ss.str();
			rs += ",";
		}
	}
	if (ws.size() != 1)
		ws.erase(ws.end() - 1);
	if (rs.size() != 1)
		rs.erase(rs.end() - 1);
	ws.append(")");
	rs.append(")");
	std::ofstream OutFile;
	OutFile.open(rfile);
	OutFile << "Correct:" << right << " " << rs << std::endl;
	OutFile << " wrong :" << wrong << " " << ws << std::endl;

};

标签:std,结对,const,string,项目,int,四则运算,Fraction,return
From: https://www.cnblogs.com/lnsep/p/18431294

相关文章

  • 如何正确的在项目中接入微信JS-SDK
    微信JS-SDK的功能如果你点进来,那么我相信你应该知道微信的JS-SDK可以用来做什么了。微信的官方文档描述如下。微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的......
  • 如何正确的在项目中接入微信JS-SDK
    微信JS-SDK的功能如果你点进来,那么我相信你应该知道微信的JS-SDK可以用来做什么了。微信的官方文档描述如下。微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的......
  • 面试官:项目中如何实现布隆过滤器?
    谈起“布隆过滤器”相信大家都不陌生,它也算日常面试中的常见面试题了。例如,当面试官在问到Redis模块的相关问题时,可能会问到缓存穿透(Redis四大经典问题之一),而缓存穿透的经典解决方案之一,则是“布隆过滤器”。但是,对于布隆过滤器是什么?以及布隆过滤器的实现原理?相信大部分同学......
  • CClink IEF Basic设备数据 转 profinet IO项目案例
    目录1 案例说明 12 VFBOX网关工作原理 13 准备工作 24 网关采集CCLINKIEFBASIC数据 25 用PROFINETIO协议转发数据 56 案例总结 81 案例说明设置vfbox网关采集CClinkIEFBasic设备数据把采集的数据转成profinetIO协议转发给其他系统。2 VFBOX网关工作原理VFBOX网......
  • 掌握项目代码无难度,CodeGeeX推出代码库问答与幽灵注释双升级
    CodeGeeX在VSCode中最新的v2.17.0版本,推出两项功能的重要升级。workspace代码库问答和GhostComment幽灵注释,全面助力开发者快速掌握项目全局。代码库问答(@workspace),可以帮助开发者快速获取与整个代码仓库相关的问题答案。无论是对代码结构、函数用途、类关系,还是复杂的代码逻辑和......
  • 大模型项目部署时Gradio Web页面打不开或者打开用不了及pydantic.errors.PydanticSche
    问题描述 在复现大模型demo时连接器和模型加载都没问题,但是gradio界面打不开或者打开后用不了原因分析:感觉应该是gradio的版本问题导致该文件缺少相关文件解决方案:可以首先按照上面要求下载文件https://cdn-media.huggingface.co/frpc-gradio-0.2/frpc_linux_a......
  • 如何恢复被删除的 GitLab 项目?
    GitLab是一个全球知名的一体化DevOps平台,很多人都通过私有化部署GitLab来进行源代码托管。极狐GitLab是GitLab在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。学习极狐GitLab的相关资料:极狐GitLab官网极狐GitLab官网文档极狐GitLab论坛极狐G......
  • Roketmq项目本地安装(connect to [127.0.0.1:9876] failed)
        最近因为公司要求,在网上找了个项目想二次开发用,就在我删除一系列无用代码后,虽然做好了心里准备一定会报错(还是有些期待它不报错的),果然报错了,除了数据库连接以及本地redis没启动的问题之类的,最主要的是这个:懂的都懂,一看就是配置的roketmq有问题,一开始我以为是配置出......
  • C++开发项目
    1.项目系统需求文章目录1.项目系统需求功能如下:2.创建项目:3.创建管理类3.1创建文件3.2头文件实现3.3源文件实现4.菜单功能4.1添加成员函数4.2菜单功能实现4.3测试菜单功能5.退出功能5.1提供功能接口5.2实现退出功能5.3测试功能运行效果图:6.创建职工类6.1创建职工抽象类6.2创建普......
  • 被误删除的 GitLab 群组和项目该如何恢复?
    本文分享如何使用极狐GitLab的项目延迟删除功能来避免仓库被用户误操作。该功能设置了删除延时时间,在延时期间内,用户还可以对项目进行恢复。极狐GitLab为GitLab的中文发行版,中文版本对中国用户更友好。可以一键私有化部署,也可以直接使用SaaS。详细安装指南可以查看官网https:......