进制转化问题

花费了很多时间,终于弄懂了进制转化问题
大概可以将进制转化分成五类:

  • 第一类:二进制,八进制,十六进制转化为十进制
    方法:按权展开
    for example:二进制转化为十进制:101=1*2^2+0*2^1+1*2^0
    八进制转化为十进制:432=4*8^2+3*8^1+2*8^0
    十六进制转化为十进制:AB=A*16^1+B*16^0
  • 第二类:十进制转化为二进制,八进制和十六进制
    方法:短除法
    这里就不举例子了,只需要知道转二进制是除以2,转八进制除以8,转十六进制除以16,最后逆序输出即可。
  • 第三类:二进制转化为八进制,十六进制
    方法:三位二进制对应一位八进制,四位二进制对应一位十六进制,不足时补零(注意:三位对应一位或者四位对应一位是从右向左看,所以补零应该在左边)
    for example:转八进制:1110=1*2^0|1*2^2+1*2^1=16
    转十六进制:1110=1*2^3+1*2^2+1*2^1+0*2^0=E
  • 第四类:八进制,十六进制转化为二进制
    方法:短除法
    八进制转化为二进制,要除以2,一位八进制对应三位二进制,不足时补零。
    十六进制转化为二进制,也是除以2,一位十六进制对应四位二进制,不足时补零。
  • 第五类:八进制与十六进制转化
    方法:先转化为二进制,再由二进制转化为另一进制即可
    说白了,关键就是二进制和十进制,进制转化大多在这两个的基础上,特殊的也就是十六进制与八进制的转化

下面举几个例题

  • 十六进制转化为八进制
#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
int main()
{
 int n;
 cin>>n;
 string sixteen[11];
 int i;
 for(i=0;i<n;i++)
  cin>>sixteen[i];
 for(i=0;i<n;i++)
 {
  string two,eight;
  char e;
  int j;
  for(j=0;j<sixteen[i].length();j++)
   {
    switch(sixteen[i][j])
    {
     case '0':two+="0000";break;
     case '1':two+="0001";break;
     case '2':two+="0010";break;
     case '3':two+="0011";break;
     case '4':two+="0100";break;
     case '5':two+="0101";break;
     case '6':two+="0110";break;
     case '7':two+="0111";break;
     case '8':two+="1000";break;
     case '9':two+="1001";break;
     case 'A':two+="1010";break;
     case 'B':two+="1011";break;
     case 'C':two+="1100";break;
     case 'D':two+="1101";break;
     case 'E':two+="1110";break;
     case 'F':two+="1111";break;
     default:break;
    }
   }
  int len=two.length()%3;
  if(len==1)
   two.insert(0,"00");
  if(len==2)
   two.insert(0,"0");
  if(!(two[0]=='0'&&two[1]=='0'&&two[2]=='0'))
   {
    e=(two[0]-'0')*2*2+(two[1]-'0')*2+(two[2]);
    eight=eight+e;
   }
  int k;
  for(k=3;k<two.length();k=k+3)
  {
   if(two.substr(k,3)=="000") eight=eight+"0";
   else if(two.substr(k,3)=="001") eight=eight+"1";
   else if(two.substr(k,3)=="010") eight=eight+"2";
   else if(two.substr(k,3)=="011") eight=eight+"3";
   else if(two.substr(k,3)=="100") eight=eight+"4";
   else if(two.substr(k,3)=="101") eight=eight+"5";
   else if(two.substr(k,3)=="110") eight=eight+"6";
   else if(two.substr(k,3)=="111") eight=eight+"7";
  }
  cout<<eight<<endl;
 }
 return 0;
 } 

本题涉及的字符串操作:
1.sixteen.length(); 获取字符串的长度
2.two.insert(插入位置,插入的字符串); 向指定位置插入
3.two.substr(substr(字符串,截取开始位置,截取长度) //返回截取的字
给出相关的例子便于理解
substr(‘Hello World’,0,1) //返回结果为 ‘H’ *从字符串第一个字符开始截取长度为1的字符串
substr(‘Hello World’,1,1) //返回结果为 ‘H’ *0和1都是表示截取的开始位置为第一个字符
substr(‘Hello World’,2,4) //返回结果为 ‘ello’
substr(‘Hello World’,-3,3)//返回结果为 ‘rld’ *负数(-i)表示截取的开始位置为字符串右端向左数第i个字符)

  • 十六进制转化为十进制(当然可以先让十六进制转化为二进制,然后二进制转化为十进制,代码与上题类似,这里列举另一种方法)
    先文字说明一下怎么转化:
    2AF5=5 * 16^0 + F * 16^1 + A * 16^2 + 2 * 16^3 = 10997
#include<iostream>
#include<string>
#include<math.h>
using namespace std;
int main()
{
 string sixteen;
 unsigned long long ten=0;
 cin>>sixteen;
 int i;
 for(i=0;i<sixteen.length();i++)
 {
  switch(sixteen[i])
  {
   case '0':ten=ten+0*pow(16,sixteen.length()-1-i);break;
   case '1':ten=ten+1*pow(16,sixteen.length()-1-i);break;
   case '2':ten=ten+2*pow(16,sixteen.length()-1-i);break;
   case '3':ten=ten+3*pow(16,sixteen.length()-1-i);break;
   case '4':ten=ten+4*pow(16,sixteen.length()-1-i);break;
   case '5':ten=ten+5*pow(16,sixteen.length()-1-i);break;
   case '6':ten=ten+6*pow(16,sixteen.length()-1-i);break;
   case '7':ten=ten+7*pow(16,sixteen.length()-1-i);break;
   case '8':ten=ten+8*pow(16,sixteen.length()-1-i);break;
   case '9':ten=ten+9*pow(16,sixteen.length()-1-i);break;
   case 'A':ten=ten+10*pow(16,sixteen.length()-1-i);break;
   case 'B':ten=ten+11*pow(16,sixteen.length()-1-i);break;
   case 'C':ten=ten+12*pow(16,sixteen.length()-1-i);break;
   case 'D':ten=ten+13*pow(16,sixteen.length()-1-i);break;
   case 'E':ten=ten+14*pow(16,sixteen.length()-1-i);break;
   case 'F':ten=ten+15*pow(16,sixteen.length()-1-i);break;
  }
 }
 cout<<ten<<endl;
 return 0; 
}

ps:pow()函数:
头文件要求include<math.h>
pow(x,y):x的y次

  • 十进制转化十六进制
#include<iostream>
#include<string>
#include<stack>
using namespace std;
stack<char> s;
char fun(int x)
{
 switch(x)
 {
  case 0:return '0';break;
  case 1:return '1';break;
  case 2:return '2';break;
  case 3:return '3';break;
  case 4:return '4';break;
  case 5:return '5';break;
  case 6:return '6';break;
  case 7:return '7';break;
  case 8:return '8';break;
  case 9:return '9';break;
  case 10:return 'A';break;
  case 11:return 'B';break;
  case 12:return 'C';break;
  case 13:return 'D';break;
  case 14:return 'E';break;
  case 15:return 'F';break;
 }
}
int main()
{
 long long ten;
 cin>>ten;
 long long m,n,k,r;
 char ch;
 int count=0;
 m=ten;
 n=16;
 while(m)
 {
  r=m%n;
  k=m/n;
  ch=fun(r);
  s.push(ch);
  m=k;
  count=1;
 }
 if(count==1)
 {
 while(!s.empty())
 {
  cout<<s.top();
  s.pop();
 }
 }
 else
 cout<<"0"<<endl;
 return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值