十六進制轉八進制

時間限制:1.0s   內存限制:512.0MB
問題描述
  給定n個十六進制正整數,輸出它們對應的八進制數。
輸入格式
  輸入的第一行爲一個正整數n (1<=n<=10)。
  接下來n行,每行一個由0~9、大寫字母A~F組成的字符串,表示要轉換的十六進制正整數,每個十六進制數長度不超過100000。
輸出格式
  輸出n行,每行爲輸入對應的八進制正整數。
注意
  輸入的十六進制數不會有前導0,比如012A。
  輸出的八進制數也不能有前導0。
樣例輸入
2
39
123ABC
樣例輸出
71
4435274

分析:該題的大致思路就是把十六進制轉化成二進制,再把二進制轉化爲八進制。
     十六進制轉二進制:將十六進制每一位變成四位的二進制,可用歐幾里得算法;
     二進制轉八進制:將二進制每三位變成八進制的一位。

接下來就是數據量的問題:
十六進制數據的最大長度爲100000位,即最大數爲FFFFFF=1118480(十進制)<20147483648(整數類型可以表示的最大值),也就是可以用整型表示數據,但是算法設計不當可能會出現超時或者超內存。

方法一:省內存,花時間。
使用字符串存儲十六進制數,使用整數類型存儲二進制和八進制數。

<span style="font-size:14px;">#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
int main()
{
    vector<int> v;//存放二進制
    vector<int> vv;//存放八進制
    string s;
    int n;
    int m,t;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            v.clear();
            vv.clear();
            cin>>s;
            reverse(s.begin(),s.end());
            for(int j=0;j<s.size();j++)
            {
                if(s[j]=='0') m=0;
                else if(s[j]=='1')  m=1;  else if(s[j]=='2')  m=2; else if(s[j]=='3')   m=3;
                else if(s[j]=='4')  m=4;  else if(s[j]=='5')  m=5; else if(s[j]=='6')   m=6;
                else if(s[j]=='7')  m=7;  else if(s[j]=='8')  m=8; else if(s[j]=='9')   m=9;
                else if(s[j]=='A')  m=10; else if(s[j]=='B')  m=11; else if(s[j]=='C')  m=12;
                else if(s[j]=='D')  m=13; else if(s[j]=='E')  m=14;  else if(s[j]=='F') m=15;
                for(int k=0;k<4;k++)//十六進制轉二進制
                {
                    t=m%2;
                    m=m/2;
                    v.push_back(t);
                }
            }
            //因爲要轉換爲八進制,所以總位數應是3的倍數,不是則給高位補零
            if(v.size()%3==2) v.push_back(0);
            else if(v.size()%3==1)
            {
                v.push_back(0);
                v.push_back(0);
            }
            m=0;
            for(int j=0;j<v.size();j++)//二進制轉八進制
            {
                m+=v[j]*pow(2,j%3);
                if(j%3==2)
                {
                    vv.push_back(m);
                    m=0;
                }
            }
            reverse(vv.begin(),vv.end());
            for(int j=0;j<vv.size();j++)
            {
                if(j==0&&vv[j]==0) continue;//不輸出最高位上的零
                else cout<<vv[j];
            }
            if(i!=n-1) cout<<endl;
        }
    }
}
</span>

方法二:省時間,花內存
使用字符串存儲各種進制的數據,要聲明一個大於等於10000001的整型數組
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int arr[10000001]; // 記錄八進制的數

int main()
{
  string str;
  int n,m,i,num,j;
  
  cin>>n;
  while(n--)
  {
    cin>>str;
    m=str.length();
    // 轉換成十進制
    num=0;
    for(i=m-1;i>=0;--i)
    {
      if(str[i]>='0'&&str[i]<='9')
        num+=pow(16,m-1-i)*(str[i]-'0');
      else if(str[i]>='A'&&str[i]<='F')
        num+=pow(16,m-1-i)*(str[i]-'A'+10);
    }
    
    i=0;
    while(num/8!=0)
    {
      arr[i]=num%8;
      num/=8;
      ++i;
    }
    arr[i]=num;

    for(j=i;j>=0;--j)
      cout<<arr[j];
    cout<<endl;

  }
  return 0;
}



發佈了55 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章