您的位置:首页 > 理论基础 > 数据结构算法

计算器之如何从字符串表达式中有效提取数字

2016-11-23 12:00 459 查看

讨论这个问题之前,我们先来看一下如何实现数字与字符串的双向转化 (虽然网上已经有了很多这种文章,但我还是想简单写一下)

sprintf

字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。

百度百科

这个函数可以实现将数字转化为字符串,但最好指明精度

比如以下代码:

#include <iostream>
#include <cstdio>

// using namespace std;

int main()
{
double d;
std::cin >> d;

char buffer1[100] ,buffer2[100];
sprintf(buffer1, "%f", d);
sprintf(buffer2, "%.2f", d);

std::cout << buffer1 << std::endl << buffer2 << "\n";

return 0;
}


input :

1.235

output :

1.235000

1.234

所以我们要结合实际需要合理使用

atof

把字符串转换成浮点数

百度百科

这个函数可以很好的将字符数组转化为对应的数字, 以下是使用案例并测试了一下精度问题 :

#include <iostream>
#include <iomanip> //setw() 设置输出的width
#include <cstdlib> //使用atof() //类似的还有一些
#include <string>

#define SIZE 6

using namespace std;

int main()
{
string num[SIZE] =
{"1.23", "1.234", "1.2345", "1.23456", "1.234567", "1.2345678"};

// 函数 c_str() 可以实现将string对象转换成C风格字符串
for (int i = 0; i < SIZE; i++)
cout << setw(10) << num[i] << "\t-->\t" << atof( num[i].c_str() ) << endl;

return 0;
}


output :

1.23        -->     1.23
1.234       -->     1.234
1.2345      -->     1.2345
1.23456     -->     1.23456
1.234567    -->     1.23457
1.2345678   -->     1.23457


我们可以清楚的看到atof()可以很方便地将字符串数组转换为对应数字,而且我们也会注意到它不适合高精度计算,但对于实现计算器小程序足够了

以下步入正题

输入一串字符串表达式,如何有效地将其中所有的数字提取出来并进行操作(这里为了简便,操作直接为显示出来),以下代码即可实现:

#include <iostream>
#include <cstdlib> //使用atof(char*) //类似的还有一些
#include <cctype>  //字符判断: isdigit(char)
#include <string>

using namespace std;
string expression;
do {
cout << "Please input your string expression(Ctr+z to exit): ";
getline(cin, expression);

int i = 0, j = 0, len = expression.length();
while (i < len)
{
if (isdigit(expression[i]))
{
j = i;
// 若下一位小于len并且是数字则i++,可以理解用i来探测数字
while (i++ < len && isdigit(expression[i])) {}

if(i < len && expression[i] == '.')
{
// 此处为了简易而简单处理了
if (!isdigit(expression[i+1]))
exit(1);
while (i++ < len && isdigit(expression[i])) {}
}

// j为子串在源字符串中的开始位置,i-j为子串的长度
string num_string = expression.substr(j, i-j);

double num_double = atof(num_string.c_str());

cout << "string num: " << num_string << "\t -->" << "double num: " << num_double << endl;
}
else
i++;
}
} while (getline(cin, expression));


input:

1.23+(4.56-7.89)*0.123/3.456789


output:

string num: 1.23        -->        double num: 1.23
string num: 4.56        -->        double num: 4.56
string num: 7.89        -->        double num: 7.89
string num: 0.123       -->        double num: 0.123
string num: 3.456789    -->        double num: 3.45679


input :

12(@#4.23/!12.47%$@456*)


output :

string num: 12       -->     double num: 12
string num: 4.23     -->     double num: 4.23
string num: 12.47    -->     double num: 12.47
string num: 456      -->     double num: 456


OK,以上结束 :)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构