2~16之间进制转换

进制转换2

大家了解过”读入优化“吗?由于cin和scanf效率不高,利用getchar()手写一个读入数字的函数可以使程序运行时间变短,这在读入量很大时尤其明显,甚至可能使程序由超时变通过。

getchar函数的作用是一次读入一个字符,当然它也会将数字之间的空格或回车读入,若读入数字的函数还没有读到数字,我们应将这些字符过滤。若函数已经读入了数字,那么这些字符就代表一个数字已经读完了,应结束读取。

示例:

int read(){
	char c=getchar();
	while(c<'0'||c>'9'){//过滤无用字符
		c=getchar();
	}
	int num=c^48;//读入数字时,c^48等效于c-'0',c^48效率似乎"稍微"高一点
	c=getchar();
	while(c>='0'&&c<='9'){//如果读入了其他字符,就跳出循环
		num=num*10+(c^48);
		//当读入新的字符,那么之前的数字整体向高位移动一位,即之前的数乘10+新数字
		//例如,之前已经读入了123,新读入一个数字4,那么数字应为1230+4=1234
		c=getchar();
	}
	return num;
}

那么这和今天的题有什么关系呢?

——这个函数经过修改就可以读入任意进制, 将(新读入的数字)改为(进制)+(新读入的数字)即可。

至于按指定进制输出,我们将读入的过程反着来,发现这样会先输出最低位,然后依次输出高位,而我们期待它先输出高位,再依次输出地位。 怎么办呢?用string把输出的字符从后往前存起来,最后一起输出就行。另一种方法是存入栈中。

#include<iostream>
using namespace std;
int cti(char a){//字符转数字 
	if(a>='A'){
		return a-'A'+10;
	}
	return a-'0';
}
char itc(int a){//数字转字符
	if(a>=10){
		return 'A'+a-10;
	}
	return a+'0';
}
int main(){
	long long i,n=0,p1,p2,x=1;
	string s,res="";
	cin>>p1>>s>>p2;
	for(i=s.size()-1;i>=0;i--){
		n+=cti(s[i])*x;
		x*=p1;
	}
	while(n!=0){
		res=itc(n%p2)+res;
		n/=p2;
	}
	cout<<res<<endl;
	return 0;
}

扩展:

如果你已经了解ASCII的话,做这道题会方便一点,否则,上文中cti函数和itc函数实现起来会更麻烦一些。

ASCII简单理解就是将字符与数字一一对应的一种方法。存储这些字符时,计算机存储的就是对应的数字,要显示字符时再按数字查找应显示的字符。

ASCII一共定义了128个字符对应的数字,毫无疑问这样的话存储一个字符需要7位的空间,char是8位,可以存下。(多余的一位用于在传输信息时校验,我们不需要考虑)

字符与数字的对应关系可以在网上查找到,在ACM中,我们较常见的字符是数字和大小写字母,不过我们不必背下来这些字符与数字的对应关系 就算考试时真的需要知道某个字符对应的值,我们也可以利用计算机获得,比如cout<<(int)'a';

我们只需要记住一些常识即可:'0'~'9'对应的ASCII值是连续的,'a'~'z'对应的ASCII值也是连续的,'A'~'Z'同理。数字<大写字母<小写字母,而且三者不连续,即'9'的下一个不是'A','Z'的下一个不是'a'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值