2016-10-03 69 views
0

我已經基本完成了編碼來求解簡單的線性方程組。似乎在地圖引發問題的遞歸調用中丟失了一些東西。用地圖求解線性方程

這是問題的語句來解決,例如:

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

考慮:LHS將只是變量名。 RHS只有變量,無符號整數和'+'運算符。解決所有未知問題。

解決方案,我用我的代碼獲得:

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()) 

在識別問題或任何邏輯經過任何幫助,將不勝感激。 謝謝

+0

程序調用未定義的行爲是由於你試圖改變n.c_str的'返回的內容()''的通話strtok_s'期間。 – PaulMcKenzie

+0

查看地圖的返回狀態。如果在地圖中找不到值,則返回map.end()。 –

+0

'//需要非常量轉換。 - 不是。 [strtok是破壞性的](http://en.cppreference.com/w/c/string/byte/strtok) - 閱讀細則。因此你不能使用'c_str()'的返回值,因爲它是'const'。 – PaulMcKenzie

回答

0

修復了幾個邏輯後,我的代碼正常工作。

  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()) 
  1. 更新了我的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中[鍵] = to_string(總和);

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