首页 > 试题广场 >

进制转换

[编程题]进制转换
  • 热度指数:35080 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。

输入描述:
多组数据,每行为一个长度不超过30位的十进制非负整数。
(注意是10进制数字的个数可能有30个,而非30bits的整数)


输出描述:
每行输出对应的二进制数。
示例1

输入

0
1
3
8

输出

0
1
11
1000
就是大数除法,每次求得余数作为进制上位的数字。
#include <bits/stdc++.h>
using namespace std;
int main(){
	string S;
	stack<char> T;
	for(int M,N,lm,i,j,c;cin>>M>>N>>S;cout<<endl){
		lm = S.length();
		vector<int> V(lm,0);
		for(i=0;i<lm;V[i]=(isalpha(S[i])?S[i]-'A'+10:S[i]-'0'),++i);
		for(i=0;i<lm;V[i]?0:++i){
			for(j=i,c=0;j<lm;++j){
				V[j]+=c*M;
				c=V[j]%N;
				V[j]/=N;
			}
			T.push(c>9?'a'+c-10:'0'+c);
		}
		for(;T.top()=='0';T.pop());	// trim back zero
		for(;T.size();cout<<T.top(),T.pop());
	}
    return 0;
} 


发表于 2016-09-04 10:13:03 回复(0)
利用短除法,一直除至0,输出的数通过栈反序输出。
通过字符数组接受数据,转换成int存入队列q1中,将队列中的数据一次取出对2取余,整除,存入第二个队列q2,直到第一个队列为空,将去q1=q2;循环,直到q1为空
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
int main(){
    char ch[35];
    while(cin>>ch){
        queue<int> q1;
        stack<int> s1;
        for(int i=0;i<strlen(ch);i++){//装换为int
            int temp=ch[i]-'0';
            q1.push(temp);//存入队列
        }
        while(!q1.empty()){//结束条件,队列为空 
            int cf=0;//进位;
            queue<int> q2;//临时队列,存中间数据
            while(!q1.empty()){
                int temp=q1.front();
               // cout<<temp<<endl;
                q1.pop();
                int sum=cf*10+temp;
                if(sum%2==1){
                    cf=1;
                }else{
                    cf=0;
                }
                int next=sum/2;
                //判断第一个数为0的情况
                if(next==0){
                    if(!q2.empty()){
                        q2.push(next);
                    }
                }else{
                    q2.push(next);
                }
            }
            q1=q2;
            s1.push(cf);//结果放入栈中
        }
        while(!s1.empty()){//输出
            cout<<s1.top();
            s1.pop();
        }
        cout<<endl;
    }
    return 0;
}


发表于 2020-08-08 10:45:24 回复(0)
try:
    while True:
        print(bin(int(input())).replace('0b',''))
except Exception:
    pass
编辑于 2018-10-09 10:28:39 回复(2)

python 解法


