处理字符串的实用函数
字符串处理是PAT基础题中较难的一种,一般不涉及数据结构的知识,基础但并不容易AC,有很多边界情况要考虑。 使用字符数组的方法处理字符串非常麻烦和琐碎,使用string的函数以及STL一些与字符串有关的函数可以使问题更清晰简单
string相关函数
string str = "hello world~";
//#1 str.substr返回子串的拷贝
string s1 = str.substr(6,6);
//world~
//#2 str.append在strwei尾追加字符串,返回str的拷贝
auto s = str.append(" hello");
//hello world~ hello
//#3 str.replace用一个字符串替换str中的部分,返回str的拷贝
auto s = str.replace(6,6,"Cpp");
//hello cpp hello
//#4 string搜索
//#均有逆向搜索的版本
str.find("hello"); //返回"hello"第一次出现的地方
str.find('o'); //返回'o'第一次出现的地方
str.find_first_of("abcd");//返回"abcd"中任一字符第一次出现的地方
str.find_first_not_of("hello ");//返回任一不属于"hello "中的字符首次出现的地方
//如果没有找到,均返回string::npos
//#5 数值转换
string s = to_string(val);
//数值类型转换为string,val是数值类型
//string转换为数值类型,格式一定要正确,否则可能触发异常
stoi
stof
stod
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.d1…dN*10^k” (d1>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*10^5
Sample Input 2:
3 120 128
Sample Output 2:
NO 0.120*10^3 0.128*10^3
题意
给出一个正整数N,两个浮点数,将浮点数转化为标准的科学计数式: 0.d1…dN*10^k,保留N位有效数字,然后比较这两个数转化后的格式是否相等
-
浮点数用字符串保存
给出的浮点数很大,最多100位,超过所有数值型能表示的范围
思路
0.d1…dN *10^k
目的是获取k和有效数字d1…dN-
第一位有效数字和小数点的位置至关重要
- 小数点的位置 - 第一位有效数字的位置 = k
- 第一位有效数字向后N位就是有效数字d1…dN
- 如果没有第一位有效数字,则这个数是0
完整代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
//*10^k 计算k
int getk(const string& s)
{
//也可以用s.find('.'),寻找'.'的位置,如果没有,令它为s.size()
int pos_dot = s.find_first_of(".") == string::npos ? s.size() : s.find_first_of(".");
//找到第一位有效数字(第一位非 0或. 的字符)
int pos_first_sig = s.find_first_not_of("0.");
//如果没有第一位有效数字,这个数是0
if (pos_first_sig == string::npos)
{
return 0;
}
else
{
int res = pos_dot - pos_first_sig;
//[1]为什么负数就要+1?
return res > 0 ? res : res + 1;
}
}
//0.d1...dN 获取格式化d1...dN
string getstd(const string& s, int N)
{
int pos_first_sig = s.find_first_not_of("0.");
string temp;
int i = pos_first_sig;
while (N && i < s.size())
{
//获取N位有效数字时,跳过 .
if (s[i] != '.')
{
temp.push_back(s[i]);
--N;
}
++i;
}
//原字符串有效数字长度不足N位,用0补位
while (N)
{
temp.push_back('0');
--N;
}
return temp;
}
string getres(const string& s, int N)
{
return "0." + getstd(s, N) + "*10^" + to_string(getk(s));
}
int main()
{
int N;
string s1, s2;
cin >> N >> s1 >> s2;
if (N == 0)
while (1);
if (getres(s1, N) == getres(s2, N))
{
cout << "YES " << getres(s1, N);
}
else
{
cout << "NO " << getres(s1, N) << " " << getres(s2, N);
}
system("pause");
return 0;
}
[1]为什么负数要+1
如 123.348 是 0.123*10^3 ,k=3
pos_dot - pos_first_sig = 3 -0 =3 符合如 0.01234 是 0.123*10^-1, k=-1
pos_dot - pos_first_sig = 1-3 = -2 不符合
原因就在于k为负数时,小数点在首位有效数字前面,小数点会被计算进去