简易机器翻译器

背景:在一些比较秘密的场景中,为了传输一些重要的数值串(例如美国新冠病毒实际死亡人数),相关人员往往将这些数据保存为字符串、数值以及各种符号混用的形式。在实际需要这些数据时,就通过提前定义好的方法将它们翻译回来。

相应的子程序:

[1] 计算n!

[2] 求最小公倍数和最大公约数

[3] 输入某雇员每周工作时间(以小时计)和每小时工资数,计算并输出其工资。(如果时间小于0或大于一周的总时间直接输出0)。若雇员每周工作小时超过60小时,则超过60小时的部分按原工资3倍的加班工资来计算,雇员每周工作小时超过40小时而不超过60小时的工资按原工资1.5倍的加班工资计算。

[4] 求组合数

[5] 已知公元1年1月1日是星期一,计算给定的日期是星期几

[6] 四则运算

明确需要覆盖的点:

[1] 使用子程序

[2] 面向对象编程

[3] 考虑异常

[4] 程序中全部输出都采用格式化输出

用C++或Python实现以下内容:

1从特定文本文件中读取一个特定格式字典(训练输入、循环、文件操作),包括①从数字到数值的对应,②从字母到数值的对应,③括号和计算符号不作转换(训练泛型)。

2再从一个文本文件中读取原始符号串,并实现将原始符号串根据字典进行必要的转换。注意,转换后的符号串需要用链表存储。(训练循环、指针、链表操作)

3针对转换后的符号串,按下列要求完成相应的计算,并用两侧各附有一个空格的计算结果替换原来的符号串。(训练参数子程序调用)

①对(a)形式,要求计算阶乘,并替换(计算阶乘,训练迭代和递归)

②对[a, b]形式的要替换为ab的最小公倍数,对{a, b}形式的要替换为ab的最大公约数(计算最小公倍数和最大公约数,训练变量交换)

③对<a, b>形式,要求计算员工周工资,其中a是工作小时数,b是每小时工资数,并替换(计算员工周工资,训练分支)

④对(a, b)形式,要求解从a个中挑选b个的组合数,并替换(计算组合数,训练迭代和递归)

⑤对(a,b,c)形式的要求解a年bc日是周几,并用这个数值替换(计算星期数,训练分支、逻辑运算)

⑥四则运算,例如将读入的符号串(1+3+5)替换为9,注意可能出现嵌套的括号,例如(3/(1 +2))(训练删除链表以及简单的指针操作、递归、形参调用)

4再针对处理后的、由空格分隔的数据进行排序(训练排序处理)

5最后将排好序的数据,以格式化的形式存入文件。(训练循环、文件操作,格式化输出)

其中字典如下:

1  2

a  3

b  5

4  8

c  9

原始输入文本文件内容:

3 (5,b) a (4+6/(a+3)+1) 11 {44,16} 19 (10) <b, 100> 99 (c,a,2) 100 1000 [b,10]

替换后的内容:

3 (5,5) 3 (8+6/(3+3)+2) 11 {44,16} 19 (10) <5, 100> 99 (9,3,2) 100 1000 [5,10]

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

int Cmultiple(int n1, int n2)  //最小公倍数
{
	int max = 0;
	if (n1 != 0 && n2 != 0)
	{
		max = (n1 > n2) ? n1 : n2;
		do
		{
			if (max % n1 == 0 && max % n2 == 0)
			{
				break;
			}
			else
				max++;
		} while (1);
	}
	return max;
}
int Cdivisor(int n1, int n2)  //最大公约数
{
	int min = 0;
	if (n1 != 0 && n2 != 0)
	{
		min = (n1 < n2) ? n1 : n2;
		do
		{
			if (n1 % min == 0 && n2 % min == 0)
			{
				break;
			}
			else
				min--;
		} while (1);
	}
	return min;
}
int Date(int year, int month, int day)
{
	int week;
	long totalday;
	int monthday[12] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
	int monthdayLeap[12] = { 0,31,60,91,121,152,182,213,244,274,305,335 };
	int weekname[7] = { 1,2,3,4,5,6,7 };                  //星期几
	totalday = (year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;
	if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))
	{
		totalday += monthdayLeap[month - 1];
	}
	else
	{
		totalday += monthday[month - 1];
	}
	totalday += day;
	week = (totalday - 1) % 7;
	return weekname[week];
}
int Combination(int n, int m)//组合数
{
	long sum = 1;
	for (int i = m + 1; i <= n; i++) sum *= i;
	for (int i = 1; i <= n - m; i++) sum /= i;
	return sum;
}
int Salary(int hour, double hoursalary)
{
	double salary = 0;
	if (hour < 0 || hour>168)
	{
		cout << "0" << endl;
	}
	else if (hour > 40 && hour < 60)
	{
		salary = 40 * hoursalary + (hour - 40) * hoursalary * 1.5;
	}
	else if (hour > 60)
	{
		salary = 40 * hoursalary + (hour - 40) * hoursalary * 3;
	}
	else
	{
		salary = hour * hoursalary;
	}
	return salary;
}
long Factorial(int a)
{
	long sum = 1;
	for (int i = 1;i < a + 1;i++)
	{
		sum *= i;
	}
	return sum;
}

char Dic(char& c)//转换
{
	switch (c)
	{
	case '1':c = '2';break;
	case 'a':c = '3';break;
	case 'b':c = '5';break;
	case '4':c = '8';break;
	case 'c':c = '9';break;
	default:break;
	}
	return c;
}