def baseN(num, b):
    return ((num == 0) and "0") or (baseN(num // b, b).lstrip("0") + "0123456789abcdefghijklmnopqrstuvwxyz"[num % b])
while True:
    try:
        a,b=map(int,input().split())
        c=input()
        val=int(c,a)
        print(baseN(val,b))
    except:
        break

这道题一定要懂清楚题目意思,有点绕。。

要先把输入的M进制的数转为十进制,再根据要求转为N进制。

python的int函数可以方便的实现将任意进制的数转为十进制。将十进制转为N进制,由baseN函数实现。

这种解法代码量较少。

编辑于 2017-10-16 16:03:14 回复(0)
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
	public static void main(String[] args) {	
		change();
	}

	public static void change() {
		Scanner in=new Scanner(System.in);
		while (in.hasNext()) {
			int M=in.nextInt();
			int N=in.nextInt();
			String val=in.next();
			BigInteger big=new BigInteger(val, M);
			String ss=big.toString(N).toLowerCase();
			System.out.println(ss);
		}
	}
}
直接使用了BigInteger类型,因为BigInteger有这样的数据结构:
BigInteger(String val, int radix)
 将指定基数的 BigInteger 的字符串表示形式转换为 BigInteger。
还有这样的toString方法:
toString(int radix)
 返回此 BigInteger 的给定基数的字符串表示形式。
再根据题目要求,把string变成小写就好了。
 
发表于 2016-08-27 18:01:46 回复(2)
GO:利用列表来装过长的数值,实现用列表除法
package main

// 最大30位数10进制转2进制输出

import (
	"fmt"
	"strconv"
	"strings"
)

// 转换成列表实现除法
func divide2(list []string) ([]string, bool) {
	is2 := false
	for k, item := range list {
		num, _ := strconv.Atoi(item)
		if k != 0 && is2 {
			num += 10
		}
		if num%2 == 0 {
			is2 = false
		} else {
			is2 = true
		}
		list[k] = strconv.Itoa(num / 2)
	}
	return list, is2
}

// Translate 将字符串分割列表
func Translate(num string) string {
	var res []string
	list := strings.Split(num, "")
	b := true
	for i := 0; i <= len(list)-1; i++ {
		for list[i] != "0" {
			list, b = divide2(list)
			if b {
				res = append(res, "1")
			} else {
				res = append(res, "0")
			}
		}
	}
	result := ""
	for i := len(res) - 1; i >= 0; i-- {
		result += res[i]
	}
	return result
}

func main() {
	var str string
	for {
		_, err := fmt.Scan(&str)
		if err != nil {
			break
		}
		a := Translate(str)
		fmt.Println(a)
	}

}

发表于 2022-06-23 09:55:32 回复(0)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <vector>
using namespace std;

vector<int> myVector;

string divide(string str, int n)//相当于实现n/2的操作,只要商。
{
    int mode = 0;
    for (int i = 0; i < str.size(); i++)
    {
        int current = mode * 10 + str[i] - '0';
        str[i] = current / n + '0';
        mode = current % n;
    }
    int pos = 0;
    while (str[pos] == '0')
    {
        pos++;
    }
    return str.substr(pos);
}

int main()
{
    string str;
    while (cin >> str)
    {
        while (str.size())
        {
            int last = str[str.size() - 1] - '0';
            myVector.push_back(last % 2);
            str = divide(str, 2);
        }
        for (int i = myVector.size() - 1; i >= 0; i--)
        {
            printf("%d", myVector[i]);
        }
        cout << endl;
        myVector.clear();
    }
    return EXIT_SUCCESS;
}

发表于 2021-02-18 13:54:48 回复(0)
输入的数过长得用字符来处理,难点也就是需要用字符来模拟除法,用字符数组看着不顺眼,用string来处理,为了判断是否已经除尽,用一个start标识每轮的除法开始位置,看代码吧,注释比较详细
#include "bits/stdc++.h"

#include <string>

using namespace std;

int main(){
    string input;
    while(cin>>input){
        int len = input.length();
        stack<int> result;
        int start = 0;//用来判断本轮除法从哪一位开始,因为循环除法过程中高位会变为零,这时候就需要start++,用来防止高位0的重复计算
        while(start<len){//当然,开始位置达到len也就表示整个数已经除到了0,结束
            //来模拟除2
            int res,remainder;//从高位开始除法,分别代表/2的结果和余数,余数参与下一位的除法计算。
            remainder = 0;
            for(int i=start; i<len; i++){
                res = (remainder*10 + (int)(input[i] - '0'))/2;//当前位模拟除法
                remainder = (remainder*10 + (int)(input[i] - '0'))%2;//当前位模拟取余
                if(res == 0 && i == start)start++;//除得0,意味着原数变短一位(当且仅当,当前位是当前数首位)
                input[i] = res+'0';
            }
            result.push(remainder);//本轮除法完毕,最终余数入栈
//            cout<<input<<endl;
        }
        while (!result.empty()){//所有余数弹栈,结果就是答案
            cout<<result.top();
            result.pop();
        }
        cout<<endl;
    }
}


编辑于 2021-02-04 19:25:34 回复(0)
#include<bits/stdc++.h>

using namespace std;

string Div(string a, int b, int& r)   //大整数除法 得余数
{
    string c; r = 0;
    for(int i = 0;i < a.length(); i++)
    {
        r = r*10+a[i]-'0';
        if(r < b) c += '0';
        else
        {
            c += (r/b+'0'); r %= b;
        }
    }
    while(c.length() > 1 && c[0] == '0') c.erase(c.begin());
    return c;
}

string get2(string num)    //十进制转二进制
{
    string ans = ""; int r = 0;
    do       //do-while保证二进制0
    {
        num = Div(num, 2, r);
        ans = (char)(r+'0') + ans;
    }while(num != "0");
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    string num;
    while(cin >> num)
    {
        cout << get2(num) << "\n";
    }
    return 0;
}
用时4ms,请教可以时间优化的地方😐。
编辑于 2021-01-17 22:00:20 回复(0)
print(bin(int(input())).replace('0b', ''))

发表于 2020-10-26 14:34:19 回复(0)
#include<stdio.h>//进制转换,其余进制再写个数组存字母输出即可
#include<string.h>
int zhuan(int a[],int b[],int n,int from,int to)//进制转换函数
{
    int size=0,i,j,t;
    for(i=0;i<n;)
    {
        int k=0;
        for(j=i;j<n;j++)//每一位都做除法
        {
            t=(a[j]+k*from)%to;
            a[j]=(a[j]+k*from)/to;
            k=t;//整个循环结束得到第一个二进制数
        }
        b[size++]=k;//一个二进制数
        while(a[i]==0) i++;//从非零的数开始做除法
    }
    return size;
}
int main()
{
    char sa[31];
    int a[31],b[1000],i,j;
   while(gets(sa)!=NULL)
    {
        for(i=0;sa[i]!='\0';i++)
            a[i]=sa[i]-'0';//字符数组转换成整数数组
        int size=zhuan(a,b,strlen(sa),10,2);
        for(i=size-1;i>=0;i--)//进制转换倒序输出
            printf("%d",b[i]);
        printf("\n");
    }
}

编辑于 2020-04-26 15:40:50 回复(0)
Java 解法 
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) System.out.println( scanner.nextBigInteger().toString(2));
    }
}


