2016-10-03 20 views
0

私はほぼ単純な線形方程式を解くためのコーディングを完了しました。マップを使って再帰呼び出しで何かが見つからないことが原因で問題が発生したようです。ここでマップで線形方程式を解く

解決する問題文は、例です。

考える
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()) 

問題や論理的な経過を特定する際の助けがあれば幸いです。 ありがとう

+0

。 – PaulMcKenzie

+0

地図の返品状況を確認してください。マップに値が見つからない場合、map.end()を返します。 –

+0

'//非constキャストが必要です.' - いいえ。 [strtokは破壊的である](http://en.cppreference.com/w/c/string/byte/strtok) - 小文字を読んでください。したがって 'c_str()'の戻り値は 'const'なので使用できません。 – PaulMcKenzie

答えて

0

論理のカップルを固定した後、私のコードは正しく動作します。入力マップが空白

//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])); 
    } 

をストライピングすることにより、作成作成)(メイン

しばらく

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

    完全な作業コードである - `strtok_s`通話中に`)プログラムは(n.c_str `の返された内容を変更しようとするため、あなたに未定義の振る舞いを呼び出す

    #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; 
    } 
    
関連する問題