十六进制转八进制 10万位输入数据

问题描述

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

输入格式

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

输出格式

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

题目分析:
注意到输入数据巨大(100000),不能直接使用系统类型进行存储转换。我们考虑先将16进制转2进制,然后将2进制转8进制。
16进制转2进制是每个数字或字母对应4个2进制位,2进制转8进制是3个进制位转1一个进制位。
代码及注释:

#include <bits/stdc++.h>
using namespace std;
char c[11][100040];//存输入
string b[11];//由于单个string近乎可以无限存储,所以可以采用string数组存储数据
string g[17] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000",
                "1001", "1010", "1011", "1100", "1101", "1110", "1111"
               };//此数组作为字典用来查询16进制对应的二进制数字
int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> c[i];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; c[i][j] != '\0'; ++j) {
			if (c[i][j] >= '0' && c[i][j] <= '9') {
				b[i] += g[c[i][j] - '0'];//如果是数字就填入二进制数字
			} else {
				b[i] += g[c[i][j] - 'A' + 10];//字母
			}
		}
	}
	string::iterator it; //指向string类的迭代器。你可以理解为指针
	for (int i = 0; i < n; i++) {
		for (it = b[i].begin(); *it != '1';) {
			if (*it == '0') {
				b[i].erase(it); //去除前面的0,注意erase之后it会自动指向下一位所以不用it++
			}
		}
		//cout << b[i] << endl;
	}

	for (int i = 0; i < n; i++) {
		int len = b[i].length();
		int k = len % 3;//取数字要从个位三个三个取,最大位不一定能取三个
		int t = 0;
		int p = 0;
		for (int j = 0; j < len;) {
			//处理一行数 3个一位
			if (j == 0&&k!=0) {//如果最大位不能取三个
				for (p = 0; p < k; p++) {
					t = 2 * t + b[i][p]-'0';//取k位
				}
				cout << t;//取了就输出
				j += k;//后移k位
				continue;
			}
			for (p = j, t = 0; p < j + 3; p++) {
				t = 2 * t + b[i][p]-'0';
			}
			cout << t;
			j += 3;

		}
		cout << endl;
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值