void Read()
{
	ifstream ifs;
	char ch;
	int size = 0;
	string str;
	list<int>L;

	int i = 0;
	ifs.open("input.txt", ios::in);
	while (ifs.get(ch))
	{
		if (ch == '<')
		{
			str += ch;
			while (ch != '>')
			{
				ifs.get(ch);
				if (ch == ' ') continue;
				str += ch;
			}
		}
		else
			str += ch;
		i++;
	}
	ifs.close();

	int len = str.length();
	string newstr;
	for (int i = 0;i < len;i++)
	{
		if ('9' >= str[i] && str[i] >= '0')
		{
			while ('9' >= str[i] && str[i] >= '0')
			{
				newstr += str[i];
				i++;
			}
			newstr += str[i];
		}
		else
		{
			newstr += Dic(str[i]);
		}
	}

	ofstream ofs;//写入新文件
	ofs.open("temp.txt", ios::out);
	ofs << newstr << endl;
	ofs.close();

	ifstream ifs1;//读新文件
	ifs1.open("temp.txt", ios::in);

	char ch1;
	while (ifs1.get(ch1))
	{
		if ('9' >= ch1 && ch1 >= '0')
		{
			int a = 0, b = 0, c = 0;
			while (ch1 != ' ')
			{
				if ('9' >= ch1 && ch1 >= '0')
				{
					a = ch1 - '0';
					b *= 10;
					b += a;
				}
				else
				{
					ifs1.get(ch1);continue;
				}
				ifs1.get(ch1);
			}
			L.push_back(b);
		}
		else if (ch1 == '{')
		{
			int a = 0, b = 0, c = 0;
			while (ch1 != '}')
			{

				if ('9' >= ch1 && ch1 >= '0')
				{
					a = ch1 - '0';
					b *= 10;
					b += a;
				}
				else
				{
					c = b; b = 0;	ifs1.get(ch1);continue;   //c是第一个数据
				}
				ifs1.get(ch1);
			}
			L.push_back(Cdivisor(c, b));
		}
		else if (ch1 == '<')
		{
			int a = 0, b = 0, c = 0;
			while (ch1 != '>')
			{

				if ('9' >= ch1 && ch1 >= '0')
				{
					a = ch1 - '0';
					b *= 10;
					b += a;
				}
				else
				{
					c = b; b = 0;ifs1.get(ch1);continue;   //c是第一个数据
				}
				ifs1.get(ch1);
			}
			L.push_back(Salary(c, b));
		}
		else if (ch1 == '[')
		{
			int a = 0, b = 0, c = 0;
			while (ch1 != ']')
			{
				if ('9' >= ch1 && ch1 >= '0')
				{
					a = ch1 - '0';
					b *= 10;
					b += a;
				}
				else
				{
					c = b; b = 0;ifs1.get(ch1);continue;   //c是第一个数据
				}
				ifs1.get(ch1);
			}
			L.push_back(Cmultiple(c, b));
		}
		else if (ch1 == '(')
		{
			int n = 0, m = 0, times = 0;
			int a = 0, b = 0, c = 0, d = 0, f = 0;
			while (ch1 != ' ')
			{
				times++;                   //记录读了多少次——读了多少字节
				ifs1.get(ch1);
				if (ch1 == ',') n++;
				else if (ch1 == '(') m++;
			}
			ifs1.seekg(-times, ios::cur);   //移动文件读指针回原先位置'('。
			ifs1.get(ch1);                      //读取e为值
			if (m != 0)
			{
				while (ch1 != ' ')
				{
					ifs1.get(ch1);
					continue;
				}
			}
			else if (n == 0 && m == 0)
			{
				while (ch1 != ')')
				{
					if ('9' >= ch1 && ch1 >= '0')
					{
						a = ch1 - '0';
						b *= 10;
						b += a;
					}
					else
					{
						c = b;b = 0;ifs1.get(ch1);continue;
					}
					ifs1.get(ch1);
				}
				L.push_back(Factorial(b));
			}
			else if (n == 1 && m == 0)
			{
				while (ch1 != ')')
				{
					if ('9' >= ch1 && ch1 >= '0')
					{
						a = ch1 - '0';
						b *= 10;
						b += a;
					}
					else
					{
						c = b;b = 0;ifs1.get(ch1);continue;
					}
					ifs1.get(ch1);
				}
				L.push_back(Combination(c, b));
			}
			else if (n == 2 && m == 0)
			{
				int num = 0;
				while (ch1 != ')')
				{
					if ('9' >= ch1 && ch1 >= '0')
					{
						a = ch1 - '0';
						b *= 10;
						b += a;
					}
					else
					{
						num++;
						if (num == 1)
						{
							c = b;b = 0; ifs1.get(ch1); continue;  //第一个数
						}
						else
						{
							d = b;b = 0; ifs1.get(ch1);  continue;  //第二个数,b是第三个
						}
					}
					ifs1.get(ch1);
				}
				L.push_back(Date(c, d, b));
			}
		}
	}
	ifs1.close();
	L.sort();

	ofstream ofs1;
	ofs1.open("Converted_data.txt", ios::out);
	list<int>::iterator p;
	p = L.begin();
	while (p != L.end())
	{
		ofs1 << *p << " ";
		p++;
	}
	ofs1.close();
}

int main()
{
	Read();
	return 0;
}

因为水平不够,忽略掉了四则运算等。算是勉强实现。。。

上一篇:移植libevent库到目标SDK


下一篇:问题 M: 中缀表达式转后缀表达式