zoukankan      html  css  js  c++  java
  • 高精度运算——加减乘除阶乘

    加法

    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	string a, b;
    	int i = 0, j;
    	int f = 0;//是否产生进位
    	int ans[510];
    	cin >> a >> b;
    	reverse(a.begin(), a.end());
    	reverse(b.begin(), b.end());
    
    	string temp;
    	//保证大数a的长度>=b的长度
    	if (a.length() < b.length()) {
    		temp = a;
    		a = b;
    		b = temp;
    	}
    	for (i = 0; i < b.length(); i++) {
    		int temp = (a[i] - '0') + (b[i] - '0') + f;
    		ans[i] = temp % 10;
    		if (temp >= 10) {
    			f = 1;
    		}
    		else {
    			f = 0;
    		}
    	}
    	if (a.length() > b.length()) {
    		while (i < a.length()) {
    			int temp = (a[i] - '0') + f;
    			ans[i] = temp % 10;
    			if (temp >= 10) {
    				f = 1;
    			}
    			else {
    				f = 0;
    			}
    			i++;
    		}
    	}
    	if (f == 1) {
    		cout << f;
    	}
    	for (j = i - 1; j >= 0; j--) {
    		cout << ans[j];
    	}
    	return 0;
    }
    

    减法

    #include<iostream>
    #include<string>
    #include<algorithm>
    
    using namespace std;
    
    #define maxsize 10100
    //比较大小   1:a大  2:b大
    int compare(string a, string b) {
    	int flag = 0;
    	if (a.length() > b.length()) {
    		return 1;
    	}
    	else if(a.length() < b.length()){
    		return 2;
    	}
    	else {
    		//长度相等,未逆转,直接比较,低位即数值高位
    		for (int i = 0; i < a.length(); i++) {
    			if (a[i] > b[i]) {
    				flag = 1;
    				return 1;
    			}
    			else if (b[i] > a[i]) {
    				flag = 1;
    				return 2;
    			}
    		}
    	}
    	if (flag == 0) {
    		return 0;//相等
    	}
    }
    int main() {
    	string a, b;
    	int i = 0, j;
    	int f = 0;//是否产生借位
    	int ans[maxsize];
    
    	cin >> a >> b;
    	int c = compare(a, b);
    
    	//a、b相等
    	if (c == 0) {
    		cout << "0" << endl;
    		return 0;
    	}
    	//若b比a大,先输出一个负号,交换a,b
    	if (c == 2) {
    		cout << "-"; 
    		swap(a, b);
    	}
    	
    	reverse(a.begin(), a.end());
    	reverse(b.begin(), b.end());
    
    	int atemp, btemp;
    	for (i = 0; i < b.length(); i++) {
    		atemp = a[i] - '0';
    		btemp = b[i] - '0';
    		if (atemp - f - btemp < 0) {			
    			ans[i] = atemp + 10 - f - btemp;
    			f = 1;
    		}
    		else {			
    			ans[i] = atemp - f - btemp;
    			f = 0;
    		}
    		
    	}
    	if (a.length() > b.length()) {
    		while (i < a.length()) {
    			atemp = a[i] - '0';
    			if (atemp - f < 0) {				
    				ans[i] = atemp + 10 - f;
    				f = 1;
    			}
    			else {				
    				ans[i] = atemp - f;
    				f = 0;
    			}
    			i++;
    		}
    	}
    	int zero = 0;
    	//3330000000000000
    	//3320000000000000
    	//0010000000000000前面的0不能输出
    	for (j = i - 1; j >= 0; j--) {
    		if (ans[j] != 0) {
    			zero = 1;
    		}//前面的0不输出
    		if (zero) {
    			cout << ans[j];
    		}
    		
    	}
    
    	return 0;
    }
    

    乘法

    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    int c[5001];
    int ans[5001];
    int main() {	
    	string a, b;		
    	cin >> a >> b;
    	//a,b中有0
    	if ((a.length() == 1 && a[0] == '0') || (b.length() == 1 && b[0] == '0')) {
    		cout << "0";
    		return 0;
    
    	}
    	reverse(a.begin(), a.end());
    	reverse(b.begin(), b.end());
    	int f, f2, i, j, k, m;
    	//f乘法进位,f2每位结果相加进位
    	int prel,length;
    	//循环,每一位被乘数
    	for (i = 0; i < b.length(); i++) {
    		f = 0;
    		k = 0;
    		int b1 = b[i] - '0';//取一位乘数
    		int wei = i;
    		while (wei--) { //高位乘要补0,第二位补1个0
    			c[k++] = 0;
    		}
    		//与被乘数每一位相乘
    		for (j = 0; j < a.length(); j++) {
    			int a1 = a[j] - '0';	
    			if (a1 * b1 + f < 10) {
    				c[k] = a1 * b1 + f;
    				f = 0;
    			}
    			else {
    				c[k] = (a1 * b1 + f) % 10;
    				f = (a1 * b1 + f) / 10;
    			}	
    			k++;
    		}
    		//最后一位的进位
    		if (f != 0) {
    			c[k++] = f;
    		}
    		// 乘数第一位乘被乘数的结果赋给ans,方便后期相加
    		if (i == 0) {  
    			for (m = 0; m < k; m++) {
    				ans[m] = c[m];
    			}
    			prel = k;//前一个结果的长度
    		}
    		else {			
    			m = 0; f2 = 0;
    			while (m < prel) {			
    				if (ans[m] + c[m] + f2 < 10){
    					ans[m] = ans[m] + c[m] + f2;
    					f2 = 0;
    				}
    				else {
    					int tt = f2; //否则会对ans值有影响
    					f2 = (ans[m] + c[m] + f2) / 10;
    					ans[m] = (ans[m] + c[m] + tt) % 10;
    					
    				}	
    				m++;
    			}
    			if (prel != k ){
    				while (m < k) {
    					if (c[m] + f2 <10) {
    						ans[m] = c[m] + f2;
    						f2 = 0;						
    					}
    					else {
    						int tt = f2;
    						f2 = (c[m] + f2) / 10;
    						ans[m] = (c[m] + tt) % 10;						
    					}
    					m++;
    				}				
    			}
    			if (f2 != 0) {
    				ans[m++] = f2;
    			}
    			prel = m;	
    		}
    	}	
    	for (int w = prel-1; w >= 0; w--) {
    		cout << ans[w];
    	}
    	cout << endl;	
    	return 0;
    }
    

    除法(高精度/单精度)

    #include<iostream>
    #include<string>
    //高精度/低精度
    using namespace std;
    #define maxsize 5010
    
    //
    int main() {
    	string a;
    	int b;
    	int i, j;
    	int ans[maxsize];
    	cin >> a >> b;
    
    	if (a.length() == 1 && a[0]-'0' == 0) {
    		cout << "0" << endl;
    		return 0;
    	}
    	int temp = 0;
    	j = 0;
    	for (i = 0; i < a.length(); i++) {
    		int t = a[i] - '0';
    		temp = temp * 10 + t;
    		if (temp >= b) {
    			//cout << temp << endl;
    			ans[j] = temp / b;
    			temp = temp % b;
    			//cout << ans[j] << " " << temp << endl;
    		}
    		else {
    			ans[j] = 0;
    		}
    		j++;
    	}
    	int zero = 0;
    	//cout << temp << endl;
    	for (i = 0; i < j; i++) {
    		if (ans[i] != 0) {
    			zero = 1;
    		}
    		if (zero) {
    			cout << ans[i];
    		}
    	}
    	return 0;
    }
    

    除法(高精度/高精度)

    搬运工

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    //去除前导0
    int delPreZero(int x[], int xLen) {
        int i = xLen;
    
        while (x[i - 1] == 0 && i > 1) {
            i--;
        }
    
        return i;
    }
    
    //逆序输出数组值 
    void printArr(int x[], int xLen) {
        for (int i = xLen - 1; i >= 0; i--) {
            cout << x[i];
        }
        cout << endl;
    }
    
    //若x>=y返回true,否则返回false 
    bool compare(int x[], int y[], int xLen, int yLen) {
        if (xLen < yLen) {
            return false;
        }
    
    
        if (xLen == yLen) {
            for (int i = xLen - 1; i >= 0; i--) {
                if (x[i] > y[i]) {
                    return true;
                }
                if (x[i] < y[i]) {
                    return false;
                }
            }
            return true;
        }
        return true;
    }
    
    //若x>=y,则x的高位减去y(只减一次),返回值为x的新长度
    int sub(int x[], int y[], int z[], int xLen, int yLen) {
        int zLoc = xLen - yLen;    //商的位置 
    
        //若不够减,则商的位置后移一位 
        for (int i = 1; i <= yLen; i++) {
            if (x[xLen - i] > y[yLen - i])
                break;
    
            if (x[xLen - i] < y[yLen - i]) {
                zLoc--;
                break;
            }
        }
    
        if (zLoc < 0)
            return xLen;
    
        //当前被除数x的高位与除数y做一次减法运算 
        for (int i = zLoc, j = 0; i < xLen && j < yLen; i++, j++) {
            while (x[i] < y[j]) {
                x[i + 1]--;
                x[i] += 10;
            }
    
            x[i] -= y[j];
        }
    
        //商的相应位置加一 
        z[zLoc]++;
    
        //计算当前被除数x的真实长度 
        while (x[xLen - 1] == 0)
            xLen--;
    
        if (xLen <= 0)
            xLen = 1;
    
        return xLen;
    }
    
    int main() {
        char as[301], bs[301];
    
        int a[301] = { 0 }, b[301] = { 0 }, c[301] = { 0 };
        int aLen = 0, bLen = 0, cLen = 1, maxLen = 0;
        int i;
    
        //输入 
        cin >> as >> bs;
        aLen = strlen(as);
        bLen = strlen(bs);
    
        //被除数和除数分别逆序存放 
        for (i = 0; i < aLen; i++) {
            a[i] = as[aLen - 1 - i] - '0';
        }
    
        for (i = 0; i < bLen; i++) {
            b[i] = bs[bLen - 1 - i] - '0';
        }
    
        //去除前导0
        aLen = delPreZero(a, aLen);
        bLen = delPreZero(b, bLen);
    
        //通过从高位开始连续减去除数,计算商和余数 
        cLen = aLen - bLen + 1;
        while (compare(a, b, aLen, bLen)) {
            aLen = sub(a, b, c, aLen, bLen);
        }
    
        //解决商的位数是0或负数的情况 
        if (cLen < 1) {
            cLen = 1;
        }
    
        //去除商的前导0 
        cLen = delPreZero(c, cLen);
    
        //输出商c 
        printArr(c, cLen);
    
        //输出余数a 
        printArr(a, aLen);
    
        return 0;
    }
    

    P1009 阶乘之和

    用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤50)

    #include<iostream>
    
    using namespace std;
    int a[2000];
    int b[2000];
    int c[2000];
    int sum[2000];
    
    void pplus(int* a, int* c)
    {
        int jw = 0;
        for (int i = 1; i <= 1000; i++)
        {
            c[i] += a[i] + jw;
            jw = c[i] / 10;
            c[i] %= 10;
        }
    }
    void cheng(int* a, int c)
    {
        int jw = 0;
        for (int i = 1; i <= 1000; i++)
        {
            a[i] = a[i] * c + jw;
            jw = a[i] / 10;
            a[i] %= 10;
        }
    }
    int main()
    {
        int n;
        cin >> n;
        a[1] = 1;
        for (int i = 1; i <= n; i++)
        {
            cheng(a, i);
            pplus(a, c);
        }
        bool flag = 0;
        for (int i = 1000; i >= 1; i--)
        {
            if (c[i] != 0) flag = 1;
            if (flag) cout << c[i];
        }
    }
    
  • 相关阅读:
    Leetcode Substring with Concatenation of All Words
    Leetcode Divide Two Integers
    Leetcode Edit Distance
    Leetcode Longest Palindromic Substring
    Leetcode Longest Substring Without Repeating Characters
    Leetcode 4Sum
    Leetcode 3Sum Closest
    Leetcode 3Sum
    Leetcode Candy
    Leetcode jump Game II
  • 原文地址:https://www.cnblogs.com/tanghm/p/12863233.html
Copyright © 2011-2022 走看看