Я нашел эти две библиотеки:
— Мупарсер
— symbolicc ++
Первый способен эффективно разбирать математические выражения, чтобы с минимальным переносом я мог создать объект парсера, чтобы
parser my_parser("1/2 * x^2");
cout<<myparser(2)<<endl;
Это привело бы к печати 2.0. Это замечательно, но работает только с двойниками, верно?
Второй реализует объект Symbolic, так что в примере я могу сделать что-то вроде:
Symbolic x("x");
Symbolic x2 = x^2;
cout<<df(x2, x)<<endl;
В результате 2.0 * х. Так что он способен различать выражения, и это нормально.
Что мне нужно сделать, это сочетание двух! Мне нужно, чтобы функция была проанализирована, а затем дифференцирована, чтобы я мог сделать что-то вроде:
cout<<df("1/2 * x^2", "x")<<endl;
И я хотел бы, чтобы он также распечатал 2.0 * x.
Можно ли сделать что-то подобное? В принципе, если бы muparser мог работать с любым объектом, я мог бы просто запустить выражение для символических объектов, а затем дифференцировать их. Но я не мог сделать что-то вроде этой работы.
Так есть ли другой обходной путь? Мне нужно что-то, что принимает входную строку с выражением и возвращает выходную строку с производной этого выражения.
Спасибо!
Это не полный отвечу, так как, как говорится, TMTOWTDI. Однако, чтобы иметь возможность использовать Symbolic ++, вам нужно иметь доступ на уровне программы… то есть вы не можете писать и компилировать
Symbolic x("x");
Symbolic x2 = x^2;
но нужно что-то порядка (но waaaaay более гибкий, чем)
if (there_is_x_symbol) {
expr = Symbolic x("x");
}
if (raise_to_the_2nd_power) {
expr = expr^2;
}
Чтобы сделать это органично, вы необходимость парсер и парсер, который не просто экспортирует evaluate()
метод, но то, что позволит вам получить доступ к дереву выражений, например
( multiply )
/ \
( 2 ) ( square )
\
( x )
Это вы можете оценить рекурсивно:
left = myEvaluate(node.left)
right = myEvaluate(node.right)
if (node.op == multiply) {
return left * right;
}
if (node.op == square ) {
return right ^ 2;
}
...
Библиотеки muparser (и muparserX), похоже, не позволяют этого.
Есть несколько других алгебраических парсеров, например этот выглядит многообещающе Вы можете использовать алгоритм Parser поставщика и написать собственный оценщик, который использует Symbolic ++ и выводит выражение Symbolic ++.
Вам не нужны глубокие знания грамматики, чтобы взломать такой парсер — большинство просто сгенерирует Обратная польская запись стек, и это все, что вам действительно нужно знать.
В Бокка Аль Лупо 🙂