Dear all,
I tried sth easy(actually this was an exercise) but I tried to use the
standard lib. heavily for this problem(as far as I can). There was one
point I could not figure out. The problem is :
../a.out 1.3+3.2+.1+40/3*8/7-4*5-32
The program will parse the argument and find the result of the above
expression. I have two versions(the 2nd is working , not perfect ;-}),
but the first have a return problem I guess because if I use that
version I get "nan" as the result at line 37. What is my problem?
Sorry that there are some comments and cout statement in around the
code. But I guess it could be easier to figure out.
My Best,
1: this version returns nan from the "performer function"
--------------
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <sstream>
7 #include <algorithm>
8 #include <cstdlib>
9 using namespace std;
10
11 template <typename T>
12 T str_To_num (const std::string & s)
13 {
14 T result;
15 std::istringstr eam stream (s);
16 if (stream >result)
17 return result;
18 else{
19 cerr << "error in conversion" <<endl;
20 return EXIT_FAILURE;
21 }
22 }
23 void parse_string(co nst
string&str,vect or<double>&stri ng_num_vec,vect or<char>&operat ors_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_ty pe index;
28 while((index=st r_temp.find_fir st_of(operators ))!
=string::npos){
29 operators_vec.p ush_back(str_te mp[index]);
30 value=str_temp. substr(0,index) ;
31
string_num_vec. push_back(str_T o_num<double>(v alue));
32 str_temp=str_te mp.substr(index +1);
33
if(str_temp.fin d_first_of(oper ators)==string: :npos)
34
string_num_vec. push_back(str_T o_num<double>(s tr_temp));
35 }
36 }
37 double performer(vecto r<double>&vec_d ,vector<char>&v ec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::i terator iter;
42 vector<int>::si ze_type index;
43
if((iter=find_f irst_of(vec_ch. begin(),vec_ch. end(),md.begin( ),md.end())
)!=vec_ch.end() )
44 ;
45 else
if((iter=find_f irst_of(vec_ch. begin(),vec_ch. end(),pm.begin( ),pm.end())
)!=vec_ch.end() )
46 ;
47 else
48 ;
49 switch (*iter){
50 case '*':
51 index = iter-vec_ch.begin();
52 result_temp=vec _d[index]*vec_d[index+1];
53
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
54 vec_ch.erase(it er);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec _d[index]/vec_d[index+1];
59
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
60 vec_ch.erase(it er);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec _d[index]+vec_d[index+1];
65
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
66 vec_ch.erase(it er);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec _d[index]-vec_d[index+1];
71
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
72 vec_ch.erase(it er);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!= 1*/vec_ch.size()!= 0){
78 for(vector<doub le>::const_iter ator
i=vec_d.begin() ;i!=vec_d.end() ;++i)
79 cout << *i << endl;
80 cout << "------------"<<endl;
81 performer(vec_d ,vec_ch);
82 }
83 else
84 return vec_d[0];
85 }
86 int main(int argc, char *argv[]){
87 if(argc!=2){
88 cout << "Usage error should be: <program_name
<mathematical expression" << endl;
89 cout << "Example: operator 1.3+3.2+.
1+40/3*8/7-4*5-32" << endl;
90 return EXIT_FAILURE;
91 }
92 // convert c-style string argument to a c++ string
93 string arg(argv[1]);
94 //cout << arg << endl;
95 vector<doublenu ms;
96 vector<charops;
97 parse_string(ar g,nums,ops);
98 cout << performer(nums, ops) << endl;
99 return 0;
100}
2: on this version, at the end vector includes only one element that
is the result
-------------------------
1 // C++ way of parsing: heavy use of standard library, string parsing
functions
2 //
=============== =============== =============== =============== ===========
=====
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <sstream>
7 #include <algorithm>
8 #include <cstdlib>
9 using namespace std;
10
11 template <typename T>
12 T str_To_num (const std::string & s)
13 {
14 T result;
15 std::istringstr eam stream (s);
16 if (stream >result)
17 return result;
18 else{
19 cerr << "error in conversion" <<endl;
20 return EXIT_FAILURE;
21 }
22 }
23 void parse_string(co nst
string&str,vect or<double>&stri ng_num_vec,vect or<char>&operat ors_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_ty pe index;
28 while((index=st r_temp.find_fir st_of(operators ))!
=string::npos){
29 operators_vec.p ush_back(str_te mp[index]);
30 value=str_temp. substr(0,index) ;
31
string_num_vec. push_back(str_T o_num<double>(v alue));
32 str_temp=str_te mp.substr(index +1);
33
if(str_temp.fin d_first_of(oper ators)==string: :npos)
34
string_num_vec. push_back(str_T o_num<double>(s tr_temp));
35 }
36 }
37 void performer(vecto r<double>&vec_d ,vector<char>&v ec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::i terator iter;
42 vector<int>::si ze_type index;
43
if((iter=find_f irst_of(vec_ch. begin(),vec_ch. end(),md.begin( ),md.end())
)!=vec_ch.end() )
44 ;
45 else
if((iter=find_f irst_of(vec_ch. begin(),vec_ch. end(),pm.begin( ),pm.end())
)!=vec_ch.end() )
46 ;
47 else
48 ;
49 switch (*iter){
50 case '*':
51 index = iter-vec_ch.begin();
52 result_temp=vec _d[index]*vec_d[index+1];
53
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
54 vec_ch.erase(it er);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec _d[index]/vec_d[index+1];
59
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
60 vec_ch.erase(it er);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec _d[index]+vec_d[index+1];
65
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
66 vec_ch.erase(it er);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec _d[index]-vec_d[index+1];
71
vec_d.insert(ve c_d.erase(vec_d .erase(vec_d.be gin()
+index)),result _temp);
72 vec_ch.erase(it er);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!= 1*/vec_ch.size()!= 0){
78 performer(vec_d ,vec_ch);
79 }
80 //else
81 // return vec_d[0];
82 }
83 int main(int argc, char *argv[]){
84 if(argc!=2){
85 cout << "Usage error should be: <program_name
<mathematical expression" << endl;
86 cout << "Example: operator 1.3+3.2+.
1+40/3*8/7-4*5-32" << endl;
87 return EXIT_FAILURE;
88 }
89 // convert c-style string argument to a c++ string
90 string arg(argv[1]);
91 //cout << arg << endl;
92 vector<doublenu ms;
93 vector<charops;
94 parse_string(ar g,nums,ops);
95 //cout << performer(nums, ops) << endl;
96 performer(nums, ops);
97 for(vector<doub le>::const_iter ator iter=nums.begin ();iter!
=nums.end();++i ter)
98 cout << *iter << endl;
99 //for(vector<char >::const_iterat or iter=ops.begin( );iter!
=ops.end();++it er)
100 // cout << *iter << endl;
101 return 0;
102 }