用映射求解线性方程

Solve linear equation with Maps

本文关键字:线性方程 映射      更新时间:2023-10-16

我已经基本完成了求解简单线性方程组的编码。似乎在递归调用中缺少了一些map导致的问题。

这是要解决的问题陈述,例如:

X = Y + 2
Y = Z + R + 1
R = 2 +       3
Z = 1

给定:LHS将只是变量名。RHS将只有变量,unsigned int和'+'操作符。解出所有未知数

解决方案,我得到我的代码:

X = 2
Y = 1
R = 5
Z = 1
我的代码:
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <fstream>
#include <set>
#include <regex>
using namespace std;
map<string, string> mymap;
// Method to Parse a given expression based on given arg delimiter
// ret: vector of parsed expression
vector<string> parse_expr(string n, char  *delims)
{
    vector<string> v;
    string cleanline;
    char* char_line = (char*)n.c_str(); // Non-const cast required.
    char* token = NULL;
    char* context = NULL;
    vector<string>::iterator it;
    token = strtok_s(char_line, delims, &context);
    while (token != NULL)
    {
        cleanline += token;
        cleanline += ' ';
        v.push_back(token);
        token = strtok_s(NULL, delims, &context);
    }
    return v;
}
//Method to find sum for a given vector
//retype: string 
//ret: sum of given vector
string find_VctrSum(string key, vector<string> v)
{
    int sum = 0;
    string val;
    vector<string>::iterator i;
    for (i = v.begin(); i != v.end(); i++)
    {
        val = *i;
        //cout << "val is :" << val << endl;
        sum += stoi(val);
    }
    return to_string(sum);
}
//Method to check if arg is integer or string
// ret: True if int
bool isNumber(string x) {
    regex e("^-?\d+");
    if (regex_match(x, e)) return true;
    else return false;
}

//Recursive call to evaluate the set of expressions
string evaluate_eq(string key)
{
    string expr, var;
    vector<string> items;
    vector<string>::iterator i;
    auto temp = mymap.find(key);
    if (temp != mymap.end())  // check temp is pointing to underneath element of a map
    {
        //fetch lhs
        var = temp->first;
        //fetch rhs
        expr = temp->second;
    }
    // remove whitespaces
    expr.erase(remove_if(expr.begin(), expr.end(), isspace), expr.end());
    //Parse RHS by '+' sign
    items = parse_expr(expr, "+");
    for (i = items.begin(); i != items.end(); i++)
    {
        //cout << (*i) << endl;
        if (isNumber(*i) == true)
        {
            //pass- do nothiing
        }
        else
        {
            //recursive call to evaluate unknown
            string c = evaluate_eq(*i);
            //now update the map and Find Sum vector
            mymap[key] = c;
            *i = c;
        }
    }
    //find sum 
    return find_VctrSum(key, items);
}

//main to parse input from text file and evaluate
int main()
{
    string line;
    ifstream myfile("equation.txt");
    vector<string> v;
    if (myfile.is_open())
    {
        while (getline(myfile, line))
        {
            v.push_back(line);
        }
        myfile.close();
    }
    else cout << "Unable to open file";
    //Create a map with key:variable and value: expression to solve
    for (int i = 0; i < v.size(); i++)
    {
        vector<string> token;
        token = parse_expr(v[i], "=");
        mymap.insert(pair<string, string>(token[0], token[1]));
    }
    cout << "Equation sets given:" << endl;
    for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
    {
        std::cout << it->first << " => " << it->second << 'n';
    }
    for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); it++)
    {
        //Also update the map
        mymap[it->first] = evaluate_eq(it->first);
    }
    cout << "Equation sets solved:" << endl;
    for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
    {
        std::cout << it->first << " => " << it->second << 'n';
    }
    char ch;
    cin >> ch;
}

逻辑是在解析给定表达式时递归地调用任何未知(字符串),并使用值更新映射。在调试时,我可以看到我的递归调用在下面失败,但我看到"mymap"正在更新。不知道为什么。

if (temp != mymap.end())

任何帮助在确定问题或任何逻辑失误将不胜感激。由于

修复了几个逻辑后,我的代码可以正常工作了。

  1. 在main ()

当创建输入映射时,通过分隔空格

创建
//Create a map with key:variable and value: expression to solve
    for (int i = 0; i < v.size(); i++)
    {
        vector<string> token;
        token = parse_expr(v[i], "=");
        //Strip whitespaces
        token[0].erase(remove_if(token[0].begin(), token[0].end(), isspace), token[0].end());
        token[1].erase(remove_if(token[1].begin(), token[1].end(), isspace), token[1].end());
        mymap.insert(pair<string, string>(token[0], token[1]));
    }

