2016-10-03 4 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()) 

Любая помощь в выявлении проблемы или любом логическом пропуске была бы высоко оценена. Thanks

+0

Программа вызывает неопределенное поведение из-за вы пытаетесь изменить возвращаемые содержимое 'n.c_str()' 'во время strtok_s' вызова , – PaulMcKenzie

+0

см. Статус возврата карты. Он возвращает map.end(), если значение не найдено на карте. –

+0

'// Non-const cast required. '-No. [strtok is destructive] (http://en.cppreference.com/w/c/string/byte/strtok). Прочитайте мелкий шрифт. Таким образом, вы не можете использовать возвращаемое значение 'c_str()', так как оно 'const'. – PaulMcKenzie

ответ

0

После исправления пары логики мой код работает правильно.

  1. В главном()

While, создавая входную карта создает с помощью удаляющего пробельных

//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 для обновления здесь, в отличие от моей предыдущей попытки обновления в файле_цены_цены().

//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; 
} 
Смежные вопросы