蓝桥杯 试题 基础练习 十六进制转八进制

本文介绍了如何使用C++编程语言,利用map容器和字符串操作将给定的十六进制数转换为八进制数,通过`BinaryTOOctal`和`hexToBinary`映射表辅助转换过程。同时,注意了C++98模式下map的初始化方式和字符串处理技巧。
摘要由CSDN通过智能技术生成

蓝桥杯 试题 基础练习 十六进制转八进制

1.0 问题描述

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

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

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

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

1.3 样例输入
2
39
123ABC

1.4 样例输出
71
4435274

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

2.0 数据结构

2.1. string 容器

要准确地理解string容器,这样做起来会更得心应手。

这个题目中,我用string来存放输入的十六进制数str16、中间结果二进制数str2和最后结果八进制数str8。因为string方便实现手算步骤。

  1. 逐个逐个取str16中的字符,并转化为二进制数(也是字符串),并且直接拼接到str2中。
  2. str2拼接完成后,检查str2的length是否为3的倍数,如果不是直接在str2的begin处添加字符‘0’。
  3. 然后三个三个地取str2上的字符串,并转化为八进制数(也是字符串),并且直接拼接到str8.
  4. str8拼接完成后,检查str8的首部(即str[0])是否是 ‘0’ ,如果是就把 ‘0’ erase掉。
  5. 最后cout<<str8<<endl;即可

2.1.1 string 和 char*的区别

  • char * 是一个指针
  • string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器

2.1.2 string的好用之处

  • string 类内部封装了很多成员方法
    • 例如:查找find,拷贝copy,删除delete 替换replace,插入insert
  • string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责

2.1.3 string的存取

string中单个字符存取方式有两种

  • char& operator[](int n); //通过[]方式取字符
  • char& at(int n); //通过at方法获取字符

2.1.4 string字符串拼接字符串

功能描述:
实现在字符串末尾拼接字符串
函数原型:

  • string& operator+=(const char* str); //重载+=操作符(字符数组的指针)
  • string& operator+=(const char c); //重载+=操作符(单个字符)
  • string& operator+=(const string& str); //重载+=操作符(string字符串)
  • string& append(const char *s); //把字符串s连接到当前字符串结尾(字符数组的指针)
  • string& append(const char *s, int n); //把字符串s的前n个字符连接到当前字符串结尾(字符数组的指针,数量)
  • string& append(const string &s); //同operator+=(const string& str)(string字符串)
  • string& append(const string &s, int pos, int n);//字符串s中从pos开始的n个字符连接到字符串结尾(string字符串,开始位置,数量)

简单来说:
string可以通过简单的“加法”把字符串或字符拼接到末尾,
或者通过
append
指定string字符串的具体的子串拼接到末尾。

2.1.5 string插入和删除字符

对string字符串进行插入(insert)和删除(erase字符操作

函数原型:

  • string& insert(int pos, const char* s); //插入字符串
  • string& insert(int pos, const string& str); //插入字符串
  • string& insert(int pos, int n, char c); //在指定位置插入n个字符c
  • string& erase(int pos, int n = npos); //删除从Pos开始的n个字符

2.1.6 string的子串

从字符串中获取想要的子串
函数原型:
string substr(int pos = 0, int n = npos) const; //返回由pos开始的n个字符组成的字符串

2.2 map容器

  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序

优点:
可以根据key值快速找到value值。

map<string,char> BinaryTOOctal={    /* 用键对实现二进制转化为十进制*/
        {"000",'0'},{"001",'1'},{"010",'2'},
        {"011",'3'},{"100",'4'},{"101",'5'},
        {"110",'6'},{"111",'7'}
 };
map<char,string> hexToBinary ={
        {'0',"0000"},{'1',"0001"},{'2',"0010"},{'3',"0011"},
        {'4',"0100"}, {'5',"0101"},{'6',"0110"},{'7',"0111"},
        {'8',"1000"}, {'9',"1001"},{'A',"1010"},{'B',"1011"},
        {'C',"1100"},{'D',"1101"},{'E',"1110"},{'F',"1111"}
 };

注意字符要用单引号,字符串要用双引号。

3.0 代码实现

# include <iostream>
# include <string>
# include <map>
using namespace std;
map<string,char> BinaryTOOctal={    /* 用键对实现二进制转化为十进制*/
        {"000",'0'},{"001",'1'},{"010",'2'},
        {"011",'3'},{"100",'4'},{"101",'5'},
        {"110",'6'},{"111",'7'}
    };
map<char,string> hexToBinary ={
        {'0',"0000"},{'1',"0001"},{'2',"0010"},{'3',"0011"},{'4',"0100"},
        {'5',"0101"},{'6',"0110"},{'7',"0111"},{'8',"1000"},{'9',"1001"},
        {'A',"1010"},{'B',"1011"},{'C',"1100"},
        {'D',"1101"},{'E',"1110"},{'F',"1111"}
    };
int main()
{
    int n;cin>>n;
    for(int i=0;i<n;i++)
    {
        string str16;
        cin>>str16;
        string str2;
        string str8;
        /*16进制转化为2进制*/
        for(char c:str16)
        {
            str2+=hexToBinary[c];   /* 字符串加字符串 */
        }
        /*2进制转化为8进制*/
        while(str2.size()%3!=0) /* 补充0*/
        {
            str2.insert(str2.begin(),'0');    /* 字符串加字符,字符要用单引号 */
        }
        for(size_t j=0;j<str2.size();j+=3)
        {
            string sub = str2.substr(j,3);
            str8+=BinaryTOOctal[sub];
        }
        while(str8[0]=='0')
        {
            str8.erase(0,1);
        }
        cout<<str8<<endl;
    }
}

提交到蓝桥杯的练习系统之后,有很多报错。

Main.cpp:9:5: error: in C++98 'BinaryTOOctal' must be initialized by constructor, not by '{...}'
     };
     ^
