Я строю приложение, написанное на C ++, которое в значительной степени включает алгебру. Я решил использовать GiNaC для системы компьютерной алгебры (CAS). Она работает отлично; Однако есть небольшая проблема. Порядок элементов не такой, каким я хочу, чтобы они были в выводе. Позвольте мне привести пример. Это мой код C ++:
#include <iostream>
#include <ginac/ginac.h>
int main()
{
using namespace GiNaC;
symbol x("x");
ex poly((x^2)+3*x+5);
std::cout << poly;
}
Выход этой программы:
5+x^2+3*x
Ну, я обнаружил, что это не является постоянным, выход также может быть:
5+3*x+x^2
Хотя, оба математически правильные формы, которую я хочу (или, может быть, мне нужно 🙂 ни один из них. Я хочу, чтобы полином начинался с наибольшей степени, т.е. мой вывод должен быть:
x^2+3*x+5
Эта проблема еще хуже, когда мы добавляем числа со знаком, парантез или более сложное алгебраическое выражение (иногда даже пишем (-3 + a) x, что выглядит очень некрасиво 🙂 std::cout<<GiNaC::latex
не решает проблему. И на мой взгляд, самая раздражающая часть — это неустойчивое поведение результатов.
Возможно ли что-то подобное в GiNaC. Я также не хочу иметь действительно грязный код (потому что C ++ 0x <regex>
библиотека может сделать это легко, но я бы не хотел использовать регулярные выражения, мой код достаточно сложный)
Я использую GCC 4.7.2 под Ubuntu Quantal Quetzal. Спасибо за помощь.
Поведение, на которое вы ссылаетесь, задокументировано Вот, и это не похоже на встроенную функциональность для обработки этого случая.
В соответствии с этот Вы должны реализовать это самостоятельно. Ниже приведен краткий пример кода, как это можно сделать.
#include <iostream>
#include <vector>
#include <algorithm>
#include <ginac/ginac.h>
int main()
{
using namespace GiNaC;
symbol x("x");
ex poly(-3*x-5+power(x,2));
std::vector<ex> terms(poly.begin(), poly.end());
std::sort(std::begin(terms), std::end(terms),
[x](const ex& lhs, const ex& rhs) { return lhs.degree(x)>rhs.degree(x); });
bool first{ true };
for(auto term : terms) {
if( first ) first = false;
else if( term.coeff(term)>0) std::cout << '+' ;
std::cout << term;
}
std::cout << std::endl;
}
Других решений пока нет …