Я почти закончил кодирование, чтобы решить простой набор линейных уравнений. Просто кажется, что что-то не хватает в рекурсивном вызове с причинами, вызывающими Карту.Решить линейное уравнение с помощью карт
Вот постановка задачи для решения, например:
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
Программа вызывает неопределенное поведение из-за вы пытаетесь изменить возвращаемые содержимое 'n.c_str()' 'во время strtok_s' вызова , – PaulMcKenzie
см. Статус возврата карты. Он возвращает map.end(), если значение не найдено на карте. –
'// Non-const cast required. '-No. [strtok is destructive] (http://en.cppreference.com/w/c/string/byte/strtok). Прочитайте мелкий шрифт. Таким образом, вы не можете использовать возвращаемое значение 'c_str()', так как оно 'const'. – PaulMcKenzie