算法笔记习题 6-3小节
算法笔记@Ada_Lake
算法笔记代码保留地~~~
6.3——C++标准模板库(STL)介绍->string的常见用法详解
1060 Are They Equal (25 分)
- 题目描述 ,If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123×105 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.
- Input Specification::,Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 10100 , and that its total digit number is less than 100.
-
Output Specification:,For each test case, print in a line YES if the two numbers are treated equal, and then the number in the standard form 0.d[1]…d[N]*10k (d[1]>0 unless the number is 0); or NO if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.
Note: Simple chopping is assumed without rounding. -
Sample Input 1:
3 12300 12358.9 -
Sample Output 1:
YES 0.123*105 -
Sample Input 2:
3 120 128 -
Sample Output 2:
NO 0.120*103 0.128 * 103
我的理解
给出一个有效数字位数,两个浮点数。看两个浮点数是否在有效数字内是相等的。如果相等 就输出“YES”,并给出其标准格式。如果不相等就输出“NO”,给出两个浮点数的标准格式。
1.输入有效数字位数 scanf("%d", &n);
2.输入两个浮点数 两个字符串 str
3.截取两个浮点数的有效数字位数 substr()返回从pos号开始,长度为len的子串
4.比较两个浮点数是否相等 compare operator比较
5.相等输出“YES”,给出科学计数法的形式 科学计数法的形式??
嗯,理解的。。不怎么对
题目要求是 现将两个数转换成科学计数法的形式,再比较
科学计数法
格式 :
0.abcd… * 10e 即只需获取abcd和e就可以知道是否相等
两种形式:
1.整数部分为0 即 0.abcd… -> 本体从小数点后第一位非零位开始的n位 指数为小数点与该非零位之间的0的个数的相反数
2.整数部分有0 即 abc.def… -> 本体从a开始的n位。指数是小数点前的总位数–》e初值为0,从前往后枚举。只要不到达最后一位或是出现小数点,就让e加1
隐含trick:
数据可能出现前导0.即 0000.01或 000123.45 -> 去除所有前导0.按去除前导0后的字符串的第一位是否是小数点来判断其属于哪种情况
取出本体:
1:去除前导0,小数点、第一个非零位前的0 。保留第一个非零位开始的部分
2:去除前导0, 小数点。保留从a开始的部分。
在上面获取指数e的过程中同时做到(使用string的erase函数)
将剩余部分取其有效位的部分赋值到新字符串,长度不够有效位后面补0
比较本体部分与指数是否都相等。决定输出YES或NO注意
看删除到最后有没有到尾部 : s.length() > 0
检测第一个数是不是0 s[0] == ‘0’
具体步骤
1.去掉前导0。
反复循环看在没有删除到最后一个数之前,第一个数是不是0.如果是的话就把开始的数给删掉
2. 看是0.abc的情况还是 a.bcd的情况 -> 找出e
0.abc的情况:
去掉前导0的第一个数是‘.’.因此去掉‘.’
再看后面的数是0开始还是直接是abc.
是0:e不断减。直至出现非0
非0:e为零
a.bcd的情况:
遍历‘.’前的所有数,找出e
当长度小于总长度:即后面至少还有一个‘.’ 删除‘. ’
全都是0的情况: 会出现全都是0的情况。这个时候e也要为0
直接看长度是否为0。前面只要不是全为0.长度都不会删除到0
3.找出n位有效数字:
设置一个数与输入的n相比较。如果小于n
若仍小于总长度,长度就一直加上目前的数
若已经大于了总长度,就在后面补0
4.最终返回str;
以下是代码
// Ada
#include<iostream>
#include<string>
using namespace std;
int n;
int main() {
string deal(string, int&);
int e1 = 0, e2 = 0;
string s1, s2, s3, s4;
cin >> n >> s1 >> s2;
s3 = deal(s1, e1);
s4 = deal(s2, e2);
if((s3 == s4) && (e1 == e2)) {
cout << "YES 0." << s3 << "*10^" << e1 << endl;
}
else {
cout << "NO 0." << s3 << "*10^" << e1 <<" 0."<< s4 << "*10^" << e2 << endl;
}
return 0;
}
string deal(string s, int& e) {
string str;
while(s.length() > 0 && s[0] == '0') {
s.erase(s.begin());
}
if(s[0] == '.') {
s.erase(s.begin());
while(s.length() > 0 && s[0] == '0') {
s.erase(s.begin());
e--;
}
if(s.length() == 0) {
e = 0;
}
}
else {
int k = 0;
while( k < s.length() && s[k] != '.') {
k++;
e++;
}
if(k < s.length()) {
s.erase(s.begin() + k);
}
}
int num = 0;
while(num < n) {
if(num < s.length()) {
str += s[num];
}
else {
str += '0';
}
num++;
}
return str;
}