发表于 2020-03-18 10:20:23 回复(0)
#include<stdio.h> void main() { unsigned n; int a[30],i=0; printf("please input a number less 30 characters:"); scanf("%d",&n); while(n>1){ a[i++]=n%2; n=n/2; } if(n==1) a[i]=1; else i--; while(i>=0) printf("%d",a[i--]); }
发表于 2018-03-24 11:36:23 回复(0)
我的主要思路是:
    1)用字符数组存十进制数和二进制数
    2)进制转换还是使用除2得余法,先顺序存储每次的余数,再反转。
    3)至于除余运算:
            t [ ] 是十进制数
            c位高位余数,初值为0,
            遍历t [ i ] ,新的进位c0=(t[i]+c*10)%2
                                新的t[ i ] = (t[i]+c*10)/2
                                c=c0;
            遍历结束的c就是整个数除以2 的余数,而t【】是商
   
#include 
#include 
#include 
#include 
void change(const char *s,char *s2){
    int lens=strlen(s);
    char t[lens];
    int lent=lens;
    for(int i=0;i<lens;++i){
        t[i]=s[i]-'0';
    }
    int j=0;
    int c=0;
    int r=0;
    while(1){
        while(r<lent && t[r]==0)  ++r;
        if(r>=lent){    break;  }
        for(int i=r;i<lent;++i){
            int c0=t[i]%2;
            t[i]=(t[i]+c*10)/2;
            c=c0;
        }
        s2[j++]=c;
        c=0;
    }
    int lens2=j;
    for(int i=0;i<lens2/2;++i){
        char t=s2[i];
        s2[i]=s2[lens2-1-i];
        s2[lens2-1-i]=t;
    }
    for(int i=0;i<lens2;++i){
        s2[i]+='0';
    }
    s2[lens2]='\0';
}
int main(){
    char s[35];
    char s2[150];
    while(1){
        int flag=scanf("%30s",s);
        if(flag==EOF)   break;
        change(s,s2);
        printf("%s\n",s2);
    }
    return 0;
}

