《算法笔记》第4章 入门篇(2)---算法初步 5.6 大整数运算

1.大整数的存储:

《算法笔记》第4章 入门篇(2)---算法初步 5.6 大整数运算_第1张图片

大整数结构:数组+长度

struct bign
{
	int a[1000];
	int len;   //len表示其长度
}

构造函数:

初始化结构体函数,函数名与结构体名相同,无返回值,写在结构体内部:

struct bign
{
	int a[1000];
	int len;   //len表示其长度
	begin()
	{
		memset(a,0,sizeof(a));
		len=0;		
	}	
}:

将字符串逆转为结构体数组:

由于都是用字符串来接受输入的数据,而大整数数组是把数字倒着存放进去,所以需要逆着放进去

bign change(char str[]) //将字符串数字转化为整数结构bign
{
	bign a;
	a.len=strlen(str);  //a的长度为字符串str的长度
	for(int i=0; i<a.len; i++)
	{
		a.d[i]=str[a.len-i-1]-'0';   //逆着赋值
	}
}

比较两个bign变量的大小:

在这里插入图片描述

int compare(bign a, bign b)
{
	if(a.len>b.len)  //如果a的长度达,就反回1
		return 1;
	else if(a.len<blen)   //a小,返回-1
		return -1;
	else   //这个是表示长度一样,然后比较字的大小
	{
		for(int i=a.len-1; i>=0; i--)  //从结构a开始从数组最后一位开始判断
		{
			if(a.a[i]>b.a[i])
				return 1;
			else 
				return -1;
		}
		return 0;
	}
}

大整数四则运算:

1.加法:

在这里插入图片描述

bign add(bign a, bign b)  //高进度a+b
{
	bign c;
	int carry=0;      //carry表示进位
	for(int i=0; i<a.len || i<b.len; i++)  //以a,b中较长的为界线
	{
		int temp=a[i]+b[i]+carry;   //将对应的位置数相加并且加上进位carry
		c.d[c.len++]=temp%10;   //个位数为该为的结果
		carry=temp/10;   //10位为新进的位
	}
	if(carry!=0)    //如果最后的进位不为0,则直接给新的数组的最高位
		c.d[c.len++]=carry;
	return c;
}

玩一个大整数加法:

//大整数的结构
//将字符数组转化为结构数组
//高精度加法
//输出函数,到这输出
#include
#include
#include   //这个用于memset()函数
using namespace std;
struct bign
{
    int d[1000];
    int len;
    bign()
    {
        memset(d,0,sizeof(d));
        len=0;
    }
};
bign change(string str)
{
    bign a;
    a.len=str.length();
    for(int i=0; i<a.len; i++)
        a.d[i]=str[a.len-i-1]-'0';
    return a;
}
bign add(bign a, bign b)
{
    bign c;
    int carry=0;    //设置一个进位为carry
    for(int i=0; i<a.len || i<b.len; i++)
    {
        int temp=a.d[i]+b.d[i]+carry;
        c.d[c.len++]=temp%10;
        carry=temp/10;
    }
    if(carry!=0)
        c.d[c.len++]=carry;
    return c;
}
int main()
{
    string a,b;
    bign x,y,z;
    cin >> a >> b;
    x=change(a);
    y=change(b);
    z=add(x,y);
    for(int i=z.len-1; i>=0; i--)
    {
        cout << z.d[i] << " ";
    }
}

2.减法:

在这里插入图片描述

注意使用sub前要比较两个数的大小,要交换两个变量,使用sub函数,最后输出负号

bign sub(bign a, bign b)   //高精度a-b
{
    bign c;
    for(int i=0; i<a.len || i<b.len; i++)
    {
        if(a.d[i]<b.d[i])  //如果不够减位
        {
            a.d[i+1]--;
            a.d[i]+=10;
        }
        c.d[c.len++]=a.d[i]-b.d[i];
    }
    while(c.len-1>=1 && c.d[c.len-1]==0)    //去除最高位的0,同时至少保留1位最低位
        c.len--;
    return c;
}

3.乘法:

《算法笔记》第4章 入门篇(2)---算法初步 5.6 大整数运算_第2张图片

bign multi(bign a, int b)  //a是大整数结构,b是第2个乘数
{
    bign c;
    int carry=0;   //进位
    for(int i=0; i<a.len; i++)
    {
        int temp=a.d[i]*b+carry;
        c.d[c.len++]=temp%10;
        carry=temp/10;
    }
    while(carry!=0)   //与加法不同,进位不一定只是进位1位,所以使用while
    {
        c.d[c.len++]=carry%10;
        carry/=10;
    }
    return c;

}

4.除法:

《算法笔记》第4章 入门篇(2)---算法初步 5.6 大整数运算_第3张图片

注意r的设置,这样可以保证在返回函数时,余数是最后剩余的那一个
《算法笔记》第4章 入门篇(2)---算法初步 5.6 大整数运算_第4张图片

bign divide(bign a, int b, int& r) //高进度除法,r是余数
{
    bign c;
    c.len=a.len;   //商的长度和除数的长度是对应的
    for(int i=a.len-1; i>=0; i--)   //从最高位开始
    {
        r=r*10+a.d[i];   //与上一位遗留的余数相加
        if(r<b)   //表示不够除
        {
            c.d[i]=0;  //商为0
        }
        else
        {
            c.d[i]=r/b;
            r=r%b;
        }
    }
    while(c.len-1>=1 && c.d[c.len-1]==0)
        c.len--;
    return c;
}

你可能感兴趣的:(《算法笔记》)