CHAPTER_6 C++STL相关
6.3字符串string
在c语言中,我们使用char数组来存放字符串,有些操作会显得很麻烦。因此,STL中加入了string类型,可以更方便的让我们对字符串进行操作。要使用string,需要添加头文件#include <string>。
string的用法记录在《算法笔记》P202-P209。更详细的用法可以参考博客c++中string的用法_我是一片小树叶的博客-优快云博客_c++string用法。
我们来看一道题目,以此来熟悉string的用法。
题目:
给出两个数,把他们写成科学计数法(保留N位小数)的形式之后,问他们是否相等。若相等,则输出“YES”,并给出该转换结果;若不等,则输出“NO”,并分别给出两个数的转换结果。
输入样例1:
3 12300 12308.9
输出样例1:
YES 1.230*10^4
输入样例2:
3 120 128
输出样例2:
NO 1.200*10^2 1.280*10^2
思路:
我们使用string来读入两个数,便于对数字进行操作。考虑数据本身,我们读入的数字有两种情况:(1) (2)
。即按照整数部分是否为0来分类。
首先,我们要解决一个小问题:去掉数字的前导0。例如:输入为000.123或者0012.3。我们先要把前面多余的0给去掉,以便后面的统一处理。而去掉前导0的方法很简单,使用string类的erase()方法即可。
科学计数法将数表示为两部分:浮点数部分和10的指数部分。如果浮点数部分和指数部分均相等,那么判断为相等YES。反之为不等NO。对于(1)(2)两种情况,我们分别讨论它们的浮点数和指数部分的界定。为了便于讨论,我们假设保留3位小数,即N=3。
情况(1) 。首先我们找到小数点之后第一个非0数字
。找到后,我们的指数e也就确定了,e=-k。例如0.0012,第一个非零数字为
,那么指数部分e=-3。e其实也就是中间0的个数加一,再取相反数。找到
后,在其后面加上小数点,再往后数3位即可组成其小数部分,如果后面不足3位,将不足的位数补0。如0.0012补为1.200。
但是,对于情况(1),还有种可能我们没有考虑:如果我们找不到第一个非0数字 呢?例如0.000的小数点后面全为0。这种情况做如下处理:当遍历完数字却找不到
时,我们直接自原小数点后的第四位数字开始全部截去(即保留3位),即可获得其浮点数部分。显然指数部分e=0。
情况(2) 。去掉前导0之后,第一个数字
一定非0。指数部分为原小数点前的总位数减一,即m-1。浮点数部分为
加上后面三位数,如果位数不足则补0。例如123.4,指数e=3-1=2,浮点数部分为1.234。
对于情况(2),也有一种特殊情况:如果数字没有小数点,我们怎么确定指数e呢?例如123000。很简单,指数为数字总位数减一,同样也是m-1。
综上所述,我们已经能够对两种情况分类处理。因此我们还需要最后一步:确定数字是情况1还是情况2。这显然不难,我们再去除前导0后,如果第一位为小数点则为情况1,反之为情况2。
参考代码:
#include<iostream>
#include<string>
using namespace std;
int n; //保留n位数
void deal(string s,string &f,int &e) {
int k,flag=0;
while(s.size()>1&&s[0]=='0') { //去掉前导0
s.erase(0,1);
}
if(s=="0") { //去掉前导后可能出现一种情况,只剩
f="0."+string(n,'0'); //一个0,此处单独处理这种情况
e=0;
return;
}
if(s[0]=='.') { //情况(1)
for(k=1;k<s.size();k++) { //i从1开始,跳过s[0]即小数点
if(s[k]!='0') {
flag=1;
break;
}
}
if(flag==0) { //小数点后面全是0
f="0."+string(n,'0');
e=0;
return;
}
else { //找到了小数点后第一个非0数
e=-k;
s.insert(k+1,"."); //第一个非0数后插入小数点
f=s.substr(k,2);
k=k+2; //将第一个非0数和小数点计入f串,k往后移2位
while(f.size()<n+2&&k<s.size()) { //从小数点后面数字开始遍历,将它们加入浮点部分
f.insert(f.end(),s[k]); //将s[i]加入f末尾
k++;
}
if(f.size()<n+2) //如果长度不够,用0补至n位小数
f=f+string(n+2-f.size(),'0');
return;
}
}
if(s[0]!='.') { //情况(2)
for(k=0;k<s.size();k++) { //从头遍历串
if(s[k]=='.') {
flag=1;
break;
}
}
if(flag==1) { //找到小数点
e=k-1;
f=s.substr(0,1)+"."; //将第一个数和小数点计入f串
s.erase(k,1);
k=1; //将小数点去掉,并将k指向第二个元素
while(f.size()<n+2&&k<s.size()) { //从第二个数字开始遍历,将它们加入浮点部分
f.insert(f.end(),s[k]); //将s[i]加入f末尾
k++;
}
if(f.size()<n+2) //如果长度不够,用0补至n位小数
f=f+string(n+2-f.size(),'0');
return;
}
else { //没有小数点
e=s.size()-1;
f=s.substr(0,1)+"."; //将第一个数和小数点计入f串
k=1; //将k指向第二个元素
while(f.size()<n+2&&k<s.size()) { //从第二个数字开始遍历,将它们加入浮点部分
f.insert(f.end(),s[k]); //将s[i]加入f末尾
k++;
}
if(f.size()<n+2) //如果长度不够,用0补至n位小数
f=f+string(n+2-f.size(),'0');
return;
}
}
}
int main() {
int e1,e2; //e1、e2保存两个数的指数部分
string s1,s2,f1,f2; //f1、f2保存两个数的浮点数部分
cin>>n>>s1>>s2;
deal(s1,f1,e1);
deal(s2,f2,e2);
if(f1==f2&&e1==e2)
cout<<"YES "<<f1<<"*10^"<<e1<<endl;
else
cout<<"NO "<<f1<<"*10^"<<e1<<" "<<f2<<"*10^"<<e2<<endl;
return 0;
}
本文介绍了如何使用C++ STL库中的string类型实现科学计数法转换,通过实例演示了去除前导零、确定指数和浮点数部分的方法,以判断两个数是否相等。
226

被折叠的 条评论
为什么被折叠?