这消除了我在地图中查找键的问题-

if (temp != mymap.end())
  • 更新了我的find_VctrSum来更新这里的地图,不像我以前尝试在evaluate_eq()中更新。

  • //Method to find sum for a given vector
    //retype: string 
    //ret: sum of given vector
    string find_VctrSum(string key, vector<string> v)
    {
        int sum = 0;
        string val;
        vector<string>::iterator i;
        for (i = v.begin(); i != v.end(); i++)
        {
            val = *i;
            sum += stoi(val);
        }
        //Update the Map
    

    mymap[key] = to_string(sum);

        return to_string(sum);
    }
    

    这是完整的工作代码-

    #include <vector>
    #include <string>
    #include <sstream>
    #include <iostream>
    #include <map>
    #include <fstream>
    #include <set>
    #include <regex>
    using namespace std;
    map<string, string> mymap;
    // Method to Parse a given expression based on given arg delimiter
    // ret: vector of parsed expression
    vector<string> parse_expr(string n, char  *delims)
    {
        vector<string> v;
        string cleanline;
        char* char_line = (char*)n.c_str(); // Non-const cast required.
        char* token = NULL;
        char* context = NULL;
        vector<string>::iterator it;
        token = strtok_s(char_line, delims, &context);
        while (token != NULL)
        {
            cleanline += token;
            cleanline += ' ';
            v.push_back(token);
            token = strtok_s(NULL, delims, &context);
        }
        return v;
    }
    //Method to find sum for a given vector
    //retype: string 
    //ret: sum of given vector
    string find_VctrSum(string key, vector<string> v)
    {
        int sum = 0;
        string val;
        vector<string>::iterator i;
        for (i = v.begin(); i != v.end(); i++)
        {
            val = *i;
            sum += stoi(val);
        }
        //Update the Map
        mymap[key] = to_string(sum);
        return to_string(sum);
    }
    //Method to check if arg is integer or string
    // ret: True if int
    bool isNumber(string x) {
        regex e("^-?\d+");
        if (regex_match(x, e)) return true;
        else return false;
    }
    
    //Recursive call to evaluate the set of expressions
    string evaluate_eq(string key)
    {
        string expr, var;
        vector<string> items;
        vector<string>::iterator i;
        string currentkey = key;
        auto temp = mymap.find(key);
        if (temp != mymap.end())  // check temp is pointing to underneath element of a map
        {
            //fetch lhs
            var = key;
            //fetch rhs
            expr = temp->second;
        }
        // remove whitespaces
        expr.erase(remove_if(expr.begin(), expr.end(), isspace), expr.end());
        //Parse RHS by '+' sign
        items = parse_expr(expr, "+");
        for (i = items.begin(); i != items.end(); i++)
        {
            if (isNumber(*i) == true)
            {
                //pass- do nothiing
            }
            else
            {
                //recursive call to evaluate unknown
                string c = evaluate_eq(*i);
                //update the temp vector
                *i = c;
            }
        }
        //find sum 
        return find_VctrSum(key, items);
    }
    
    //main to parse input from text file and evaluate
    int main()
    {
        string line;
        ifstream myfile("equation.txt");
        vector<string> v;
        if (myfile.is_open())
        {
            while (getline(myfile, line))
            {
                v.push_back(line);
            }
            myfile.close();
        }
        else cout << "Unable to open file";
        //Create a map with key:variable and value: expression to solve
        for (int i = 0; i < v.size(); i++)
        {
            vector<string> token;
            token = parse_expr(v[i], "=");
            //Strip whitespaces
            token[0].erase(remove_if(token[0].begin(), token[0].end(), isspace), token[0].end());
            token[1].erase(remove_if(token[1].begin(), token[1].end(), isspace), token[1].end());
            mymap.insert(pair<string, string>(token[0], token[1]));
        }
        cout << "Equation sets given:" << endl;
        for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
        {
            std::cout << it->first << " => " << it->second << 'n';
        }
        for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); it++)
        {
            //Also update the map
            mymap[it->first] = evaluate_eq(it->first);
        }
        cout << "Equation sets solved:" << endl;
        for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
        {
            std::cout << it->first << " => " << it->second << 'n';
        }
    
        char ch;
        cin >> ch;
    }