前言
这两个是我在c++primer第九章所做的最后两题,其难度也是我在这本书中目前为止遇到的最难的题,对于第一题我并未很好的想法,所以我就直接看了参考答案,对于第二题的话,参考答案只是有关于加减法的,由于我早就学完了数据结构,对于利用后缀表达式来写这些表达式的求值早就想做了,所以就通过这个题把表达式的求值扩展到了加减乘除。
 把第九章更完之后,我大概又要隔好久来更c++primer系列了,哈工大的操作系统实验我已经鸽了好久了,我必须要先把这系列实验做完去。当然,c++primer也会更,但不可能像以前那么快速了。
 在这我还是想要说一下我的数学建模吧,我的数学建模做的比较垃圾,队友的话,确实比较菜吧。。,主要是室友邀请我的,我也不好拒绝,论文写作,建模,程序都差不多是我一个人搞得。特别我不太了解写作的时间,所以这次留的写作时间不够,我是硬生生一天三餐都没吃把论文赶出来的,连检查都没有就交上去了,里面还有错误。。。,但真要说的话我也确实没有好好准备,自己在培训的时候也偷了很大的懒。但数学建模我确实也是渐渐不太喜欢了,在培训的时候我就这样了,其实这次参赛更多是为了一个承诺。但是在这个数学建模比赛中也不是毫无收获,这让我知道了一定要有了计划之后就马上行动,不要拖。对于拖我从小到大便有这个毛病,我必须要把这个毛病改掉去。
日期格式转化代码
//日期格式转化
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;
    //月份全称
    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())//与简写匹配
                       break;
            }
            if(i==12){
                throw invalid_argument("不是合法月份名");
            }
            if(ds[j]==' '){//空白符,仅是月份简写
                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]==' '){//月份全称
                end_of_month = j + 1;
                return i + 1;
            }
            throw invalid_argument("不是合法月份名");
        }
        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("不是合法日期值");
            }
            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("非法结尾内容");
            }
            return year;
        }
};
date::date(string &ds){
            int p;
            size_t q;
            if((p==ds.find_first_of("0123456789"))==string::npos)
                throw invalid_argument("没有数字,非法日期");
            if(p>0){
                month = get_month(ds, p);
                day = get_day(ds, month, p);
                if(ds[p]!=' '&&ds[p]!=',')
                    throw invalid_argument("非法间隔符");
                p++;
                year = get_year(ds, p);
            }else{
                month = stoi(ds, &q);
                p = q;
                if(month<1||month>12){
                    throw invalid_argument("不是合法月份值");
                }
                if(ds[p++]!='/'){
                    throw invalid_argument("非法间隔符");
                }
                day = get_day(ds, month, p);
                if(ds[p++]!='/')
                    throw invalid_argument("非法间隔符");
                year = get_year(ds, p);
            }
}
ostream &operator<<(ostream&out,const date&d){
            out << d.y() << "年" << d.m() << "月" << d.d() << "日" << 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;
}
 
结果

表达式求值
这个是我自己写的表达式求值,总的做法就是把中缀表达式转化成后缀表达式,然后利用后缀表达式来求解。但说实话我这个写的比较垃圾,只是把需求写出来了,但其效率无疑是很慢的,特别是对于vector容器插入操作如果不是插入到尾端的话是比较慢的,然后自己也是搞了很多自我感觉比较愚蠢的方法,但也是实在没有办法,并且自己对c++也确实还不是很熟很熟,对于库函数的运用估计还不到位。如果各位想要参考的话,可以看这个链接:后缀表达式求值
代码
#include<iostream>
#include<string>
#include<stack>
#include<vector>
#include<deque>
using namespace std;
stack<string>empty1;//空栈
vector<string>empty2;//空的容器
stack<string> stk;//栈1,存放运算符
vector<string> ans;//转化后的后缀表达式放入其中
vector<string>temp;//输入的表达式装入其中
int error;
void change_string(string& str) {//优先级处理
    if (str == "+") {
        str = "a";
    }
    if (str == "-")
        str = "b";
    if (str == "*")
        str = "c";
    if (str == "/")
        str ="d";
}
void change(vector<string>& temp) {//转化成后缀表达式
    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) {//为零代表根本就没有左括号
                        error = -1;
                        return;
                    }
                    if (count == 0) {//为零代表括号内没有元素
                        error = -1;
                        return;
                    }
                    stk.pop();
                }
                else {
                    stk.push(num);
                }
            }
            else {
                ans.push_back(num);
            }
        }
    }
    while (!stk.empty()) {
        ans.push_back(stk.top());
        stk.pop();
    }
}
//针对后缀表达式求出结果
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;
                //一次加入,三次删除
                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;
                //一次加入,三次删除
                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;
                //一次加入,三次删除
                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 << "请输入表达式:" << endl;
    while (getline(cin, line)) {
        if (line.find_first_not_of("0123456789()*-+/") != string::npos) {
            cout << "请重新输入!" << endl;
            continue;
        }
        for (int i = 0; i < line.size();) {
            if (line[0] == '0') {
                cout << "请重新输入!" << endl;
                break;
            }
            if (i > 0 && line.substr(i-1,1).find_first_of("()*-+/") != string::npos && line[i] == '0') {
                cout << "请重新输入!" << 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 << "表达式错误,请重新输入!" << endl;
            error = 0;
        }
        else {
            cout << "表达式结果为:" << result << endl;
        }
        stk = empty1;
        ans = empty2;
        temp = empty2;
        cout << "请输入表达式:" << endl;
    }
    return 0;
}
 
结果

                  
                  
                  
                  
                            
本文介绍了一个C++程序实现的表达式求值功能,该程序能够将中缀表达式转换为后缀表达式并进行计算。此外,还包括了一个日期字符串解析和格式化为年月日的实用工具。
          
      
          
                
                
                
                
              
                
                
                
                
                
              
                
                
              
            
                  
					4699
					
被折叠的  条评论
		 为什么被折叠?
		 
		 
		
    
  
    
  
            


            