用映射求解线性方程

时间:2016-10-03 17:53:58

标签: c++ recursion maps

我几乎完成了编码以解决简单的线性方程组。似乎在地图导致问题的递归调用中遗漏了一些东西。

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

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 个答案:

答案 0 :(得分:0)

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

  1. 在main()
  2. 同时,通过条带化空白创建输入映射

    //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())
    
    1. 更新了我的find_VctrSum以更新此处的地图,这与之前尝试在evaluate_eq()中更新无关。
    2. //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;
      }