PAT (Basic Level) 1024 科学计数法 (20 point(s))

// 没参考前的繁琐版
#include <bits/stdc++.h>
using namespace std;
int main() {
	string str, num;
	cin >> str;
	// 读取底数正负符号 如果'-'直接输出
	if(str[0] == '-')
		cout << '-';
			
	int i = 1;
	// 读取E前数字(含小数点
	while(1){
		// 读取到E
		if(str[++i] == 'E')
			break;
	}
	num = str.substr(1, i-1);
	
	// 读取E后正负符号
	char symbol = str[++i];
	
	// 读取指数
	string tmp = str.substr(++i);
	// 转换指数字符串为数字
	int expon = stoi(tmp);
	int xiaoshu = num.size() - 2;
	i = 1;
	// 小数点左右移动
	do{
		if(symbol == '-'){
			if(num[0] != '.'){
				num[i] = num[i-1];
				num[i-1] = '.';
			}
			else{
				// 如果超过头插入0
				num.insert(i, 1, '0');
			}
			expon--;
		}
		else if (symbol == '+'){
			// 向右移动
			if(xiaoshu){
				num[i] = num[++i];
				num[i] = '.'; 
				xiaoshu--,expon--;
			}
			// 是否插入0 
			else if(expon--){
				// 从尾部继续插入 
				num.insert(i++, 1, '0');
			}
			if(expon == 0 && xiaoshu == 0){
					num[i] = '\0';
			}
		}
	} while(expon);
	// 输出负指数
	if(symbol == '-') 
		cout << 0 << num;
	else
		cout << num;
}
#include<iostream>
#include<string>
using namespace std;
int main()
{
	char h,a[10001]={0};
	int i,e;
	scanf("%c%c.%[0-9]E%d",&h,&a[0],a+1,&e);
	if(h=='-')
	printf("-");
	if(e<0)       //指数小于0的情况 
	{
		printf("0.");
		e=-e-1;
		while(e)
		{
			printf("0");
			e--;
		}
		printf("%s",a);
	}
	else         //指数不小于0的情况 
	{
		// 当指数和底数任一非空时继续循环
		for(i=0;i<=e||a[i]!=0;i++)
		{
			if(i==e+1)
				printf(".");
			printf("%c",a[i]==0?'0':a[i]);
		}
	}
 } 

while(expon--);

本来while在循环前面,判断expon--,后来改成了do……while发现有几个问题。

首先循环条件用到了expon这个变量,如果写在开头,那么先在开头判断expon是否为真,然后 -- 运算,再执行循环里面的代码。如果把它改成do……while放在循环末尾,而判断形式不变,那么就会先执行一次循环内代码,然后判断 -- 运算。这意味着会多一次执行循环里面的代码。

为了改正这个问题,就需要改变运算和判断的顺序,先 -- 运算,再判断expon变量是否为真,减去一次以对应前面的第一次循环执行。 


if(expon == 0 && xiaoshu == 0){
        num[i] = '\0';

num[i] = num[++i];
num[i] = '.';  

当指数为零,并且小数位已经处理完毕也同样为0时,将数字的结尾替换成'\0'。因为在前面将数字左移而小数点右移,所以如果小数点不在数字当中,就会在数字末尾,这时候需要替换。


num[i] = num[++i];
num[i] = '.'; 
xiaoshu--,expon--;

前面写expon用作循环次数的变量,同时在循环里面还通过expon判断是否在字符串末尾防止 \0 。这时候就不能够把expon-- 次数运算放在循环末尾或开头 -- ,而应该在循环代码中间处理之后即可进行运算,以对应第二个判断。

因为这时候expon不仅仅充当循环次数的功能,还需要用作其他语句的判断,就需要考虑其他语句的前后关系。


一个写代码的思路认识。先判断将问题分类,然后在不同的判断代码块里面制造循环处理。如果像未简化前的代码,先构造一个循环,然后在循环里面再判断不同问题处理,那么就可能由于问题之间边界问题的不同,而导致难以协调,从而浪费很多时间在协调和修改上面。

比如上面的未修改前的代码,就是先进入循环然后再判断指数是正还是负,但是循环变量共用了expon计算循环次数,而指数为负的时候又需要判断指数是否为 0 的情况,或者进行运算。这就给写代码的时候带来很多问题。如果在考试的时候不能够捋清楚这些关系,显然就会浪费大量的时间。

而如果这样,显然不如先用判断分类后,再分别用循环相互独立地处理,虽然代码量可能显得更多,但从问题解决的方面考虑显然要来得简单和直接,不要过多考虑指数正负处理代码的相互关系。


参考别人的思路,发现自己在原字符串上面做修改这种方法显得复杂了,直接将对应的部分输出会更简单,而不需要修改时候还要考虑其他的边界问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值