ACM-进制转换

在做题的时候,遇到好多题目都是有关进制间的转换的,所以花点时间整理一下。具体的进制之间的转换方法,一般计算机书籍上都有,无非是基数与权值的讨论,只是将它们写成程序时有点费时。所以下面就直接给出一份比较简洁的模版:

const int MAXN = 1000;
int  t[MAXN], A[MAXN];
char OldData[MAXN], NewData[MAXN];  // 转换前、后的数据
int olds, news;                     // 转换前、后的进制

// 调用方式:输入olds、news、OldData,然后调用trans(),输出NewData
void trans()
{
    int i, len, k;
    len = strlen(OldData);
    for(i=len; i>=0; --i)
        t[len-1-i] = OldData[i] - (OldData[i]<58 ? 48 : OldData[i]<97 ? 55 : 61);
    for(k=0; len;)
    {
        for(i=len; i>=1; --i)
        {
            t[i-1] += t[i]%news*olds;
            t[i] /= news;
        }
        A[k++] = t[0] % news;
        t[0] /= news;
        while(len>0 && !t[len-1]) --len;
    }
    NewData[k] = NULL;
    for(i=0; i<k; ++i)
        NewData[k-1-i] = A[i] + (A[i]<10 ? 48 : A[i]<36 ? 55 : 61);
}

这份代码还有一个比较好的地方,就是数据是用字符串接收的,也就是说它可以处理高精度数据,哦,还有就是它适用于最高62进制的任意进制转换。

顺便说一句,java里面提供了一些现成的函数可直接用于进制间的转换,好像最高为35进制,下面给出一些,其它的可以查一查API文档:

int i = '123'; 
String iBin = Integer.toBinaryString(i);  // 二进制 
String iHex = Integer.toHexString(i);     // 十六进制 
String iOct = Integer.toOctalString(i);   // 八进制 
// 十六进制转成十进制    
Integer.valueOf("FFFF",16).toString() 
// 八进制转成十进制 
Integer.valueOf("876",8).toString() 
// 二进制转十进制 
Integer.valueOf("0101",2).toString() 
String iWoKao = Integer.toString(i,3);    // 三进制或任何你想要的35进制以下的进制 


下面做一道题目来试一下,POJ:1220,时空转移(点击打开链接),题目如下:

NUMBER BASE CONVERSION
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 4324 Accepted: 1951

Description

Write a program to convert numbers in one base to numbers in a second base. There are 62 different digits: 
{ 0-9,A-Z,a-z } 
HINT: If you make a sequence of base conversions using the output of one conversion as the input to the next, when you get back to the original base, you should get the original number. 

Input

The first line of input contains a single positive integer. This is the number of lines that follow. Each of the following lines will have a (decimal) input base followed by a (decimal) output base followed by a number expressed in the input base. Both the input base and the output base will be in the range from 2 to 62. That is (in decimal) A = 10, B = 11, ..., Z = 35, a = 36, b = 37, ..., z = 61 (0-9 have their usual meanings). 

Output

The output of the program should consist of three lines of output for each base conversion performed. The first line should be the input base in decimal followed by a space then the input number (as given expressed in the input base). The second output line should be the output base followed by a space then the input number (as expressed in the output base). The third output line is blank. 

Sample Input

8
62 2 abcdefghiz
10 16 1234567890123456789012345678901234567890
16 35 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 23 333YMHOUE8JPLT7OX6K9FYCQ8A
23 49 946B9AA02MI37E3D3MMJ4G7BL2F05
49 61 1VbDkSIMJL3JjRgAdlUfcaWj
61 5 dl9MDSWqwHjDnToKcsWE1S
5 10 42104444441001414401221302402201233340311104212022133030

Sample Output

62 abcdefghiz
2 11011100000100010111110010010110011111001001100011010010001

10 1234567890123456789012345678901234567890
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2

16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 333YMHOUE8JPLT7OX6K9FYCQ8A

35 333YMHOUE8JPLT7OX6K9FYCQ8A
23 946B9AA02MI37E3D3MMJ4G7BL2F05

23 946B9AA02MI37E3D3MMJ4G7BL2F05
49 1VbDkSIMJL3JjRgAdlUfcaWj

49 1VbDkSIMJL3JjRgAdlUfcaWj
61 dl9MDSWqwHjDnToKcsWE1S

61 dl9MDSWqwHjDnToKcsWE1S
5 42104444441001414401221302402201233340311104212022133030

5 42104444441001414401221302402201233340311104212022133030
10 1234567890123456789012345678901234567890

题意:

给一个数据,已知它原来的进制,和想要转换的进制,输出转换后的数。注意,最高的进制为62,因为数据由{0-9,A-Z,a-z}组成。

分析:

纯粹模版题,带一下模版先,就这么过了。

源代码:

#include <stdio.h>
#include <string.h>

const int MAXN = 1000;
int  t[MAXN], A[MAXN];
char OldData[MAXN], NewData[MAXN];  // 转换前、后的数据
int olds, news;                     // 转换前、后的进制

// 调用方式:输入olds、news、OldData,然后调用trans(),输出NewData
void trans()
{
    int i, len, k;
    len = strlen(OldData);
    for(i=len; i>=0; --i)
        t[len-1-i] = OldData[i] - (OldData[i]<58 ? 48 : OldData[i]<97 ? 55 : 61);
    for(k=0; len;)
    {
        for(i=len; i>=1; --i)
        {
            t[i-1] += t[i]%news*olds;
            t[i] /= news;
        }
        A[k++] = t[0] % news;
        t[0] /= news;
        while(len>0 && !t[len-1]) --len;
    }
    NewData[k] = NULL;
    for(i=0; i<k; ++i)
        NewData[k-1-i] = A[i] + (A[i]<10 ? 48 : A[i]<36 ? 55 : 61);
}

int main()
{//freopen("sample.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%s",&olds, &news, &OldData);
        trans();
        printf("%d %s\n%d %s\n\n", olds, OldData, news, NewData);
    }
    return 0;
}

进制转换大致就这些了,其它类似的题目还有,POJ:2798,HDOJ:1230.。

下一篇再说一下有关进制的问题,就是不同进制下的加法,传送门(点击打开链接)。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值