preface
These are the last two questions I did in Chapter 9 of c++primer, and their difficulty is also the most difficult question I have encountered so far in this book. I don't have a good idea about the first question, so I read the reference answer directly. For the second question, the reference answer is only about addition and subtraction, because I have learned the data structure long ago, We have long wanted to use suffix expressions to write the evaluation of these expressions, so we extended the evaluation of expressions to addition, subtraction, multiplication and division through this problem.
After finishing Chapter 9, I will probably come to the c++primer series every long time. I have been pigeoning the operating system experiment of Harbin Institute of technology for a long time. I must finish this series of experiments first. Of course, c++primer will be more, but it can't be as fast as before.
Here, I still want to talk about my mathematical modeling. My mathematical modeling is rubbish. If my teammates are good, it's really delicious.., I'm mainly invited by my roommate, but I can't refuse. I'm almost alone in thesis writing, modeling and programming. In particular, I didn't know much about the writing time, so I didn't have enough writing time this time. I kicked out the paper without eating three meals a day. I handed it in without even checking. There were still mistakes in it..., But if I really want to say, I really didn't prepare well. I also stole a lot of laziness during training. But I really don't like mathematical modeling very much. I did it during the training. In fact, this competition is more for a promise. But in this mathematical modeling competition, I didn't get nothing, which let me know that I must take action immediately after I have a plan, and don't delay. I must get rid of the problem of dragging me to defecate since I was a child.
Date format conversion code
//Date format conversion date.h #ifndef DATE_H_INCLUDED #define DATE_H_INCLUDED #include<iostream> #include<string> #include<stdexcept> using namespace std; class date{ public: friend ostream &operator<<(ostream &, const date &); date() = default; date(string & ds); unsigned y() const { return year; } unsigned m() const { return month; } unsigned d() const { return day; } private: unsigned year, month, day; //Full name of month public: const string month_name[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; const string month_abbr[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}; const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; inline int get_month(string &ds,int &end_of_month){ int i, j; for (i = 0; i < 12;i++){ for (j = 0; j < month_abbr[i].size();j++){ if(ds[j]!=month_abbr[i][j]){ break; } } if(j==month_abbr[i].size())//Match abbreviation break; } if(i==12){ throw invalid_argument("Not a legal month name"); } if(ds[j]==' '){//Blank character, only month abbreviation end_of_month = j + 1; return i + 1; } for (; j < month_name[i].size();j++){ if(ds[j]!=month_name[i][j]) break; } if(j==month_name[i].size()&&ds[j]==' '){//Full name of month end_of_month = j + 1; return i + 1; } throw invalid_argument("Not a legal month name"); } inline int get_day(string &ds,int month,int &p){ size_t q; int day = stoi(ds.substr(p), &q); if(day<1||day>days[month]){ throw invalid_argument("Is not a legal date value"); } p += q; return day; } inline int get_year(string &ds,int &p){ size_t q; int year = stoi(ds.substr(p), &q); if(p+q<ds.size()){ throw invalid_argument("Illegal ending"); } return year; } }; date::date(string &ds){ int p; size_t q; if((p==ds.find_first_of("0123456789"))==string::npos) throw invalid_argument("No number, illegal date"); if(p>0){ month = get_month(ds, p); day = get_day(ds, month, p); if(ds[p]!=' '&&ds[p]!=',') throw invalid_argument("Illegal spacer"); p++; year = get_year(ds, p); }else{ month = stoi(ds, &q); p = q; if(month<1||month>12){ throw invalid_argument("Is not a legal month value"); } if(ds[p++]!='/'){ throw invalid_argument("Illegal spacer"); } day = get_day(ds, month, p); if(ds[p++]!='/') throw invalid_argument("Illegal spacer"); year = get_year(ds, p); } } ostream &operator<<(ostream&out,const date&d){ out << d.y() << "year" << d.m() << "month" << d.d() << "day" << endl; return out; } #endif //DATE_H_INCLUDED main.c #include<iostream> #include<string> #include"date.h" using namespace std; int main(){ string dates[] = {"February 1 2014", "3/1/2014"}; //string s = "1/3"; // size_t p; // int ret = stoi(s, &p); // cout << ret <<p<<endl; cout<<endl; try{ for(auto ds:dates){ date dl(ds); cout << dl; } }catch(invalid_argument e){ cout << e.what() << endl; } getchar(); getchar(); return 0; }
result
Expression evaluation
This is the expression evaluation I wrote myself. The general method is to convert infix expression into suffix expression, and then use suffix expression to solve it. But to tell you the truth, my writing is rather rubbish. I just write out the requirements, but its efficiency is undoubtedly very slow, especially for the vector container insertion operation. If it is not inserted to the end, it is relatively slow. Then I have made a lot of stupid methods, but I really have no way, and I am not very familiar with c + +, The estimation of the use of library functions is not in place. If you want to refer to it, you can see this link: Suffix expression evaluation
code
#include<iostream> #include<string> #include<stack> #include<vector> #include<deque> using namespace std; stack<string>empty1;//Empty stack vector<string>empty2;//Empty container stack<string> stk;//Stack 1, store operator vector<string> ans;//Put the converted suffix expression into it vector<string>temp;//The entered expression is loaded into it int error; void change_string(string& str) {//Priority processing if (str == "+") { str = "a"; } if (str == "-") str = "b"; if (str == "*") str = "c"; if (str == "/") str ="d"; } void change(vector<string>& temp) {//Convert to suffix expression if(!temp.empty()){ for (auto& num : temp) { if (num.find_first_of("abcd") != string::npos) { start: if (stk.empty()||stk.top()=="(") { stk.push(num); } else if (num > stk.top()) { stk.push(num); } else{ ans.push_back(stk.top()); stk.pop(); goto start; } } else if (num.find_first_of("()") != string::npos) { if (num == ")") { int count = 0; while (stk.top() != "(" && stk.size()) { ++count; ans.push_back(stk.top()); stk.pop(); } if (stk.size() == 0) {//Zero means there is no left parenthesis at all error = -1; return; } if (count == 0) {//Zero means there are no elements in parentheses error = -1; return; } stk.pop(); } else { stk.push(num); } } else { ans.push_back(num); } } } while (!stk.empty()) { ans.push_back(stk.top()); stk.pop(); } } //Find the result for the suffix expression double get_ans(vector<string>& ans) { double ret; if (ans.size() <= 1) { if (ans[0].find_first_of("0123456789") != string::npos) { return stod(ans[0]); } else { error = -1; return -1; } } while (ans.size() > 1) { string str = ""; for (auto s : ans) { str += s; } if (str.find_first_of("0123456789") == string::npos || str.find_first_of("abcd") == string::npos) { error = -1; return -1; } for (int i = 0; i < ans.size(); i++) { if (ans[i] == "a") { if (i - 2 < 0) { error = -1; return -1; } auto begin = ans.begin(); string ans_str = to_string(stod(ans[i - 2]) + stod(ans[i - 1])); //cout << ans_str << endl; //Join once and delete three times begin = ans.insert(begin + i - 2, ans_str); begin = ans.erase(begin + 1); begin = ans.erase(begin); begin = ans.erase(begin); break; } if (ans[i] == "b") { if (i - 2 < 0) { error = -1; return -1; } auto begin = ans.begin(); string ans_str = to_string(stod(ans[i - 2]) - stod(ans[i - 1])); //cout << ans_str << endl; begin = ans.insert(begin + i - 2, ans_str); begin = ans.erase(begin + 1); begin = ans.erase(begin); begin = ans.erase(begin); break; } if (ans[i] == "c") { if (i - 2 < 0) { error = -1; return -1; } auto begin = ans.begin(); string ans_str = to_string(stod(ans[i - 2]) * stod(ans[i - 1])); // cout << ans_str << endl; //Join once and delete three times begin = ans.insert(begin + i - 2, ans_str); begin = ans.erase(begin + 1); begin = ans.erase(begin); begin = ans.erase(begin); break; } if (ans[i] == "d") { if (i - 2 < 0) { error = -1; return -1; } auto begin = ans.begin(); string ans_str = to_string(stod(ans[i - 2]) / stod(ans[i - 1])); //cout << ans_str << endl; //Join once and delete three times begin = ans.insert(begin + i - 2, ans_str); begin = ans.erase(begin + 1); begin = ans.erase(begin); begin = ans.erase(begin); break; } } } double result = stod(ans[0]); ans.pop_back(); return result; } int main() { string line; cout << "Please enter an expression:" << endl; while (getline(cin, line)) { if (line.find_first_not_of("0123456789()*-+/") != string::npos) { cout << "Please re-enter!" << endl; continue; } for (int i = 0; i < line.size();) { if (line[0] == '0') { cout << "Please re-enter!" << endl; break; } if (i > 0 && line.substr(i-1,1).find_first_of("()*-+/") != string::npos && line[i] == '0') { cout << "Please re-enter!" << endl; break; } string str = ""; bool flag = false; while (line.substr(i,1).find_first_of("0123456789") != string::npos) { flag = true; str += line[i]; ++i; } if (str.size() > 0) { temp.push_back(str); } if (flag)continue; if (line.substr(i,1).find_first_of("()*-+/") != string::npos) temp.push_back(line.substr(i,1)); ++i; } for (auto& s : temp) { change_string(s); } cout << endl; change(temp); double result = get_ans(ans); if (error == -1) { cout << "Expression error, please re-enter!" << endl; error = 0; } else { cout << "The expression result is:" << result << endl; } stk = empty1; ans = empty2; temp = empty2; cout << "Please enter an expression:" << endl; } return 0; }