将十进制数互赞换成八进制数的C语言,洛谷 P1017 [NOIP2000 提高组] 进制转换

输入数字n 进制r

先将输入的数字n按照正数的进制转换int数组 记得倒叙

然后按照奇偶位拆成2个数组 array1(偶位数组) array2(奇位数组)

在正数的进制下 abs(n)=array1+array2

在负进制体系下 偶数数组代表正数 奇数数组代表负数

如果n为正数 那么n=array1-array2

如果n为负数 那么n=array2-array1

然后实现一个特殊的加法 计算上面的式子

如果前一位和大于 abs(r) 那么进位是负数

如果前一位的和小于0 那么进位是正数

(因为相邻2位代表的值符号是不一样的 所以进位也要相反)

最后要保证所有的位数都是正数就OK了

最后加出来的结果就是 答案

#include

#include

// const char WeiNum[21]="0123456789ABCDEFGHIJ";

//大数加法 特殊加法进位-1

//传入数组是倒叙 返回也是倒叙

//num 几进制

void add(int * array1,int len1,int* array2,int len2,int *result,int &len,int num)

{

int i;

len=(len1>len2?len1:len2)+1;

for(i = 0; i < len; i++)

{

result[i]=0;

}

//倒序相加直到小的数被加完为止

for(i = 0;i

{

int num1=0;

int num2=0;

if(i

{

num1=array1[i];

}

if(i

{

num2=array2[i];

}

result[i] = num1+num2;

}

//从低位到高位进行进位

for(i = 0; i < len; i++)

{

if(result[i] >= num)

{

result[i+1] -= result[i]/num;

result[i] %= num;

}

else if(result[i]<0)

{

int value=result[i]/num;

int yu=result[i]%num;

if(yu<0)

{

value--;

yu+=num;

}

result[i]=yu;

result[i+1] -=value;

}

}

//将前导0全部剔掉,比如我们结果是236,在result中

//是这样存储的63200……我们需要定位到第一个不为零的数,它的位置也就是i ,两数相乘,位数最多是两数位数之和

for(i = len-1; i >= 0 ; i--)

{

if(result[i] != 0)

{

break;

}

}

len=i+1;

}

void printNum(int * array,int len){

for(int i=len-1; i >=0; i--)

{

// printf("%c",WeiNum[array[i]]);

int tmp=array[i];

// if(tmp<0)

// {

// tmp=-tmp;

// }

if(tmp<10)

{

printf("%d",tmp);

}

else{

char c=tmp-10+'A';

printf("%c",c);

}

}

// printf("\n");

}

// // //将int转成int数组 倒叙 num 几进制 len存长度

int* formatInt(int a,int num,int &len)

{

double tmp=log(a)/log(num);

len=(int)tmp+1;

double end=tmp-len;

//防止出现tmp=x.99999999这种情况

if(end>1-10^-8)

{

len++;

}

int * array=new int[len];

int tmp2=a;

for(int i=0;i

{

array[i]=tmp2%num;

tmp2/=num;

}

return array;

}

// int powInt(int r,int n)

// {

// int result=1;

// for(int i=0;i

// {

// result*=r;

// }

// return result;

// }

// int jsWeiNum(int n,int absr,int &wei,int &value){

// int absn=abs(n);

// double len_d=log(absn)/log(absr);

// int len=(int)(len_d);

// int flag=len%2==0?1:-1;

// int tmp=powInt(-absr,len);

// //同号

// if(n*flag>0)

// {

// value=n/tmp;

// if(value>=absr)

// {

// len+=2;

// tmp*=absr*absr;

// wei=len;

// value=1;

// }

// else {

// if(n%tmp==0)

// {

// value=n/tmp;

// wei=len;

// return 0;

// }

// else{

// //等比数列求和

// int bi=absr*absr;

// int start=(len%2==0?1:absr);

// int sum=(absr-1)*(abs(tmp)*bi-start)/(bi-1);

// if(absn>sum)

// {

// len+=2;

// tmp*=absr*absr;

// wei=len;

// value=1;

// }

// else{

// wei=len;

// value=n/tmp;

// }

// }

// }

// }

// //异号

// else{

// len+=1;

// tmp*=-absr;

// wei=len;

// value=1;

// }

// return n-tmp*value;

// }

int* jsIntArray(int n,int r,int &len)

{

int* array;

if(n==0)

{

len=1;

array=new int[len];

array[0]=0;

}

else{

int i;

int absn=abs(n);

int absr=abs(r);

int len1=0;

int* array1=formatInt(absn,absr,len1);

int len2=len1+1;

int * array2=new int[len2];

len=len1+2;

array=new int[len];

// printNum(array1,len1);

// printf("\n");

//判断哪个位置的需要补差

int flag=n>0?1:0;

for(i=0;i

{

array2[i]=0;

}

for(i=flag;i

{

array2[i]=-array1[i];

array1[i]=0;

}

// printNum(array1,len1);

// printf("\n");

// printNum(array2,len2);

// printf("\n");

add(array1,len1,array2,len2,array,len,absr);

delete array1;

delete array2;

}

return array;

}

int main(){

int n,r;

scanf("%d %d",&n,&r);

int len=0,i=0;

int* array=jsIntArray(n,r,len);

printf("%d=",n);

printNum(array,len);

printf("(base%d)\n",r);

delete array;

// int n,r,i,j,len;

// int *array;

// scanf("%d",&r);

// FILE *fpl; //定义两个文件指针变量fpl和fp2

// fpl=fopen("E:\\fl.txt","wb");//以

// for(j=-37336;j<=37336;j++)

// {

// len=0;

// array=jsIntArray(j,r,len);

// // printf("%d=",j);

// // printNum(array,len);

// // printf("(base%d)\n",r);

// for(int i=len-1; i >=0; i--)

// {

// // printf("%c",WeiNum[array[i]]);

// if(array[i]<10)

// {

// fprintf(fpl,"%d",array[i]);

// }

// else{

// char c=array[i]-10+'A';

// fprintf(fpl,"%c",c);

// }

// }

// int num=0;

// int tmpPow=1;

// for(i=0;i

// {

// num+=tmpPow*array[i];

// tmpPow*=r;

// }

// fprintf(fpl," %d %d\n",j,num);

// delete array;

// if(num!=j)

// {

// break;

// }

// }

// fclose(fpl);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值