c++高精度一系列的算法(包含阶乘求和)

高精度运算

一、高精度加减高精度以及高精度乘低精度。

#include <iostream>
#include <vector>                       //使用了vector动态数组的方法来实现。
#include <string>
using namespace std;
vector<int> add(vector<int> A, vector<int> B)
{
    cout << "高精度加法运算:\n";
    if (A.size() < B.size())
        return add(B, A);          //要保证用更长的一个数组来完成整个循环。
    vector<int>C; int t=0;
    for (int i = 0; i < A.size(); i++)
    {
        t += A[i];
        if (i < B.size())
            t +=B[i];
        C.push_back(t % 10);
            t /= 10;
    }
    if (t)                  //注意这一步if判断,在高精度减法中就不用这一步。
        C.push_back(t);
    while (C.size() >= 1&& C.back() == 0)           //清除前置零
        C.pop_back();                               //和push_back配套使用。
    for (int i = C.size() - 1; i >= 0; i--)
    {
        cout << C[i];
    }
    cout << endl;
    return C;
}
vector<int> mul(vector<int>A, vector<int>B)
{
    cout << "高精度减法运算:\n";
    if (A.size() < B.size())
        return mul(B, A);                   //保证用长的减短的。
    vector<int>C; int t = 0;
    for (int i = 0; i < A.size(); i++)
    {
        t = A[i] - t;
        if (i < B.size())
            t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0)                              //这步判断是跟高精度加法不一样的地方。
            t = 1;
        else
            t = 0;
    }
    
    while (C.size() >1 && C.back()==0)              //同样是为了清除前置零。
        C.pop_back();
    for (int i = C.size() - 1; i >= 0; i--)
    {
        cout << C[i];
    }
    cout << endl;
    return C;
}
vector<int> solve(vector<int>A, int x)
{
    cout << "高精度乘低精度:\n";
    vector<int>C;
    int t=0;
    for (int i = 0; i < A.size(); i++)
    {
        t+= A[i]*x ;                    //挨个乘。
        C.push_back(t % 10);
        t /= 10;
    }
    if (t)
        C.push_back(t);
    while (C.size() > 1 && C.back() == 0)
    C.pop_back();
    for (int i = C.size() - 1; i >=0 ; i--)             //注意一下for循环的条件。
    {
        cout << C[i];
    }
    cout << endl;
    return C;
}
int main()
{
    vector<int>A, B;
    string a, b;
    cin >> a >> b;
    for (int i=0;i<a.size();i++)
    {
        A.push_back(a[a.size()-1-i] - '0');     //for的这两种循环方式都可以,只是下边这种看着更加简洁。
    }
    for (int i = b.size() - 1; i >= 0; i--)
    {
        B.push_back(b[i] - '0');
    }
    add(A, B);
    mul(A, B);
    solve(A, 9);
    system("pause");
    return 0;
}

二、高精度乘高精度。

#include <iostream>
#include <string>
using namespace std;
int a[100], b[100], c[100];				//目的是为了将string类型转化为int类型存在数组中。
int main()
{
	string A, B;
	cin >> A >> B;
	for(int i =0;i<A.size();i++)		//这些转化的for语句循环条件要注意一点。
	{
		a[i] = A[A.size() - 1 - i] - '0';
	}
	for (int i = 0; i < B.size() ; i++)
	{
		b[i] = B[B.size() - 1 - i] - '0';
	}
	for (int i = 0; i < A.size() ; i++)
	{
		for (int j = 0; j < B.size() ; j++)
		{
			c[i + j] += a[i] * b[j];			//这三条语句是主要实现过程。
			c[i + j + 1] += c[i + j] / 10;	//贡献进位。
			c[i + j] %= 10;					
		}
	}
	int h = A.size() + B.size();			//这里用一个局部变量来大致推测长度。
	for (; !c[h];)							//这条语句来清除前置零;
		h--;
	for (int i = h; i >= 0; i--)
	{
		cout << c[i];
	}
	cout << endl;

	system("pause");
	return 0;
}

三、高精度阶乘

#include <iostream>
#define Max 100
using namespace std;
struct BigInt
{
	int len;		//;len用来记录长度;
	int a[Max];		//用来存储数据。
	BigInt(int x = 0)
	{
		memset(a, 0, sizeof(a));			//用来初始化数组。
		for (len = 1; x; len++)
		{
			a[len] = x % 10;
			x /= 10;
		}
	}
	int& operator[](int i)					//重载运算符[]为了方便定义的对象使用下标法访问
	{
		return a[i];
	}
	void flatten(int n)					//一个展平函数,非常好用,这样就可以不用单独处理*和+后的结果的了。
	{
		len = n;
		for (int i = 1; i <= n; i++)
		{
			a[i + 1] += a[i] / 10;
			a[i] %= 10;
		}
		for (; !a[len];)
			len--;
	}
	void print()			//打印结果函数。
	{
		for (int i = len; i >= 1; i--)				//这里注意一下为什么i不是>=0以为数组里面的下标是从1开始存储的。
		{
			cout << a[i];
		}
	}
};
BigInt operator+(BigInt A, BigInt B)			//运算符重载
{
	BigInt C;
	int h = max(A.len, B.len);
		for (int i = 1; i <= h; i++)
		{
			C[i] = A[i] + B[i];
		}
	C.flatten(h + 1);					//+1因为加法运算进位最多为1;
	return C;
}
BigInt operator* (BigInt A, int h)
{
	BigInt C;
	int k = A.len;
	for (int i = 1; i <= k; i++)
	{
		C[i] = A[i] * h;
	}
	C.flatten(k + 11);						//这里加11是为一个int类型的数据最长为10位,如果是十位可能产生一位进位,保险起见。
	return C;
}
int main()
{
	int m;
	cin >> m;
	BigInt ans(0), fac(1);					//ans(0)用于加法运算,fac(1)用来挨个乘。
	for (int i = 1; i <= m; i++)
	{
		fac = fac * i;				
		ans = ans + fac;
	}
	ans.print();

	system("pause");
	return 0;
}
上一篇:高频leetcode排序部分:15. 三数之和


下一篇:I'm Back