机试算法讲解:第31题 大整数的M进制转N进制

/*
将M进制的数X转换为N进制的数输出,2<=M,N<=36,输入时字母部分为大写,输出时为小写,并且有大数据
输入:
16(M进制) 10(N进制)
F(待转换的数)
输出:
15
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct BigInterger{
	int _digit[1000];
	int _size;
	void init();
	void set(int x);
	//重载的返回值仍然是大数
	BigInterger operator + (const BigInterger& x) const;
	BigInterger operator * (int x) const;
	BigInterger operator / (int x) const;
	int operator % (int x) const;
	void output();
}BigInterger;

void BigInterger::init()
{
	for(int i = 0 ; i < 1000 ; i++)
	{
		_digit[i] = 0;
	}
	_size = 0;
}

void BigInterger::set(int x)
{
	//易错,set之前一定要初始化
	init();
	do
	{
		_digit[_size++] = x%10000;//保存余数作为低位
		x /= 10000;//留下低位
	}while(x!=0);
}

BigInterger BigInterger::operator * (int x) const
{
	BigInterger ret;
	ret.init();
	int iPass = 0;//默认进位是从0开始
	//重载乘法,应该是从低位到高位乘
	for(int i = 0 ; i < _size ; i++)
	{
		int iSum = x*_digit[i] + iPass;
		ret._digit[ret._size++] = iSum % 10000;//记录乘积
		iPass = iSum / 10000;//获取进位
		iSum %= 10000;//获取余数
	}
	//如果最后的高位需要进位,则进位
	if(0!=iPass)
	{
		ret._digit[ret._size++] = iPass;
	}
	return ret;
}

BigInterger BigInterger::operator + (const BigInterger& x) const
{
	//两个大数相加,应该从低位开始
	BigInterger ret;
	ret.init();
	int iPass = 0;
	for(int i = 0 ; i < _size ; i++)
	{
		int iSum = _digit[i] + x._digit[i] + iPass;
		ret._digit[ret._size++] = iSum % 10000;
		iPass = iSum / 10000;
		//iSum /= 10000;
	}
	//最后高位需要进位
	if(0!=iPass)
	{
		ret._digit[ret._size++] = iPass;
	}
	return ret;
}


#define MaxSize 100
BigInterger BigInterger::operator / (int x) const
{
	//大数相除,应该从高位开始
	BigInterger ret;
	ret.init();
	int iRemainder = 0 ; //设置除数为0
	for(int i = _size - 1 ; i >= 0 ; i--)
	{
		//设置除数是上一趟的余数加上这一趟的本数
		int iShang = (10000*iRemainder + _digit[i]) / x;//求商
		int iYu = (10000*iRemainder + _digit[i]) % x;//求余数
		//ret._digit[ret._size] = iShang;//易错,保存本位的值,利用ret._digir[i] = iShang;
		ret._digit[i] = iShang;
		//易错,更新余数为本次求出的余数
		//iRemainder /= 10000;
		iRemainder = iYu;
	}
	//易错,需要设置,最高有效位的上一位为未使用过的那一位
	ret._size = 0;
	for(int j = 0 ; j < MaxSize ; j++)
	{
		if(ret._digit[j]!=0)
		{
			//ret._size = i;
			ret._size = j;
		}
	}
	ret._size++;
	//一定要返回那个值
	return ret;
}

int BigInterger::operator % (int x) const
{
	int iRemainder = 0 ; 
	for(int i = _size - 1 ; i >= 0 ; i--)
	{
		int iShang = (iRemainder*10000 + _digit[i]) / x;
		int iYu = (iRemainder*10000 + _digit[i]) % x;
		iRemainder = iYu;
	}
	return iRemainder;
}

void BigInterger::output()
{
	//输出时,应该从低到高输出
	bool isFirst = true;
	for(int i = _size - 1 ; i >= 0 ; i--)
	{
		if(i!=_size-1)
		{
			printf("%04d",_digit[i]);
		}
		else
		{
			printf("%d",_digit[i]);
		}
	}
	printf("\n");
}

int main(int argc,char* argv[])
{
	char str[10000];
	char ans[10000];//存放分解后的结果
	int m,n;
	while(EOF!=scanf("%d %d",&m,&n))
	{
		BigInterger a,b;
		scanf("%s",str);//待转换的数
		int iSize = strlen(str);
		a.set(0);//a的初始值设为0,用来保存十进制的m进制数
		b.set(1);//m->10进制,代表每一位的权重
		//m->10进制 
		for(int k = iSize - 1 ; k >=0 ; k--)
		{
			int t;
			if(str[k] <= '9' && str[k] >= '0')
			{
				t = str[k] - '0';
			}
			else
			{
				t = str[k] - 'A' + 10;
			}
			a = a + b*t;
			//a.output();
			b = b*m;//更新权重
		}
		int iCount = 0;//代表转换为n进制后的字符个数
		//10->n进制
		do{
			int iYu = a%n;//求余数
			if(iYu > 10)
			{
				ans[iCount++] = iYu - 10 + 'a';
			}
			else
			{
				ans[iCount++] = iYu + '0';
			}
			a = a/n;//求商
		}while(a._digit[0]!=0 || a._size!=1);
		for(int j = iCount - 1 ; j>= 0 ;j--)
		{
			printf("%c",ans[j]);
		}
		printf("\n");
	}
	system("pause");
	getchar();
	return 0;
}

你可能感兴趣的:(进制转换,机试算法,大整数表示)