蓝桥杯 试题 基础练习 十六进制转八进制
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方便实现手算步骤。
- 逐个逐个取str16中的字符,并转化为二进制数(也是字符串),并且直接拼接到str2中。
- str2拼接完成后,检查str2的length是否为3的倍数,如果不是直接在str2的begin处添加字符‘0’。
- 然后三个三个地取str2上的字符串,并转化为八进制数(也是字符串),并且直接拼接到str8.
- str8拼接完成后,检查str8的首部(即str[0])是否是 ‘0’ ,如果是就把 ‘0’ erase掉。
- 最后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个字符cstring& 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; /* 输出转换结果 */
}
}