Мы получаем довольно необычную ошибку. Наша программа пытается вычислить производные с использованием регулярных выражений и рекурсии.C++ regex, передавая эквивалентные строковые параметры, но получая разные выходы
Из нашего ввода файла мы использовали регулярное выражение для определения правила производной, которое мы должны применить. Используя smatch, мы можем анализировать различные части нашего уравнения струны.
Наша ошибка появляется, когда наша программа пытается вычислить производную для «(x^2) + (x)». Smatch анализирует «x^2» и «x» из этого уравнения и рекурсивно вызывает производную функцию, используя эти две строки в качестве параметров. Однако в нашем выпуске отсутствует производная от «x».
Вход:
(x^2)+(x)
Вызов:
return derivative(s[1].str()) + "+" + derivative(s[2].str());
Выход:
2x^1*1+
Однако, если мы пройдем:
return derivative(s[1].str()) + "+" + derivative("x");
Затем, выход становится:
2x^1*1+1
Мы также проверили, если (с [2] .str() == "х"), и это верно. Почему мы получаем разные результаты с одного входа?
Equations.txt:
7
x
5x
x^3
(x^2)+(x)
main.cpp:
#include <iostream>
#include <fstream>
#include <cmath>
#include <queue>
#include <stack>
#include <regex>
#include <vector>
#include <iterator>
#include <map>
#include <string>
using namespace std;
/*****************************************************************/
class ReadFile
{
private:
ifstream infile;
queue<string> input;
public:
ReadFile(string filename)
{
infile.open(filename);
if(!infile)
cerr << "Unable to open file\n";
string temp;
while(!infile.eof())
{
getline(infile, temp);
input.push(temp);
}
}
string getFront()
{
string temp = input.front();
input.pop();
return temp;
}
bool isEmpty() { return input.empty(); }
};
/*****************************************************************/
class Simplifier
{
private:
string exp;
public:
Simplifier(string ex): exp(ex) {}
};
/*****************************************************************/
class ExpressionAnalyzer
{
string expression;
map<string, regex> rules;
smatch s;
public:
ExpressionAnalyzer()
{
rules["con"] = "([[:d:]]+)";
rules["xxx"] = "(x|\\(x\\))";
rules["cof"] = "([[:d:]]+)(.*)";
rules["pow"] = "(.*)[^]([[:d:]]+)";
rules["add"] = "\\((.*)\\)[+]\\((.*)\\)";
}
string derivative(string str)
{
s = generateSmatch(str);
if(regex_match(str, rules["con"]))
return "0";
else if (regex_match(str, rules["xxx"]))
return "1";
else if (regex_match(str, rules["cof"]))
return s[1].str() + "*" + derivative(s[2].str());
else if (regex_match(str, rules["pow"]))
return s[2].str() + s[1].str() + "^" + to_string(stoi(s[2].str()) - 1) + "*" + derivative(s[1].str());
else if (regex_match(str, rules["add"])) {
cout << "s[1]: " << s[1].str() << ", s[2]: " << s[2].str() << endl;
return derivative(s[1].str()) + "+" + derivative(s[2].str());}
return "";
}
smatch generateSmatch(string str)
{
smatch s;
map<string, regex>::iterator it;
for(it = rules.begin(); it != rules.end(); it++)
{
if(regex_match(str, s, it->second))
{
return s;
}
}
return s;
}
};
/*****************************************************************/
int main()
{
ReadFile test("Equations.txt");
string s = test.getFront();
ExpressionAnalyzer e;
cout << e.derivative(s) << endl;
}
я не уверен, что актуальной проблемой является , но выполнение вашего кода на ideone дает следующие результаты: 'e.derivative (" (x) ")' возвращает '1' (что работает)' e.derivative ("(x^2)") 'возвращает пустую строку и 'e.derivative (" (x^2) + (x) ")' возвращает 1 + 1. Я думаю, что что-то с вашей рекурсией нарушено. Я бы предложил попробовать создать только конкретный smatch, который вам нужен внутри if, вместо того, чтобы перебирать все возможности, а затем использовать if. Я думаю, что это сделало бы ошибки более очевидными. – Anedar
У меня разные результаты в зависимости от clang/gcc ... – Jarod42