1. 程式人生 > >大整數類加減乘除的簡單實現——C++

大整數類加減乘除的簡單實現——C++

程式設計題#4:大整數的加減乘除

總時間限制: 
1000ms 
記憶體限制: 
65536kB
描述

給出兩個正整數以及四則運算操作符(+ - * /),求運算結果。

輸入
第一行:正整數a,長度不超過100
第二行:四則運算子o,o是“+”,“-”,“*”,“/”中的某一個
第三行:正整數b,長度不超過100

保證輸入不含多餘的空格或其它字元
輸出
一行:表示式“a o b”的值。

補充說明:
1. 減法結果有可能為負數
2. 除法結果向下取整
3. 輸出符合日常書寫習慣,不能有多餘的0、空格或其它字元
樣例輸入
9876543210
+
9876543210
樣例輸出
19753086420

這次的大整數加減乘除的基本思想是用字串構造一個類,記錄十進位制的數字。

用豎式計算實現加和減。接下來要注意,對於乘法,因為只有+/- 可以呼叫,若要求求得a*b,僅僅用a次迴圈的+=b是極慢的。所以,要用遞迴來實現,若用res記錄結果,第一次res=b,

第n次可使res=res+res;這樣res的值以二次方增長,大大節省時間。除法也是如此。

</pre><pre name="code" class="cpp"><pre name="code" class="cpp">#include <iostream>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <sstream>
#include <stdio.h>
using namespace std;
void itoa1(int a, char* b, int c);
long long atoi1(const char s[])                            //atoi
{
	long long temp = 0;
	const char *ptr = s;
	if (*s == '-' || *s == '+')
	{
		s++;
	}
	while (*s != 0)
	{
		if ((*s < '0') || (*s > '9'))
		{
			break;
		}
		temp = temp * 10LL + (long long)(*s - '0');
		s++;
	}
	if (*ptr == '-') {
		temp = -temp;
	}

	return temp;
}
class longint {
	string a;

public:
	longint(string);
	longint();
	longint(const char*);
	string operator=(const char*);
	string operator+(longint);
	string operator-(longint);
	string operator*(longint);
	string operator/(longint);
};
void itoa1(int n, char *str, int c)                         //itoa 
{
	char buf[10] = "";
	int i = 0;
	int len = 0;
	int temp = n < 0 ? -n : n;
	if (n == 0) {
		str[0] = '0';
		str[1] = 0;
		return;
	}
	if (str == NULL)
	{
		return;
	}
	while (temp)
	{
		buf[i++] = (temp % 10) + '0';
		temp = temp / 10;
	}

	len = n < 0 ? ++i : i;  //如果n是負數,則多需要一位來儲存負號
	str[i] = 0;            //末尾是結束符0
	while (1)
	{
		i--;
		if (buf[len - i - 1] == 0)
		{
			break;
		}
		str[i] = buf[len - i - 1];  //把buf數組裡的字元拷到字串
	}
	if (i == 0)
	{
		str[i] = '-';          //如果是負數,新增一個負號
	}
}
int cmpl(string f, string l);                      
int main() {
	
	string k;
	char o = 0; string kk;
	cin >> k >> o >> kk;
	longint a(k), b(kk);
	switch (o)
	{
	case '+':cout << a + b << endl; break;
	case '-':cout << a - b << endl; break;
	case '*':cout << a * b << endl; break;
	case '/':cout << a / b << endl; break;
	default:
		break;
	}
	/*
	char tes[30] = {}; long long k = 0;
	while (cin >> k) {
		
		itoa1(k, tes, 10);
		cout<<tes<< endl << endl;
	}
	*/
	cin.get();
	cin.get();
	return 0;
}
int cmpl(string f, string l) {                                             //用於比較字串大小
	if (f.length() > l.length()) return 1;
	else if (f.length() < l.length()) return -1;
	else {
		for (int i = 0; i < f.length(); i++) {
			if (f[i] > l[i])return 1;
			if (l[i] > f[i])return -1;
		}
	}return 0;
}
longint::longint(string b) 
{
	a = b;
}
longint::longint()
{

}
longint::longint(const char *b)
{
	a = b;
}
string longint::operator=(const char * b)
{
	a = b;
	return a;
}
string longint::operator+(longint b)
{
	int maxlen = 0;
	string maxN;
	string minN;
	if (a.length() >= b.a.length()) {
		maxlen = a.length();
		maxN = "0";
		maxN += a;
		minN.resize(a.length() - b.a.length() + 1, '0');
		minN += b.a;
	}
	else {
		maxlen = b.a.length();
		maxN = "0";
		maxN += b.a;
		minN.resize(b.a.length() - a.length() + 1, '0');
		minN += a;
	}
	bool ad = 0;
	string Sr; Sr.resize(maxlen + 1, '0');
	for (int i = maxlen; i >= 0; i--) {
		int res = 0;
		if (ad) {
			res += 1;
			ad = 0;
		}
		char in1[2] = { maxN[i],'\0' };
		char in2[2] = { minN[i],'\0' };
		res += atoi1(in1) + atoi1(in2);

		if (res > 9) {
			ad = 1;
			char temp[3] = {}; itoa1(res, temp, 10);
			Sr[i] = temp[1];
		}
		else {
			char temp[2] = {}; itoa1(res, temp, 10);
			Sr[i] = temp[0];
		}
	}
	if (Sr[0] == '0') {
		Sr.erase(0, 1);
	}

	return Sr;
}
string longint::operator-(longint b)
{
	int maxlen = 0; bool nag = 0;
	string maxN;
	string minN;
	if (cmpl(a, b.a) == 1) {
		maxlen = a.length();
		maxN = "0";
		maxN += a;
		minN.resize(a.length() - b.a.length() + 1, '0');
		minN += b.a;
	}

	else if (cmpl(a, b.a) == -1) {
		nag = 1;
		maxlen = b.a.length();
		maxN = "0";
		maxN += b.a;
		minN.resize(b.a.length() - a.length() + 1, '0');
		minN += a;
	}
	else return "0";
	bool ad = 0;
	string Sr; Sr.resize(1, '0'); Sr.resize(maxlen + 1, '0');
	int res = 0;
	for (int i = maxlen; i >= 0; i--) {
		res = 0;
		if (ad) {
			res -= 1;
			ad = 0;
		}
		char in1[2] = { maxN[i],'\0' };
		char in2[2] = { minN[i],'\0' };
		if (in1[0] + res< in2[0]) {
			res += 10 + atoi1(in1) - atoi1(in2);
			ad = 1;
		}
		else res += atoi1(in1) - atoi1(in2);

		char temp[2] = {}; itoa1(res, temp, 10);
		Sr[i] = temp[0];

	}
	while (Sr[0] == '0'&&Sr[1] == '0') {
		Sr.erase(0, 1);

	}
	if (nag) {
		Sr[0] = '-';
	}
	else {
		Sr.erase(0, 1);
	}
	if (Sr[0] == 0) {
		Sr.erase(0, 1);
	}

	return Sr;
}
string longint::operator*(longint b)
{
	longint maxN;
	longint minN;
	if (a == "0" || b.a == "0")
		return "0";
	else if (cmpl(a, b.a) == 1) {
		maxN = a;
		minN = b.a;
	}
	else {
		maxN = b.a;
		minN = a;
	}
	longint times = minN;
	longint Sr;
	longint i = "1";
	Sr = maxN;
	/*for (; cmpl(i+i, times.a) != 1; i = i + i) {   // i<times
		Sr = Sr + Sr;
	}*/
	for (; cmpl(i.a, times.a) ==-1;) {                              //類似遞迴的迴圈
		longint k = "1";
		longint Sr1 = maxN;
		for (; cmpl(k+k, times - i) ==-1; k = k + k) {
			Sr1 = Sr1 + Sr1;
		}
		i = k + i;
		Sr = Sr + Sr1;
	}
	return Sr.a;
}
string  longint::operator/(longint b)
{
	longint maxN = a;
	longint minN = b.a;
	longint i = "0";
	longint k = "1";
	longint Sr1 = minN;
	for (; cmpl(((minN + minN)), (maxN.a.c_str())) != 1;) {

		k = "1";
		for (; cmpl((Sr1 + Sr1), maxN.a) != 1; k = k*"2") {
			Sr1 = Sr1 + Sr1;
		}
		i = k + i;
		maxN = maxN - Sr1;
		Sr1 = minN;
		k = "2";
	}
	for (; maxN.a[0] != '-'; i = i + "1") {                           <span style="font-family: Arial, Helvetica, sans-serif;">//類似遞迴的迴圈</span>

		maxN = maxN - minN;
	}i = i - "1";

	return i.a;
}
/*
741269586512                               // 一些測試資料
*
984562478654

56765156165465786156467
/
54657815454782

48789151687984156
*
56487112346786

8465156478654165468421
-
15646878115487854312234567

48951487894146576543215646
+
5123123165784512313215686

87894123467984512789
/
5684

1.729826221447080406314848

2.2755958292703544831466745522616

3.1038555157

4.-15638412959009200146766146

5.54074611059931088856431332

6.15463427774100019
*/

另外,大整數也可以用連結串列、陣列等來實現。

最後,提醒來找程式碼交作業的同學,不要直接拷貝啊!!!!這樣沒有任何好處!