Simple date format conversion and expression evaluation

Keywords: Algorithm

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;
}

result

Posted by steeveherris on Mon, 20 Sep 2021 09:17:44 -0700