zoukankan      html  css  js  c++  java
  • 蓝桥杯基础 进制转换问题

    问题描述

      给定n个十六进制正整数,输出它们对应的八进制数。

    输入格式
      输入的第一行为一个正整数n (1<=n<=10)。
      接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

    输出格式
      输出n行,每行为输入对应的八进制正整数。

      【注意
      输入的十六进制数不会有前导0,比如012A。
      输出的八进制数也不能有前导0。

    样例输入
      2
      39
      123ABC

    样例输出
      71
      4435274

      提示
      先将十六进制数转换成某进制数,再由某进制数转换成八进制。

    ---初看这道题,想的就是把十六进制数转成十进制数,再转回成八进制就好,事实证明我错了....它要求的数据规模是不大于100000,显然转成十进制是不妥当的。

    先把用十进制转的错误思想代码贴在这里。

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<math.h>
     4 #include<string>
     5 using namespace std;
     6 char str[100000];
     7 int  eight[100000];
     8 int main()
     9 {
    10     int i,j;
    11     int n;
    12     scanf("%d",&n);
    13     int num;
    14     while(n--)
    15     {
    16         num=0;
    17         scanf("%s",&str);
    18         int len=strlen(str);
    19         //十六进制转十进制
    20         for(i=len-1;i>=0;i--)
    21         {
    22             if(str[i]>='0'&&str[i]<='9')
    23             num+=pow(16,len-1-i)*(str[i]-'0');
    24             else if(str[i]>='A'&&str[i]<='F')
    25             num+=pow(16,len-1-i)*(str[i]-'A'+10);
    26         }
    27         
    28         //printf("%d
    ",num);
    29         //十进制转八进制
    30         i=0;
    31         while((num/8)!=0)
    32         {
    33             eight[i]=num%8;
    34             num=num/8;
    35             i++;
    36         }
    37         eight[i]=num;//否则最后一次存入数据会丢失(首位丢失)
    38         for(int j=i;j>=0;j--)
    39         {
    40             printf("%d",eight[j]);
    41         }
    42 }
    43 
    44         return 0;
    45 }

    总结网上各路大神的代码,大概有一下思路:

    1.直接映射的,所有的过程都是以字符串形式的。每个16进制数(字符串形式)转成4位二进制数(字符串形式)。第二第三行在内存上是一样的,只是在读取的时候第二行是从右往左每4位是一起是一个16进制数;而第三行在读取得时候是从右往左每三位是一个8进制数。第二行(在内存上也是第三行)也是每一位是一个字符存储起来的字符串。

     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 int arr[10000001];
     5 
     6 int main()
     7 {
     8     int n,len_str,i,j;
     9     string str,str2;
    10     cin>>n;
    11     while(n--)
    12     {
    13         cin>>str;
    14         len_str=str.length();
    15         str2="";
    16 
    17         // 十六进制转换为二进制
    18         for(i=0;i<len_str;++i)
    19         {
    20             switch(str[i])
    21             {
    22             case '0':str2+="0000";break;
    23             case '1':str2+="0001";break;
    24             case '2':str2+="0010";break;
    25             case '3':str2+="0011";break;
    26             case '4':str2+="0100";break;
    27             case '5':str2+="0101";break;
    28             case '6':str2+="0110";break;
    29             case '7':str2+="0111";break;
    30             case '8':str2+="1000";break;
    31             case '9':str2+="1001";break;
    32             case 'A':str2+="1010";break;
    33             case 'B':str2+="1011";break;
    34             case 'C':str2+="1100";break;
    35             case 'D':str2+="1101";break;
    36             case 'E':str2+="1110";break;
    37             case 'F':str2+="1111";break;
    38             default:break;
    39             }
    40         }
    41         
    42         // 修正位数
    43         if(len_str%3==1)    str2="00"+str2;
    44         
    45         else if(len_str%3==2)    str2="0"+str2;
    46 
    47         
    48         len_str=str2.length();
    49         // 二进制转换八进制
    50         j=0;
    51         for(i=0;i<=len_str-2;i+=3)
    52         {
    53             arr[j]=(str2[i]-'0')*4+(str2[i+1]-'0')*2+(str2[i+2]-'0');
    54             ++j;
    55         }
    56 
    57         for(i=0;i<j;++i)
    58         {
    59             if(i==0 && arr[i]==0)    continue;
    60             cout<<arr[i];
    61         }
    62         cout<<endl;
    63 
    64     }
    65     return 0;
    66 }

    但是这样的实现确实麻烦,关键是二进制字符串占用内存很大,switch映射还要考虑补位,因为假设原来的十六进制数时14位,那么前12位是48位二进制数,也就是16个8进制数,但是剩下的两个十六进制数是8位二进制数,要变成8进制数要补一个二进制位(在字符串前面加个'0'),这种就是补位。

    有没有更好的实现方法呢?见博客http://blog.csdn.net/qsyzb/article/details/18891219

  • 相关阅读:
    移动端的爬坑路
    判断设备ios或android以及判断是否是微信内置浏览器
    使用vue directive 写好的滑动删除功能
    不用ajax,使用json数据渲染商品的方法
    vue中使用swiper的一些坑
    vue的自定义指令的坑
    better-score获取滑动距离的坑
    linux命令
    关于打印
    数据可视化
  • 原文地址:https://www.cnblogs.com/curo0119/p/8304880.html
Copyright © 2011-2022 走看看