标签:ali pre iostream 跳过 输入 math using layout sig
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].
[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对
正数也必定明确给出。
现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。
每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。
对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。
+1.23400E-03
0.00123400
-1.2E+10
-12000000000
这道题还是花费了好长时间才ac掉的,主要是一些细节要考虑到,而且我感觉我写的还不够简单,应该还能更简单些。
下面说一下我的思路, 把科学计数法转换成普通的形式,则小数点要么往左移要么往右移,就这两种情况左移还是右移要根据指数部分的正负号来决定,
并且左移和右移两种情况最然有点相似,但是操作却并不一样,右移要比左移更复杂,特别要注意右移时0的有效性和补0;
比如对 0.00045670056 将小数点分别右移一位、两位、三位、八位、11位、13位
下面是是我写的一些测试用例尤其是第三个数据情况比较复杂
+1.234000E+03 分别右移1、2、3、4、5、6、7位
+1.2345E+03 分别右移1、2、3、4、5、6、7位
+0.00045670056E+(-)02 分别右移1、2、3、4、5、7、8、10位
+1.2340E-03 左移一位、三位
-0.2340E-03 左移一位、四位
附上代码
#include<iostream> #include<string> #include<vector> using namespace std; int main() { string num; vector<char> result; cin>>num; int len,ex=0; char flag=‘0‘; unsigned int i,k=1; for(i=0;num[i]!=‘E‘&&i<num.length()-1;i++) result.push_back(num[i]); //把E之前的数字取出来 for(i=num.length()-1;num[i]!=‘E‘&&i>=1;i--){ //把指数给取出来 if(num[i]==‘+‘||num[i]==‘-‘) flag=num[i]; //把指数的正负号给取出来 else { //把指数取出来,指数就是小数点左移或右移的位数 ex+=(num[i]-‘0‘)*k; k*=10; } } len=result.size()-3; //小数的位数 unsigned int index=2+ex; //2为小数点当前所在位置下标,ex为小数点右移的位数,index为小数点右移后所在位置的下标 if(flag==‘+‘){ //指数部分为正,小数点右移 if(result[0]==‘-‘) //如果该数是负数,就添加负号 cout<<‘-‘; if(index>=result.size()-1){ //小数点移动到小数末尾 int fl=0; //用于区分0; 列: 0.00045670056,区分4567之前与之后的0 for(i=1;i<result.size();i++){ if(result[i]==‘.‘||(result[i]==‘0‘&&fl==0)) continue; cout<<result[i]; if(result[i]!=0) fl=1; } } else{ //小数点没有移动到小数末尾,就先输出小数点index左边的数 int fla=0; for(i=1;i<=index;i++){ if(result[i]==‘.‘) continue; if(result[i]==‘0‘&&i==index) { //输出有效的0; 如0.0004567005 456之前的那个0 cout<<result[i]<<"."; break; //已经输出了小数点 } else if(result[i]==‘0‘&&i!=index&&fla==0) continue; //跳过无效的0,如0.0004567005 前三个0 else if(i==index){ //输出整数部分后遇到小数点;如 1.2345 cout<<result[i]<<"."; break; //已经输出了小数点 } else{ cout<<result[i]; //没有特殊情况就正常输出 if(result[i]!=0) fla=1; } } } if(index<result.size()-1){ //小数点没有移动到小数末尾,再输出小数点index右边的数 for(i=index+1;i<result.size();i++) cout<<result[i]; } if(ex>len){ //右移的位数大于小数的位数在末尾补零 int k=ex-len; //差值为要补几个0 while(k--) cout<<‘0‘; } } if(flag==‘-‘){ //指数部分为负,则小数点左移 if(result[0]==‘-‘) //如果该数是负数,就添加负号 cout<<"-"; cout<<"0."; while(--ex) //000001.23400 000000.23400 cout<<‘0‘; for(i=1;i<result.size();i++){ if(result[i]==‘.‘) continue; cout<<result[i]; } } return 0; }
ac了
标签:ali pre iostream 跳过 输入 math using layout sig
原文地址:https://www.cnblogs.com/buanxu/p/12813340.html