北航研究生复试2013上机第三题:科学计数表示法

题目:给定一个数(正数,前段和末端不包含多余的0),输出其科学计数法表示结果。如:
0.000002 —> 2e-6
123.456 —-> 1.23456e2
123456 —-> 1.23456e5

//给定一个数(正数,前段和末端不包含多余的0),输出其科学计数法表示结果

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAXSIZE 1000

void GetScientificCountingMethod(char* str, int len);               //计算科学计数法表达式
void strcpy_part(char* newstr,int k1,char* str,int k2,int n);       //将str从下标k2开始的n个字符复制到以k1开始的newstr中
void AddExponent(char* newstr,int k,int exponent);                  //在newstr下标k+1位置处添加科学计数法的指数部分,
                                                                    //k位置为e(正指数)、k位置为负号(负指数)

int main(){

    char str[MAXSIZE] = {'\0'};
    while(scanf("%s", str) != EOF){
        int len = strlen(str);
        GetScientificCountingMethod(str,len);
    }

    return 0;
}

void GetScientificCountingMethod(char* str, int len){
    if(len < 1){            //错误数据
        printf("数据错误\n");
        return ;
    }else if(len == 1){     //一位数直接输出
        printf("%s\n", str);
    }else{                  //二位数及以上进行处理
        int beforePoint,afterPoint;     //小数点前个数 和 小数点后个数
        beforePoint = afterPoint = 0;
        int i;
        for(i = 0; i < len; i++){
            if(str[i] != '.'){
                ++beforePoint;
            }else{
                break;
            }
        }
        afterPoint = len - i -1;        //如果输入中有小数点 则正确,如果没有小数点 则afterPoint + 1为小数点后的位数,即0
        //printf("%d\t%d\n",beforePoint,afterPoint);

        if(str[0] != '0' && beforePoint == 1){ //1.23456的情况
            printf("%s\n",str);
            return ;
        }

        char newstr[MAXSIZE] = {'\0'};
        int exponent = 0;   //科学计数法的指数值

        if(str[0] == '0'){  //0.****情况  exponent理应为负数,但是负号可以直接添加,exponent以正值记录
            i = 2;
            while(str[i] == '0' && i < len){
                ++exponent;
                ++i;
            }
            ++exponent;         //此时i是 不为0的第一个数的下标
            if(i == len - 1){   //0.000……*情况  变为*.e-####
                newstr[0] = str[len - 1];
                newstr[1] = 'e';
                newstr[2] = '-';
                AddExponent(newstr,2,exponent);
            }else{              //0.***情况    变为*.***e-####
                newstr[0] = str[i];     //之前算的i位置起了作用
                newstr[1] = '.';
                strcpy_part(newstr,2,str,i+1,len - i - 1);
                int temp = len - i + 1; //科学计数法中e位置的下标
                newstr[temp] = 'e';
                newstr[temp + 1] = '-';
                AddExponent(newstr,temp + 1,exponent);
            }
        }else{                  //****.****情况  变为*.****e##
            exponent = beforePoint - 1;
            newstr[0] = str[0];
            newstr[1] = '.';

            int indexOfE;       //科学计数法中e位置的下标
            if(afterPoint != -1)    {                   //包含小数点
                for(i = beforePoint; i < len - 1; i++)  //将原字符串中的小数点去除
                    str[i] = str[i + 1];                //方便后面字符串的复制strcpy_part()
                //printf("%s\n", str);
                indexOfE = len;
            }
            else if(afterPoint == -1)   //整数
                indexOfE = len + 1;

            strcpy_part(newstr,2,str,1,len - 1);
            newstr[indexOfE] = 'e';
            AddExponent(newstr,indexOfE,exponent);
        }
        printf("%s\n",newstr);
    }
}

void AddExponent(char* newstr,int k,int exponent){
    int sizeOfExponent = 0;
    int temp = exponent;
    while(temp){
        ++sizeOfExponent;
        temp /= 10;
    }
    while(exponent){
        newstr[k + sizeOfExponent] = char(exponent % 10) + '0';
        exponent /= 10;
        --sizeOfExponent;
    }
}

void strcpy_part(char* newstr,int k1,char* str,int k2,int n){
    int i;
    for(i = 0; i < n; i++){
        newstr[k1 + i] = str[k2 + i];
    }
}

输入:
0.000002
0.2
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
0.234
0.00000000412341242000023452345
1234
2143.000004325423532
123.456
1.23456
123456
3
输出:
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值