U
utab
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::istringstream 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(const
string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_type index;
28 while((index=str_temp.find_first_of(operators))!
=string::npos){
29 operators_vec.push_back(str_temp[index]);
30 value=str_temp.substr(0,index);
31
string_num_vec.push_back(str_To_num<double>(value));
32 str_temp=str_temp.substr(index+1);
33
if(str_temp.find_first_of(operators)==string::npos)
34
string_num_vec.push_back(str_To_num<double>(str_temp));
35 }
36 }
37 double performer(vector<double>&vec_d,vector<char>&vec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_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(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
78 for(vector<double>::const_iterator
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<double> nums;
96 vector<char> ops;
97 parse_string(arg,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::istringstream 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(const
string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_type index;
28 while((index=str_temp.find_first_of(operators))!
=string::npos){
29 operators_vec.push_back(str_temp[index]);
30 value=str_temp.substr(0,index);
31
string_num_vec.push_back(str_To_num<double>(value));
32 str_temp=str_temp.substr(index+1);
33
if(str_temp.find_first_of(operators)==string::npos)
34
string_num_vec.push_back(str_To_num<double>(str_temp));
35 }
36 }
37 void performer(vector<double>&vec_d,vector<char>&vec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_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(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
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<double> nums;
93 vector<char> ops;
94 parse_string(arg,nums,ops);
95 //cout << performer(nums,ops) << endl;
96 performer(nums,ops);
97 for(vector<double>::const_iterator iter=nums.begin();iter!
=nums.end();++iter)
98 cout << *iter << endl;
99 //for(vector<char>::const_iterator iter=ops.begin();iter!
=ops.end();++iter)
100 // cout << *iter << endl;
101 return 0;
102 }
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::istringstream 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(const
string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_type index;
28 while((index=str_temp.find_first_of(operators))!
=string::npos){
29 operators_vec.push_back(str_temp[index]);
30 value=str_temp.substr(0,index);
31
string_num_vec.push_back(str_To_num<double>(value));
32 str_temp=str_temp.substr(index+1);
33
if(str_temp.find_first_of(operators)==string::npos)
34
string_num_vec.push_back(str_To_num<double>(str_temp));
35 }
36 }
37 double performer(vector<double>&vec_d,vector<char>&vec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_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(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
78 for(vector<double>::const_iterator
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<double> nums;
96 vector<char> ops;
97 parse_string(arg,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::istringstream 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(const
string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_type index;
28 while((index=str_temp.find_first_of(operators))!
=string::npos){
29 operators_vec.push_back(str_temp[index]);
30 value=str_temp.substr(0,index);
31
string_num_vec.push_back(str_To_num<double>(value));
32 str_temp=str_temp.substr(index+1);
33
if(str_temp.find_first_of(operators)==string::npos)
34
string_num_vec.push_back(str_To_num<double>(str_temp));
35 }
36 }
37 void performer(vector<double>&vec_d,vector<char>&vec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_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(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
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<double> nums;
93 vector<char> ops;
94 parse_string(arg,nums,ops);
95 //cout << performer(nums,ops) << endl;
96 performer(nums,ops);
97 for(vector<double>::const_iterator iter=nums.begin();iter!
=nums.end();++iter)
98 cout << *iter << endl;
99 //for(vector<char>::const_iterator iter=ops.begin();iter!
=ops.end();++iter)
100 // cout << *iter << endl;
101 return 0;
102 }