Main.cpp: In substitution of 'template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator, const _Compare&, const allocator_type&) [with _InputIterator = <missing>]':
Main.cpp:9:5:   required from here
Main.cpp:9:5: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
Main.cpp:9:5: error: could not convert '{{"000", '0'}, {"001", '1'}, {"010", '2'}, {"011", '3'}, {"100", '4'}, {"101", '5'}, {"110", '6'}, {"111", '7'}}' from '<brace-enclosed initializer list>' to 'std::map<std::basic_string<char>, char>'
Main.cpp:15:5: error: in C++98 'hexToBinary' must be initialized by constructor, not by '{...}'
     };
     ^
Main.cpp: In substitution of 'template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator, const _Compare&, const allocator_type&) [with _InputIterator = <missing>]':
Main.cpp:15:5:   required from here
Main.cpp:15:5: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
Main.cpp:15:5: error: could not convert '{{'0', "0000"}, {'1', "0001"}, {'2', "0010"}, {'3', "0011"}, {'4', "0100"}, {'5', "0101"}, {'6', "0110"}, {'7', "0111"}, {'8', "1000"}, {'9', "1001"}, {'A', "1010"}, {'B', "1011"}, {'C', "1100"}, {'D', "1101"}, {'E', "1110"}, {'F', "1111"}}' from '<brace-enclosed initializer list>' to 'std::map<char, std::basic_string<char> >'
Main.cpp: In function 'int main()':
Main.cpp:26:20: error: range-based 'for' loops are not allowed in C++98 mode
         for(char c:str16)

错误提示中提到:

  • 你的代码处于 C++98 模式
    • 不能使用 {} 来初始化 map ,需要使用构造函数。在这种情况下,我们需要在初始化 map 时使用 make_pair 或者 std::pair。
    • 不能以使用扩展的初始化列表和范围for循环。

修改后实现代码如下:

# include <iostream>
# include <string>
# include <map>
using namespace std;

int main()
{
    // 初始化 BinaryTOOctal map
    map<string, char> BinaryTOOctal;
    BinaryTOOctal.insert(make_pair("000", '0'));
    BinaryTOOctal.insert(make_pair("001", '1'));
    BinaryTOOctal.insert(make_pair("010", '2'));
    BinaryTOOctal.insert(make_pair("011", '3'));
    BinaryTOOctal.insert(make_pair("100", '4'));
    BinaryTOOctal.insert(make_pair("101", '5'));
    BinaryTOOctal.insert(make_pair("110", '6'));
    BinaryTOOctal.insert(make_pair("111", '7'));

    // 初始化 hexToBinary map
    map<char, string> hexToBinary;
    hexToBinary.insert(make_pair('0', "0000"));
    hexToBinary.insert(make_pair('1', "0001"));
    hexToBinary.insert(make_pair('2', "0010"));
    hexToBinary.insert(make_pair('3', "0011"));
    hexToBinary.insert(make_pair('4', "0100"));
    hexToBinary.insert(make_pair('5', "0101"));
    hexToBinary.insert(make_pair('6', "0110"));
    hexToBinary.insert(make_pair('7', "0111"));
    hexToBinary.insert(make_pair('8', "1000"));
    hexToBinary.insert(make_pair('9', "1001"));
    hexToBinary.insert(make_pair('A', "1010"));
    hexToBinary.insert(make_pair('B', "1011"));
    hexToBinary.insert(make_pair('C', "1100"));
    hexToBinary.insert(make_pair('D', "1101"));
    hexToBinary.insert(make_pair('E', "1110"));
    hexToBinary.insert(make_pair('F', "1111"));


    int n;cin>>n;
    for(int i=0;i<n;i++)
    {
        string str16;	/* 存放16进制数 */
        cin>>str16;
        string str2;	/* 存放2进制数 */
        string str8;	/* 存放8进制数 */
        
        /* 16进制转化为2进制 */
        for(size_t j=0;j<str16.length();j++)
        {
            str2+=hexToBinary[str16[j]];   /* 字符串加字符串 */
        }
        
        /* 2进制转化为8进制 */
        while(str2.size()%3!=0) 	/* 补充0*/
        {
            str2.insert(str2.begin(),'0');    /* 字符串加字符,字符要用单引号 */
        }
        for(size_t j=0;j<str2.size();j+=3)
        {
            string sub = str2.substr(j,3);
            str8+=BinaryTOOctal[sub];			/* 字符串加字符串 */
        }
        while(str8[0]=='0')		/* 去掉前导0 */
        {
            str8.erase(0,1);
        }
        cout<<str8<<endl;		/* 输出转换结果 */
    }
}

在这里插入图片描述

有更好的方法的话,欢迎在评论区分享!!!!

  • 32
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值