Arbitrary binary conversion (for purposes of Tarsus)

In the data structure on the stack lesson of this chapter, we have learned with "take the remainder modulo-2 method" to convert a decimal to a binary number, and then can be extended to "take the remainder modulo n Law", by which is converted to n-ary (n arbitrarily assigned). Indeed, this is a very basic problem, can you ever wondered if the decimal is a large number (thousands of its digits might, this time with the general type of data will certainly overflow), then the problem how to solve it?

Of course, you might say a very simple thing, to write a class of large numbers (of course, at least to write a large number divide the job), or you use the Java language that modern, more easily, and the direct use of this BigInteger since the class of large numbers can represent a large number, and then use the book to teach the method to achieve.

However, you really need to use large numbers class? In fact, the "overkill", we simulate some operations after the above can be found in the paper, just do some minor improvements can be made without the use of large numbers, can also "modulo n

Modulo "principle to achieve the base for the conversion of large numbers. (Of course, the whole idea is still" take the remainder modulo n "principle !!!).

As a simple example, it is for example converted to decimal 12 in binary form, the method of the books can be represented in FIG.

According to "I first was low, after more than for the high" this iron law, the result is 1100.

This book is to teach our conventional thinking (unfortunately by this case, large numbers are not considered, because if this is not 12, but a 1000 large numbers, because it is a whole large numbers are modulo operation without the use of large numbers and class

Division operations, how to proceed? ), But our aim is not to use large numbers class, so now we have to look at this issue from another angle, 12 is a ten digit, the ten is 1, the last digit is 2, in accordance with our normal

Thinking point of view, this calculation should look like the following:

Then we found in the first round of the operation, as dividend 1, 2 as a divisor on ten, the resulting quotient is 0, the remainder is 1 (can be asserted only consider the current calculation of the number of bits, the remainder either 0 or 1, if 1, then enter

When the next number of bits (i.e., here, for bit calculates), multiplied by a use band (here 10) values ​​(here, 2)), i.e., bits on the algorithm proceeds to give the number of bits and adding the dividend is a 12 , the divisor is 2, the resulting quotient is 6,

The number is zero. The results of the first round is a commercial operation is 06, the remainder is 0.

进入第二轮运算,则上一轮的商6(这里首先要去掉前面多余的0)变成本轮的被除数,如此下去,即可得到每轮的余数。

推广开来,如果被除数是一个1000位的大数,例如“12343435154324123……342314324343”

那么我们照样可以从第一个数位开始逐位考虑,比如第一位是1(作为被除数),2是除数,得到的商是0,余数是1,然后是第二个数位2,由于上一位留下了余数1,则此时被

除数应该是1*10+2 = 12,所以得到的商是6,余数是0,即运算到此时的商是06,然后是第三个数位3,由于上一个数位留下的余数是0,所以此时被除数就是3,。。。如此下去

就完成第一轮的运算,这一轮完毕后,需要把得到的商变成下一轮的被除数,继续上述的运算,直到被除数为0才停止。

下面给出了一个示例代码,展示了如何将一个10进制的大数转换为其二进制形式,仅供参考:

 1 #include <stdio.h>
 2 #include <string.h>
 3  
 4 char str[1000];//输入字符串
 5 int start[1000],ans[1000],res[1000]; //被除数,商,余数
 6  
 7 //转换前后的进制
 8 const int oldBase = 10;
 9 const int newBase = 2;
10  
11 void change()
12 {//各个数位还原为数字形式
13     int i,len = strlen(str);
14     start[0] = len;
15     for(i=1;i<= len;i++)
16     {
17         if(str[i-1] >= '0' && str[i-1] <= '9')
18         {
19             start[i] = str[i-1] - '0';
20         }
21     } 
22 }
23  
24 void solve()
25 {
26     memset(res,0,sizeof(res));//余数初始化为空
27     int y,i,j;
28     //模n取余法,(总体规律是先余为低位,后余为高位)
29     while(start[0] >= 1)
30     {//只要被除数仍然大于等于1,那就继续“模2取余”
31         y=0;
32         i=1;
33         ans[0]=start[0];
34         //
35         while(i <= start[0])
36         {
37             y = y * oldBase + start[i];
38             ans[i++] = y/newBase;
39             y %= newBase; 
40         }
41         res[++res[0]] = y;//这一轮运算得到的余数
42         i = 1;
43         //找到下一轮商的起始处
44         while((i<=ans[0]) && (ans[i]==0)) i++;
45         //清除这一轮使用的被除数
46         memset(start,0,sizeof(start));
47         //本轮得到的商变为下一轮的被除数
48         for(j = i;j <= ans[0];j++)
49             start[++start[0]] = ans[j]; 
50         memset(ans,0,sizeof(ans)); //清除这一轮的商,为下一轮运算做准备
51     } 
52 }
53  
54 void output()
55 {//从高位到低位逆序输出
56     int i;
57     for(i = res[0];i >= 1;--i)
58     {  
59         printf("%d",res[i]);
60     }
61     printf("\n"); 
62 }
63  
64 int main()
65 {
66     scanf("%s",str);
67     change();
68     solve();
69     output();
70     return 0;
71 }

接下来让我们将次算法具体应用到题目中:

题目地址:https://ac.nowcoder.com/acm/contest/910/C

题目描述

给出一个m进制下的数a,现在请输出a在n进制下的表示。

输入描述:

第一行一个整数T,代表有T组数据

接下来T行:

每一行有3个整数,分别表示m,n,a,其中2=<m<=62,2=<n<=62,a的位数不超过350位且a>=0,样例个数不超过400。

输出描述:

输出上述问题的答案,每个答案占一行。
示例1

输入

1
10 2 3

输出

11

hashch[]与hashnum这两个数组我觉得设计的非常好!
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=5000+100;
 4 char hashch[maxn];
 5 int hashnum[maxn];
 6 void init()
 7 {
 8     char ch;
 9     for(int i=0;i<62;i++){
10         if(i<10)                ch=i+'0';
11         else if(i>=10&&i<36)    ch='A'+i-10;
12         else                    ch='a'+i-36;
13         hashch[i]=ch;
14         hashnum[ch]=i;
15     }
16 }
17 string change(int m,int n,string str)
18 {
19     bool flag;
20     string ans="";
21     int tmp,quotient,remainder;
22     while(true)
23     {
24         flag=false;
25         remainder=0;
26         string div="";
27         int len=str.length();
28         for(int i=0;i<len;i++){
29             tmp=remainder*m+hashnum[str[i]];
30             quotient=tmp/n;
31             remainder=tmp%n;
32             if(flag){
33                 div+=hashch[quotient];
34             }
35             else{
36                 if(quotient!=0){
37                     flag=true;
38                     div+=hashch[quotient];
39                 }
40             }
41         }
42         ans=hashch[remainder]+ans;
43         str=div;
44         if(flag==false) break;
45     }
46     return ans;
47 }
48   
49 int main()
50 {
51     init();
52     int t;
53     scanf("%d",&t);
54     while(t--){
55         int m,n;
56         string str;
57         cin>>m>>n>>str;
58         string ans=change(m,n,str);
59         cout<<ans<<endl;
60     }
61     return 0;
62 }

 

参考文献:

https://blog.csdn.net/SJF0115/article/details/8690581

Guess you like

Origin www.cnblogs.com/XDU-Lakers/p/11373157.html