// 进制转换 ------------------------------------------
---代码1---
// 将10进制的数字N的每位转换为D(任意)进制存到数组number[],即:'除基(D)求余(D)'得到每位然后存到数组。《3.5》
// 为什么输入的必须是10进制(或问只被计算机认为是10进制呢),因为'除基求余法'基于'多项式求和',所有的任意进制分解都是以它为和进行的。(纯属XB~)
int len = 0;
do{ // 0
number[len++] = N % D; //数组0号下标存个位数字
N /= D;
} while(N != 0); //注:结束时N为0
// 例如: input:N=(10进制数字)123,D=8
// output:(8进制数字)371(即:173)
---代码2---
// 当上面代码的D=10时,又多了一个新功能:取原数的每位存到数组number[]
int len = 0;
do{ // 0
number[len++] = N % 10; //数组0号下标存个位数字
N /= 10;
} while(N != 0); //注:结束时N为0
---代码3---
// 以下代码可以理解为上面代码的增加* product后的新增功能,但不无完全是,因为:强行指定了:p进制:product*=p,而不是上述的10进制了
// p(强行指定:product*=p,而不是上述的10进制了)进制x(直接)转为十进制y(不满足任意进制,Only:10进制),即:'除基(10)求余(10)'得到每位然后乘以对应的权值(p的n次方)(实质即:以p为基数的多项式求和)。《3.5》
// 与秦九韶公式的区别:不需要数组; 从低位开始,而秦九韶从高位开始。
int y = 0, product = 1;
while(x != 0) { //for循环不如while,for循环需要先知道位数,while循环的条件只是'x!=0',且可以顺便求位数
y += (x % 10) * product; //初始时从个位开始
x /= 10; //x指向高一位
product *= p; //product加权
}
---代码4---
// 得到number[]的情况下用秦九韶公式计算多项式和(因为秦九韶需要数组),进制(基数)为D
int N = 0; //括号内的是N,然后N*D
for(int i=len-1; i>0; i--) {
//因为得到的number[]是倒序存的(即:下标由小到大对应数字的由个位到高位),而秦九韶要求从高位开始,所以起始i=len-1
//若number[]本来即为正序的,则起始i=0
N = N * D + number[i];
}
其中:‘代码3’等价于‘代码2+代码4’,但后者实现代码较长、时间复杂度较优(原因在于秦九韶公式求和比一般的多项式累加求和的计算次数要少)。
8进制 >>>(代码3 或 代码2+代码4)>>> 10进制
10进制 >>>(代码1)>>> 16进制
8进制 >>>(代码3 或 代码2+代码4)>>> 10进制 >>>(代码1)>>> 16进制
但是,用“ 8进制 >>>(代码3 或 代码2+代码4)>>> 10进制 >>>(代码1)>>> 16进制 ”的方式时,对于长数(1000位)溢出。
所以位数长时,用8进制 >>>>>> 2进制 >>>>>> 16进制,例题代码如下:
原题:十六进制转八进制
#include <cstdio>
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
int N;
int main() {
scanf("%d",&N);
for(int i=0; i<N; i++) {
string str1, str2 = ""; //str1存16进制, str2存2进制
cin>>str1;
for(int j=0; j<str1.length(); j++) {
switch(str1[j]) {
case '0' : str2 +="0000"; break; //16进制转2进制
case '1' : str2 +="0001"; break;
case '2' : str2 +="0010"; break;
case '3' : str2 +="0011"; break;
case '4' : str2 +="0100"; break;
case '5' : str2 +="0101"; break;
case '6' : str2 +="0110"; break;
case '7' : str2 +="0111"; break;
case '8' : str2 +="1000"; break;
case '9' : str2 +="1001"; break;
case 'A' : str2 +="1010"; break;
case 'B' : str2 +="1011"; break;
case 'C' : str2 +="1100"; break;
case 'D' : str2 +="1101"; break;
case 'E' : str2 +="1110"; break;
case 'F' : str2 +="1111"; break;
default:break;
}
}
int len2 = str2.length();
if(len2 % 3 == 1) {
str2 = "00" + str2;
} else if(len2 % 3 == 2) {
str2 = "0" + str2;
}
len2 = str2.length();
for(int j=0; j<=len2 - 3; j+=3) { //2进制转8进制
int num = 4 * (str2[j] - '0') + 2 * (str2[j+1] - '0') + (str2[j+2] - '0');
if(num == 0 && j == 0) { //去掉高位无效的零
continue;
}
printf("%d",num);
}
printf("\n");
}
return 0;
}
进制转换
最新推荐文章于 2023-04-22 14:31:06 发布