数字字符串的四则运算(加减乘除)

      由于平时在做题时会用到数字字符串模拟大数加减乘除,但是网上的大部分代码都只是针对大整数而言,无法对小数和负数进行运算。所以特地写了一个类,包括了大数相加 、大数相减、大数相乘、大整数相除。

      大数相加 (可以是整数、小数、负数)

      大数相减 (可以是整数、小数、负数)

      大数相乘 (可以是整数、小数、负数)

      大整数相除 (只能是正整数,返回商和余数)

      这些方法都是模拟手算过程实现,在本地测试都没什么问题,如果大家在使用过程中发现问题,希望能反馈一下,让我进一步完善。

      

//大数四则运算
//大数加法(正负整数,正负小数都行)
//大数减法(正负整数,正负小数都行)
//大数乘法(正负整数,正负小数都行)
//大整数除法(只能正整数相除,给出商和余数)
//有两个用字符串表示的非常大的大整数, 算出他们的四则运算,也是用字符串表示。不能用系统自带的大整数类型。
#include
#include
using namespace std;
struct Division_result {
	string quotient;
	string remainder;
};
class Four_Arithmetic_Operations {
public:
	string Sum_of_String(string s1, string s2) {
		if (Is_InValid_Strings("Sum_of_String", s1, s2)) return "";
		bool S1Sign = true, S2Sign = true; if (s1[0] == '-') S1Sign = false, s1.erase(s1.begin()); if (s2[0] == '-') S2Sign = false, s2.erase(s2.begin());//判断是否有负号
		if (!S1Sign && S2Sign) return Substration_of_String(s2, s1);
		else if (S1Sign && !S2Sign) return Substration_of_String(s1, s2);
		else if (!S1Sign && !S2Sign) return "-" + Sum_of_String(s1, s2);
		else {
			int s1TailLength = 0, s2TailLength = 0;
			for (int i = 0; i < s1.size(); i++) if (s1[i] == '.') { s1TailLength = (int)s1.size() - 1 - i; s1.erase(s1.begin() + i); break; }//去除s1小数点,记录小数位数
			for (int i = 0; i < s2.size(); i++) if (s2[i] == '.') { s2TailLength = (int)s2.size() - 1 - i; s2.erase(s2.begin() + i); break; }//去除s2小数点,记录小数位数
			int TailLength = (s1TailLength > s2TailLength) ? s1TailLength : s2TailLength;
			if (TailLength != s1TailLength) s1 += string(TailLength - s1TailLength, '0');//小数部分对齐补0
			if (TailLength != s2TailLength) s2 += string(TailLength - s2TailLength, '0');//小数部分对齐补0
			int Total_Length = s1.size() > s2.size() ? (int)s1.size() : (int)s2.size();
			if (Total_Length != s1.size()) s1 = string(Total_Length - s1.size(), '0') + s1;//整数部分对齐补0
			if (Total_Length != s2.size()) s2 = string(Total_Length - s2.size(), '0') + s2;//整数部分对齐补0
			reverse(s1.begin(), s1.end());
			reverse(s2.begin(), s2.end());
			string result(Total_Length + 1, '0');
			for (int i = 0; i < Total_Length; i++)
			{
				int k = s1[i] + s2[i] + result[i] - 3 * '0';
				string h = to_string(k % 10); result[i] = h[0];
				h = to_string(k / 10); result[i + 1] = h[0];
			}
			reverse(result.begin(), result.end());
			if (TailLength != 0) {
				result.insert(result.size() - TailLength, ".");//如果有小数部分插入小数点
				while (result.back() == '0') result.erase(result.end() - 1);//去除小数部分末尾的0
				if (result.back() == '.') result.erase(result.end() - 1);
			}
			if (result[0] == '0') result.erase(result.begin());
			return result;
		}
	}
	string Substration_of_String(string s1, string s2) {
		if (Is_InValid_Strings("Substration_of_String", s1, s2)) return "";
		bool S1Sign = true, S2Sign = true; if (s1[0] == '-') S1Sign = false, s1.erase(s1.begin()); if (s2[0] == '-') S2Sign = false, s2.erase(s2.begin());//判断是否有负号
		if (!S1Sign && S2Sign) return "-" + Sum_of_String(s1, s2);
		else if (S1Sign && !S2Sign) return Sum_of_String(s1, s2);
		else if (!S1Sign && !S2Sign) return Substration_of_String(s2, s1);
		else {
			int s1TailLength = 0, s2TailLength = 0;
			for (int i = 0; i < s1.size(); i++) if (s1[i] == '.') { s1TailLength = (int)s1.size() - 1 - i; s1.erase(s1.begin() + i); break; }//去除s1小数点,记录小数位数
			for (int i = 0; i < s2.size(); i++) if (s2[i] == '.') { s2TailLength = (int)s2.size() - 1 - i; s2.erase(s2.begin() + i); break; }//去除s2小数点,记录小数位数
			int TailLength = (s1TailLength > s2TailLength) ? s1TailLength : s2TailLength;
			if (TailLength != s1TailLength) s1 += string(TailLength - s1TailLength, '0');//小数部分对齐补0
			if (TailLength != s2TailLength) s2 += string(TailLength - s2TailLength, '0');//小数部分对齐补0
			int Total_Length = s1.size() > s2.size() ? (int)s1.size() : (int)s2.size();
			if (Total_Length != s1.size()) s1 = string(Total_Length - s1.size(), '0') + s1;//整数部分对齐补0
			if (Total_Length != s2.size()) s2 = string(Total_Length - s2.size(), '0') + s2;//整数部分对齐补0
			bool Sign = true;//正负符号标记
			if (!(Is_S1_BiggerThan_S2(s1, s2) || s1 == s2)) {
				s1.swap(s2);//将s1作为大的数存放,s2作为小的数
				Sign = false;
			}
			reverse(s1.begin(), s1.end());
			reverse(s2.begin(), s2.end());
			int length = s1.size() > s2.size() ? (int)s1.size() : (int)s2.size();//记录谁最长
			if (length == s1.size()) s2 += string(length - s2.size(), '0');//对齐补0
			if (length == s2.size()) s1 += string(length - s1.size(), '0');//对齐补0
			int borrow = 0; string result(length, '0');//存放结果
			for (int i = 0; i < length; i++) {
				if (s1[i] >= s2[i] + borrow) { result[i] = '0' + s1[i] - s2[i] - borrow; borrow = 0; }
				else { result[i] = '0' + 10 + s1[i] - s2[i] - borrow; borrow = 1; }
			}
			reverse(result.begin(), result.end());
			while (result.size() > 1 && result[0] == '0')  result.erase(result.begin());
			if (TailLength != 0) {
				result.insert(result.size() - TailLength, ".");//如果有小数部分插入小数点
				while (result.back() == '0') result.erase(result.end() - 1);//去除小数部分末尾的0
				if (result.back() == '.') result.erase(result.end() - 1);
			}
			if (!Sign) result = "-" + result;
			return result;
		}
	}
	string Multiply_of_String(string s1, string s2) {
		if (Is_InValid_Strings("Multiply_of_String", s1, s2)) return "";
		int s1TailLength = 0, s2TailLength = 0; int TailLength = 0;
		bool S1Sign = true, S2Sign = true; if (s1[0] == '-') S1Sign = false, s1.erase(s1.begin()); if (s2[0] == '-') S2Sign = false, s2.erase(s2.begin());//判断是否有负号
		for (int i = 0; i < s1.size(); i++) if (s1[i] == '.') { s1TailLength = (int)s1.size() - 1 - i; s1.erase(s1.begin() + i); break; }//去除是s1小数点,记录小数位数
		for (int i = 0; i < s2.size(); i++) if (s2[i] == '.') { s2TailLength = (int)s2.size() - 1 - i; s2.erase(s2.begin() + i); break; }//去除s2小数点,记录小数位数
		TailLength = s1TailLength + s2TailLength;
		string C(s1.size() + s2.size(), '0'); int carry_num;//进位数
		for (int i = (int)s2.size() - 1; i >= 0; --i) {
			carry_num = 0;
			for (int j = (int)s1.size() - 1; j >= 0; --j) {
				int T = (s2[i] - '0')*(s1[j] - '0');
				T += (C[j + i + 1] - '0') + carry_num;
				carry_num = T / 10; C[j + i + 1] = '0' + T % 10;
			}
			if (carry_num != 0) C[i] = '0' + carry_num;
		}
		if (TailLength != 0) {
			C.insert(C.size() - TailLength, ".");//如果有小数部分插入小数点
			while (C.back() == '0') C.erase(C.end() - 1);//去除小数部分末尾的0
		}
		if (C.back() == '.') C.erase(C.end() - 1);
		while (!C.empty() && C.front() == '0') C.erase(C.begin());
		if (C.empty()) C += '0';
		else if (S1Sign^S2Sign) C = "-" + C;//两者符号相异为需添加负号
		return C;
	}
	Division_result Division_of_string(string dividend, string divisor) {
		if (Is_InValid_Division_Strings("Division_of_string", dividend, divisor)) return Division_result();
			string remainder = ""; string quotient;
		for (int i = 0; dividend[i]; i++)
		{
			remainder += dividend[i];
			if (Is_S1_BiggerThan_S2(remainder, divisor) || remainder == divisor) {
				for (string factor = "9"; factor >= "1"; factor[0]--) {
					string Diviior_Fac = Multiply_of_String(divisor, factor);
					if (Is_S1_BiggerThan_S2(remainder, Diviior_Fac) || remainder == Diviior_Fac) {
						quotient += factor;
						remainder = Substration_of_String(remainder, Diviior_Fac);
						break;
					}
				}
			}
		}
		while (remainder.size() > 1 && remainder[0] == '0')remainder.erase(remainder.begin());
		if (quotient.empty()) quotient = '0';
		return Division_result() = { quotient, remainder };
	}
private:
	bool Is_S1_BiggerThan_S2(string s1, string s2) {
		if (s1.size() < s2.size()) return false;
		else if (s1.size() > s2.size()) return true;
		else {
			for (int i = 0; i < s1.size(); i++) {
				if (s1[i] > s2[i]) return true;
				else if (s1[i] < s2[i]) return false;
			}
		}
		return false;
	}
	bool Is_Valid_StringNum(string Str) {
		int state = 1; int i = 0;
		while (i < Str.size()) {
			switch (state)
			{
			case 1:
				if (Str[i] == '-' || '0' <= Str[i] && Str[i] <= '9')  state = 2;
				else return false;
				break;
			case 2:
				if (Str[i] == '.') state = 3;
				else if (Str[i]<'0' || Str[i] > '9') return false;
				break;
			case 3:
				if (Str[i]<'0' || Str[i] > '9') return false;
				break;
			default:
				break;
			}
			i++;
		}
		return true;
	}
	bool Is_InValid_Strings(string fun_name, string s1, string s2)
	{
		if (!Is_Valid_StringNum(s1) || !Is_Valid_StringNum(s2)) {
			cout << fun_name << "(" << s1 << "," << s2 << ")中";
			if (!Is_Valid_StringNum(s1)) cout << ",s1输入了无效数字字符串";
			if (!Is_Valid_StringNum(s2)) cout << ",s2输入了无效数字字符串";
			cout << endl;
			return true;
		}
		return false;
	}
	bool Is_InValid_Division_Strings(string fun_name, string s1, string s2)
	{
		bool valids1 = true, valids2 = true;
		for (int i = 0; i < s1.size(); i++) if (s1[i]<'0' || s1[i]>'9') valids1 = false;
		for (int i = 0; i < s2.size(); i++) if (s2[i]<'0' || s2[i]>'9') valids2 = false;
		if (!valids1 || !valids2) {
			cout << fun_name << "(" << s1 << "," << s2 << ")中";
			if (!valids1) cout << ",s1输入了无效数字字符串";
			if (!valids2) cout << ",s2输入了无效数字字符串";
			cout << endl;
			return true;
		}
		return false;
	}
};
int main()
{
	string s1 = "1219326320073159566072245112635269"; string s2 = "98765432123456789"; string quotient_True_ans = "12345678987654321"; string remainder_True_ans = "0";//两大整数相除,输出12345678987654321
	//string s1 = "122"; string s2 = "11";  string quotient_True_ans = "11"; string remainder_True_ans = "1";//两大整数相除
	//string s1 = "11"; string s2 = "121"; string quotient_True_ans = "0"; string remainder_True_ans = "11";//两大整数相除
	Four_Arithmetic_Operations ari;
	Division_result result=ari.Division_of_string(s1, s2);
	cout << s1 << "/" << s2 << "=商:" << result.quotient << " 余数:" << result.remainder << endl;
	cout << "输出:" << ((result.quotient == quotient_True_ans && result.remainder == remainder_True_ans) ? "正确" : "错误") << endl;
	cout << ari.Substration_of_String("-25.500", "-00.1562") << endl;
	cout << ari.Sum_of_String("-25", "00.15620") << endl;
	cout << ari.Multiply_of_String("-25.500", "-00.1562") << endl;
	cout << ari.Multiply_of_String("25.5", "-0") << endl;
	return 0;
}

 

你可能感兴趣的:(数字字符串的四则运算(加减乘除))