求两个二进制数的最大公约数

时间:2021-12-07 00:33:49
#include<iostream>
#include<cstring>
using namespace std;
char s1[2005],s2[2005];

struct node{
 int len;
 int w[2005];
};

node Tr(char s[])
{
	int m=strlen(s);
	node n;
	n.len=m;
	int k=0;
	for(int i=m-1;i>=0;i--)
	{
		n.w[k]=s[i]-'0';
		k++;
	}
	return n;
}

node div(node a) //二进制数右移一位
{
	int m=a.len;
	for(int i=0;i<m-1;i++)
	{
		a.w[i]=a.w[i+1];
	}
	a.len--;
	return a;
}

node Minus(node a,node b)
{
    node c;
    int borrow=0,i;
    c.len=a.len;
    for(i=0;i<b.len;i++)
    {
        int tmp=a.w[i]-b.w[i]-borrow;
        if(tmp>=0)
        { borrow=0,c.w[i]=tmp;}
        else { borrow=1,c.w[i]=tmp+2;} //向前借一位
    }
    while(i<a.len)
    {
        int tmp=a.w[i]-borrow;
        if(tmp>=0)
        { borrow=0,c.w[i]=tmp;}
        else { borrow=1,c.w[i]=tmp+2;}
        i++;
    }
    i--;//i=a.len-1
    while(i>=0&&c.w[i]==0)
    {
        i--;
        c.len--;
    }
    return c;
}

void gcd(node a,node b) //a>b
{
    int cnt=0;
    while(a.len&&b.len)
    {
	if(a.w[0]==0) //a为偶数
	{
		if(b.w[0]==0) //b为偶数
		{
			a=div(a);
			b=div(b);
			cnt++;
		}
		else a=div(a);
	}
	else
    {
        if(b.w[0]==0)
            b=div(b);
        else
        {
            a=Minus(a,b);
        }
    }
    }
    if(a.len)
    {
        for(int i=a.len-1;i>=0;i--)
            cout<<a.w[i];
    }
    else
    {
        for(int i=b.len-1;i>=0;i--)
            cout<<b.w[i];
    }
    while(cnt--) cout<<'0'; //乘以2相当于在末尾添加一个0
    cout<<endl;
}

int main()
{
	while(cin>>s1>>s2)
    {
     node a,b;
	if(strcmp(s1,s2)>=0)
	{
		 a=Tr(s1);
	     b=Tr(s2);
	}
	else
	{
		 a=Tr(s2);
	     b=Tr(s1);
	}
	gcd(a,b);//保证a>=b
    }
    return 0;
}