1024 科学计数法

1024 科学计数法 (20分)
 

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对

正数也必定明确给出。

现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。

输入格式:

每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。

输出格式:

对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。

输入样例 1:

+1.23400E-03
 

输出样例 1:

0.00123400
 

输入样例 2:

-1.2E+10
 

输出样例 2:

-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了

原文地址:https://www.cnblogs.com/buanxu/p/12813340.html