欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

程序员文章站 2022-07-15 10:30:11
...

目录

1,题目描述

 题目描述

2,思路

我的算法

3,AC代码

我的代码

柳神解法

4,解题过程

第一搏

 第二搏

第三搏

第四搏


1,题目描述

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

Sample Input 1:

+1.23400E-03

 

Sample Output 1:

0.00123400

 

Sample Input 2:

-1.2E+10

 

Sample Output 2:

-12000000000

 题目描述

就是将科学计数法转为普通的数的表示

 

2,思路

这种题目处理的方式感觉不固定(可能是刷的还不够)

我的算法

  1. 用bool型变量signOfNum,signOfExp存放数字部分和指数部分的符号,字符串s存放数字部分,int型exp存放指数;
  2. 根据signOfNum判断是否输出负号;
  3. 若指数部分小于0(不包括等于),则先输出0.   ,再根据exp判断需要输出多少个0,接着输出数字部分s;
  4. 若指数部分大于等于0,根据是否输出小数点分成两种情况。指数exp足够大,不需要输出小数点,并根据exp大小输出一定数目的0;否则定位小数点的位置,输出一部分数字,输出小数点,输出数字的剩余部分;

 

3,AC代码

我的代码

#include<bits/stdc++.h>
using namespace std;

bool cmp1(int a, int b){return a > b;}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE

    bool signOfNum = false, signOfExp = false;
    string s;
    char c;
    scanf("%c", &c);                    //读取数字符号
    if(c == '+') signOfNum = true;
    scanf("%c", &c);                    //读取小数点前数字
    s += c;                             //将所有数字部分拼接起来 

    scanf("%c", &c);                    //读取小数点
    scanf("%c", &c);                    //读取数字部分
    while(isdigit(c)){
        s += c;
        scanf("%c", &c);
    }
    scanf("%c", &c);                    //读取指数符号
    if(c == '+') signOfExp = true;
    int exp;
    scanf("%d", &exp);                  //读取指数部分
    
    if(signOfNum == false) printf("-"); //数字部分为负值 则先输出负号
    if(signOfExp == false && exp > 0){  //指数为负
    //if(signOfExp == false){
        printf("0.");                   //指数exp超过0时 需要输出0. 并且根据exp在前面补充0
        for(int i = 0; i < exp - 1; i++) printf("0");
        cout<<s;                        //首部0补充足后 输出数字部分
    }else{                              //指数>=0
        //while(s[s.size()-1] == '0') s.erase(s.size()-1, 1);//不需要将数字部分尾部的0删去
        if(exp >= s.size() - 1){        //不需要小数点
            cout<<s;
            exp -= (s.size() - 1);
            while(exp > 0){             //在尾部补充足够的0
                printf("0");
                exp--;
            }
        }else{
            int index;
            for(index = 0; index <= exp; index++) cout<<s[index];
            cout<<'.';                  //数字部分中间正确位置插入小数点
            for(;index < s.size(); index++) cout<<s[index];
        }
    }
    return 0;
}

柳神解法

把柳神的做法也贴出来学习学习! 

#include <iostream>
using namespace std;
int main() {
    string s;
    cin >> s;
    int i = 0;
    while (s[i] != 'E') i++;
    string t = s.substr(1, i-1);
    int n = stoi(s.substr(i+1));
    if (s[0] == '-') cout << "-";
    if (n < 0) {
        cout << "0.";
        for (int j = 0; j < abs(n) - 1; j++) cout << '0';
        for (int j = 0; j < t.length(); j++)
            if (t[j] != '.') cout << t[j];
    } else {
        cout << t[0];
        int cnt, j;
        for (j = 2, cnt = 0; j < t.length() && cnt < n; j++, cnt++) cout <<t[j];
        if (j == t.length()) {
            for (int k = 0; k < n - cnt; k++) cout << '0';
        } else {
            cout << '.';
            for (int k = j; k < t.length(); k++) cout << t[k];
        }
    }
    return 0;
}

 

4,解题过程

第一搏

果然还是讨厌这种题目。

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

#include<bits/stdc++.h>
using namespace std;

bool cmp1(int a, int b){return a > b;}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE

    bool signOfNum, signOfExp;
    string s;
    char c;
    scanf("%c", &c);//读取数字符号
    if(c == '+') signOfNum = true;
    //else signOfNum = false;
    scanf("%c", &c);//读取小数点前数字
    s += c;

    scanf("%c", &c);//读取小数点
    scanf("%c", &c);
    while(isdigit(c)){
        s += c;
        scanf("%c", &c);
    }
    scanf("%c", &c);//读取指数符号
    if(c == '+') signOfExp = true;
    int exp;
    scanf("%d", &exp);
    if(signOfNum == false) printf("-");
    if(signOfExp == false){
        printf("0.");
        for(int i = 0; i < exp - 1; i++) printf("0");
        cout<<s;
    }else{
        //while(s[s.size()-1] == '0') s.erase(s.size()-1, 1);
        if(exp >= s.size() - 1){//不需要小数点
            cout<<s;
            exp -= (s.size() - 1);
            while(exp > 0){
                printf("0");
                exp--;
            }
        }else{
            int index;
            for(index = 0; index <= exp; index++) cout<<s[index];
            cout<<'.';
            for(;index < s.size(); index++) cout<<s[index];
        }
    }
    return 0;
}

 第二搏

冷静分析之后,可能是这个问题,后面的0没有去掉。

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

问题解决了,然而仍然只有5分。

在牛客网上运行完全没问题(不同的编译器可能会有问题)

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

第三搏

突然想到,如果E后面为0会怎么样

于是测试了下面的数据

+1.23400E-0

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

发现问题了!当为E-0时,原先代码设定的逻辑是:遇到E后为负,直接先输出 0.,所以改进一下条件(我的算法是,将符号与数字分离,所以exp总数大于等于0)多加了红色框部分的内容(一开始的代码如注释所示)

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】 

第四搏

冷静分析后,想到前面第二搏修改的部分(若输入为+1.23400E+03,则输出改为1234,而不是1234.00) 会不会是多余的

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

于是我试着把这部分注释掉,再次运行

飒!

*PAT_甲级_1073 Scientific Notation (20point(s)) (C++)【字符串处理/科学计数法】

相关标签: PAT