让N进制数转化为M进制数
1.N进制-10进制-M进制
常规方法可以用短除法取余数再倒序输出的方法来,但这一方法实际上为N进制-10进制-M进制。
2.C++自带函数 strtol()
strtol()
:可以把任一进制的字符串转成long。用法:strtol(字符串,NULL,要转的进制)
,返回值就是结果。
但是把int转成别的进制字符串有些困难,因此需要使用函数把int转化成任一进制的字符串
windows下有个现成的itoa()
函数 用法:itoa(要转的值,字符串,目标进制) itoa(strtol(s,NULL,b),t,m)
Linux下可用to_chars()
函数 用法:to_chars(字符串,字符串尾部指针,要转的值,目标进制)
to_chars(t,t+40,strtol(s,NULL,b),m);
std::to_chars, std::to_chars_result 介绍
还有一个问题,就是这样转出来的字符串是小写的,题目要求是大写。这好像没有现成的函数可以做,需要用<locale>中的toupper
函数
auto& f=use_facet<ctype<char>>(locale());
f.toupper(t,t+40);
P1143 进制转换 - 洛谷
题目描述
请你编一程序实现两种不同进制之间的数据转换。
输入格式
共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A-F表示数码10-15,并且该n进制数对应的十进制的值不超过1000000000,第三行也是一个正整数,表示转换之后的数的进制m(2≤m≤16)。
输出格式
一个正整数,表示转换之后的m进制数。
样例 #1
样例输入 #1
16
FF
2
样例输出 #1
11111111
解法1:
用栈的特性逆顺序输出,也可用递归的方式
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
unsigned long long num = 0;
int n, k;
stack<char>q;
void solve() {
int jinzhi1, jinzhi2;
cin >> jinzhi1;
string str;
cin >> str;
for (int i = 0; i < str.length(); i++) {
num *= jinzhi1;
if (str[i] < 'A') {
num += str[i] - '0';
}
else {
num += 10 + (str[i] - 'A');
}
}
cin >> jinzhi2;
while (num >= jinzhi2) {
if (num % jinzhi2 < 10) {
q.push('0' + num % jinzhi2);
num /= jinzhi2;
}
else {
q.push('A' + (num % jinzhi2 - 10));
num /= jinzhi2;
}
if (num < jinzhi2) {
q.push('0' + num);
}
}
while (!q.empty()) {
cout << q.top();
q.pop();
}
return;
}
int main() {
solve();
return 0;
}
解法2:
用C++自带函数写
*需要了解测评机的运行环境是Windows还是Linux
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int b,m;char s[40],t[40];
int main(){
scanf("%d %s %d",&b,s,&m);
to_chars(t,t+40,strtol(s,NULL,b),m);
//如果把上面一行改成itoa(strtol(s,NULL,b),t,m),应该就能使用Dev-C++,C++11编译通过
auto& f=use_facet<ctype<char>>(locale());
f.toupper(t,t+40);
puts(t);
return 0;
}
负进制数转化
让N进制数转化为M进制数
方法与上面的1相同,转化过程为N进制-10进制-M进制
但区别在于
已知:被除数=商*除数+余数,
例如在C++里,-15%-2=-1,-15/-2=7,而7*-2+(-1)=-15
但是因为我们是不断取余数倒序为转换结果,所以余数不能出现负数,那怎么办呢?
我们只需要将商+1,余数-除数即可,因为余数(绝对值)一定小于除数,所以这样就可以将余数装换为正数
正确性证明:
(商+1)*除数+(余数-除数)=商*除数+除数+余数-除数=商*除数+余数=被除数
参考:题解 P1017 【进制转换】 负进制数_百度百科 (baidu.com)
NOIP2000 提高组 进制转换
题目描述
我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置为指数,以 10 为底数的幂之和的形式。例如 123 可表示为 1 \times 10^2+2\times 10^1+3\times 10^0 这样的形式。
与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置为指数,以 2 为底数的幂之和的形式。
一般说来,任何一个正整数 R 或一个负整数 -R 都可以被选来作为一个数制系统的基数。如果是以 R 或 -R 为基数,则需要用到的数码为 0,1,....R-1。
例如当 R=7 时,所需用到的数码是 0,1,2,3,4,5,6,这与其是 R 或 -R 无关。如果作为基数的数绝对值超过 10,则为了表示这些数码,通常使用英文字母来表示那些大于 9 的数码。例如对 16 进制数来说,用 A 表示 10,用 B 表示 11,用 C 表示 12,以此类推。
在负进制数中是用 -R 作为基数,例如 -15(十进制)相当于 110001 (-2进制),并且它可以被表示为 2 的幂级数的和数:
110001=1\times (-2)^5+1\times (-2)^4+0\times (-2)^3+0\times (-2)^2+0\times (-2)^1 +1\times (-2)^0
设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数。
输入格式
输入的每行有两个输入数据。
第一个是十进制数 n。 第二个是负进制数的基数 -R。
输出格式
输出此负进制数及其基数,若此基数超过 10,则参照 16 进制的方式处理。
样例 #1
样例输入 #1
30000 -2
样例输出 #1
30000=11011010101110000(base-2)
样例 #2
样例输入 #2
-20000 -2
样例输出 #2
-20000=1111011000100000(base-2)
样例 #3
样例输入 #3
28800 -16
样例输出 #3
28800=19180(base-16)
样例 #4
样例输入 #4
-25000 -16
样例输出 #4
-25000=7FB8(base-16)
提示
【数据范围】 对于 100\% 的数据,-20 \le R \le -2,|n| \le 37336。
题解:
还是用了栈来进行倒序输出
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
typedef long long ll;
stack<char>s;
void solve() {
int n, k;
cin >> n >> k;
cout << n<<"=";
while (n!=0) {
int x = n % k;
if (x < 0) {//关键于此
x -= k;
n += k;
}
if (x < 10) s.push('0' + x);
else s.push('A' + x - 10);
n /= k;
}
while (!s.empty()) {
cout << s.top(); s.pop();
}
cout << "(base" << k << ")";
return;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
Comments NOTHING