发表于 2018-02-04 23:58:07 回复(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;

int main()
{
	int m,n,shum[1000],shun[1000],i,j,jin,k;
	char strm[1000];
	while(~scanf("%d%d",&m,&n))
	{
		for(i=0;i<1000;i++) shum[i]=shun[i]=0;
		scanf("%s",strm);
		for(i=0;i<strlen(strm);i++) 
		{
			if(strm[i]>='0'&&strm[i]<='9') shum[i]=strm[i]-'0';
			if(strm[i]>='A'&&strm[i]<='Z') shum[i]=strm[i]-'A'+10;
		}
		j=0;
		while(1)
		{
			k=0;
			for(i=0;i<strlen(strm)-1;i++)
			{
				if(shum[i]!=0) k=1;
				jin=shum[i]%n;shum[i+1]+=jin*m;shum[i]/=n; 
			}
			jin=shum[i]%n;shum[i]/=n;if(shum[i]!=0) k=1;
			shun[j++]=jin; 
			if(!k) break;
		}
		for(j=999;j>=0;j--) if(shun[j]) break;
		if(j>=0) while(j>=0) 
		{
			if(shun[j]<10)
			printf("%d",shun[j]);
			else printf("%c",shun[j]-10+'a');
			j--;
		}
		else printf("0");
		printf("\n"); 
	}
	return 0;
} 
//数组开得大一点,有大数据

发表于 2016-01-24 11:20:34 回复(1)
默默~
发表于 2017-01-24 18:39:13 回复(0)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;

const int maxM = 36;    // 最大进制数 '0'-'9' + 'a'-'z' 共 36 种
const int maxn = 10000;

int M = 2;      // 原始进制
int N = 2;      // 目标进制

string str;     // 存储输入

// 所有数组 0 号元素均表示数组长度
int dr[maxn];       // 存储由字符串转过来的大数
int drans[maxn];    // 求余过程中的商
int drres[maxn];    // 余数

map<char, int> mci; // 字符与数字对应的map
map<int, char> mic; // 数字与字符对应的map

// 字符与数值对应map初始化
void initialization()
{
    // 字符与数字对应的map构建
    for(int i = 0; i < maxM; ++i)
    {
        if(i < 10)
        {
            // '0' - '9'
            mci['0'+i] = i;
            mic[i] = '0'+i;
        }
        else
        {
            // 'a' - 'z'
            mci['a'+i-10] = i;
            mic[i] = 'a'+i-10;
        }
    }
}

// 判断是否是大写字母
int isCapital(char ch)
{
    if(ch >= 'A' && ch <= 'Z')
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

// 字符串预处理,并给存储原始进制的数组赋值
void pretreatment()
{
    // 将所有大写字母转换成小写
    for(int i = 0; i < str.length(); ++i)
    {
        // 大写字母转小写
        if(isCapital(str[i]) == 1)
        {
            str[i] = 'a' + str[i] - 'A';
        }
    }
    // 给存储原始进制的数组赋值
    memset(dr, 0, sizeof(dr));
    for(int i = 0; i < str.length(); ++i)
    {
        dr[++dr[0]] = mci[str[i]];
    }
}

// 将 M 进制的 dr 转换成 N 进制
void solve()
{
    memset(drres, 0, sizeof(drres));

    int i, j, y;

    // 模 n 取余法,(总体规律是先余为低位,后余为高位)
    while(dr[0] >= 1)
    {
        // 只要被除数仍然 >= 1,则继续操作
        y = 0;
        i = 1;
        drans[0] = dr[0];       // 商的长度与被除数相同(包含前导0)
        while(i <= dr[0])
        {
            y = y * M + dr[i];
            drans[i++] = y / N;
            y %= N;
        }
        drres[++drres[0]] = y;  // 本轮计算得到的余数
        i = 1;
        // 找到下一轮商的起始位置
        while((i<=drans[0]) && (drans[i] == 0)) ++i;
        // 清除这一轮使用的被除数
        memset(dr, 0, sizeof(dr));
        // 本轮得到的商为下一轮的被除数
        for(j = i; j <= drans[0]; ++j)
        {
            dr[++dr[0]] = drans[j];
        }
        // 清除本轮的商
        memset(drans, 0, sizeof(drans));
    }
}

// 输出 N 进制的结果
void output()
{
    for(int i = drres[0]; i >= 1; --i)
    {
        cout << mic[drres[i]];
    }
}

int main()
{
    
    initialization();   // 字符与数值对应的map的构建
    while(cin >> M >> N)
    {
        cin >> str;
        pretreatment();     // 预处理字符串,并给存储原始进制的数组赋值
        solve();            // 将 M 进制的 dr 转换成 N 进制
        output();           // 输出 N 进制的结果
        cout << endl;
    }

    return 0;
}


发表于 2016-08-05 10:03:53 回复(2)
#include <stdio.h>
#include <string.h>
using namespace std;

int main(){
    char str[31];
    int  num[31];
    int res[2000];

while(scanf("%s",str)!=EOF){  //字符串转数字
    for(int i=0;i<strlen(str);i++)
        num[i]=str[i]-'0';

int size=strlen(str);
int index=0;//结果数组游标

for(int i=0;i<size;){ //控制被除数开始位置
    int temp=0,remain=0;//余数
    for(int j=i;j<size;j++){ //控制除法运算,竖式除法,从头往后每一位依次作除法
        temp=(10*remain+num[j])%2;
        num[j]=(10*remain+num[j])/2;
        remain=temp;
    }
    res[index]=remain;
    index++;
    while(num[i]==0) //从第一个非0开始
        i++;
}

        for(int i=index-1;i>=0;i--) //逆序输出
        {
            printf("%d",res[i]);
        }

            printf("\n");

    }
}

发表于 2019-02-26 12:17:48 回复(5)
import  java.util.*;
import java.math.BigInteger;
public class Main {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        while (in.hasNext()){
            String str=in.nextLine();
            BigInteger a=new BigInteger(str,10);
            System.out.println(a.toString(2));
        }

    }

发表于 2018-04-07 14:18:49 回复(3)
/* 这道题用python或者java很简单其实
 * 但一般机试都是c/cpp哈,所以还是用了cpp
 * 十进制到二进制这个就太简单了,涉及到的主要知识点就是大数除法
 * 大数除法其实就是模拟我们小学学的除法
 * 思路在下面注释里具体说明
 */

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>

using namespace std;

void trip0(string &s) {                             /* 去除字符串首的零 */
    while (!s.empty() && s[0] == '0')
        s.erase(s.begin());
}

string div_two(string s) {                          /* 大数除法 */
    string ans;
    int plus = 0;                                   /* 这个是前一个数除后的余数 */
    for (int i = 0; i < s.length(); i++) {
        int now = plus * 10 + (s[i] - '0');         /* 当前的被除数转化成整数要加上前面的余数*10 */
        if (now >= 2) {                             /* 如果当前被除数>=2的话,会留下余数 */
            ans.push_back(char(now / 2 + '0'));     /* 得到的商 */
            plus = now % 2;                         /* 当前被除数除后的余数 */
        } else {                                    /* 当前被除数小于2的话呢,商就是零,余数是本身 */
            ans.push_back('0');
            plus = now;
        }
    }
    trip0(ans);                                     /* 去掉前导零,例如123/2,得到的是066 */
    return ans;
}

int main() {
    string temp;
    while (cin >> temp) {
        string ans;
        trip0(temp);
        while (!temp.empty() && temp != "0") {
            int rail = (*(temp.end() - 1) - '0') % 2;
            ans.push_back(char(rail + '0'));
            temp = div_two(temp);
        }
        reverse(ans.begin(), ans.end());
        if (!ans.empty()) cout << ans << endl;
        else printf("0\n");
    }
    return 0;
}

发表于 2018-04-22 20:52:03 回复(2)