比如说我先定义一个单项式类为这种形式:
a * pow(p, n) * pow(q, m)
其中 a, m, n 都是整数,p 和 q 是两个字符,然后现在我想定义操作一个更复杂的类,就是一般所说的多项式,但是它要满足我添加一个单项式进来之后仍然还是一个多项式的要求。。
用了下 chatgpt 对照着写了下大概完成了(手法很原始,抱歉我实在没啥基础)
#include <iostream>
using namespace std;
#include <string>
#include <vector>
// We define first the monomial class to be of the form a * pow(p, n) * power(q, m). We also fix the variables p, q here.
class Mono {
public:
int coefficient;
int power1;
int power2;
Mono(int a, int n = 0, int m = 0) : coefficient(a), power1(n), power2(m) {}
};
class Poly {
friend ostream & operator<<(ostream & os, const Poly & poly);
private:
vector<Mono> terms;
public:
Poly & addTerm(const Mono & term) {
terms.push_back(term);
return * this;
}
};
ostream & operator<<(ostream & os, const Poly & poly) {
for (size_t i = 0; i < poly.terms.size(); i++) {
const auto & term = poly.terms[i];
if (term.coefficient != 0) {
if (term.power1 == 0 && term.power2 == 0) {
os << term.coefficient;
}
else if (term.power1 == 0) {
os << term.coefficient << " * pow(q, " << term.power2 << ")";
}
else if (term.power2 == 0) {
os << term.coefficient << " * pow(p, " << term.power1 << ")";
}
else {
os << term.coefficient << " * pow(p, " << term.power1 << ") * " << "pow(q, " << term.power2 << ")";
}
if (i < poly.terms.size() - 1) {
os << " + ";
}
}
}
return os;
}
int main() {
Poly poly;
poly.addTerm(Mono(3)).addTerm(Mono(0,1)).addTerm(Mono(1,1)).addTerm(Mono(1,0,1)).addTerm(Mono(2,2,2));
cout << "Polynomial:\n" << poly << endl;
return 0;
}
输出结果是
Polynomial:
3 * pow(p, 2) * pow(q, 1) + 5 * pow(p, 2) * pow(q, 1)
上面 append 里的输出结果复制错了,应该是
Polynomial:
3 + 1 * pow(p, 1) + 1 * pow(q, 1) + 2 * pow(p, 2) * pow(q, 2)
1
jones2000 40 天前
不就是一个四则运算, 直接字符解析下, 不完是了, 计算机本科“编译原理”就有。 压栈出栈。
|
2
c0xt30a 40 天前
你可能需要模版表达式跟操作符重载这两个特性(手法)。前者不如后者常见,你搜索下 C++ expression templates
|
3
molika 40 天前
写个逆波兰表达式就完事了.
|
4
ipwx 40 天前 1
楼主要不要试试怎么能让你的 C++ 程序支持:
auto p = Symbol("p"); auto q = Symbol("q"); auto expression = 3 * pow(p, 2) * pow(q, 1) + 5 * pow(p, 2) * pow(q, 1); std::cout << expression << std::endl; |
5
BRS5672023 OP @ipwx 我试了一下,大概是下面的形式
``` #include <iostream> using namespace std; #include <string> #include <vector> class Mono { public: int coefficient; char variable1; int power1; char variable2; int power2; Mono(int a, char p, int n = 0, char q = '1', int m = 0) : coefficient(a), variable1(p), power1(n), variable2(q), power2(m) {} bool isSameTerm(const Mono & other) { return(variable1 == other.variable1 && power1 == other.power1 && variable2 == other.variable2 && power2 == other.power2); } }; Mono operator * (int coef, const Mono & mono) { return Mono(coef * mono.coefficient, mono.variable1, mono.power1, mono.variable2, mono.power2); } Mono operator * (const Mono & lhs, const Mono & rhs) { if (lhs.variable2 == '1' && rhs.variable2 == '1') { return Mono(lhs.coefficient * rhs.coefficient, lhs.variable1, lhs.power1, rhs.variable1, rhs.power1); } else if (lhs.variable1 == rhs.variable1 && lhs.variable2 == '1') { if (rhs.variable2 == '1') { return Mono(lhs.coefficient * rhs.coefficient, lhs.variable1, lhs.power1 + rhs.power1); } return Mono(lhs.coefficient * rhs.coefficient, lhs.variable1, lhs.power1 + rhs.power1, lhs.variable2, lhs.power2); } else if (lhs.variable1 == rhs.variable1 && rhs.variable2 == '1') { // We do not need consider the case when the second variable of lhs is '1', which was already contained in the last case. return Mono(lhs.coefficient * rhs.coefficient, lhs.variable1, lhs.power1 + rhs.power1, rhs.variable2, rhs.power2); } else if (lhs.variable1 == rhs.variable1 && lhs.variable2 == rhs.variable2) { return Mono(lhs.coefficient * rhs.coefficient, lhs.variable1, lhs.power1 + rhs.power1, lhs.variable2, lhs.power2 + rhs.power2); } else if (lhs.variable1 == rhs.variable2 && lhs.variable2 == rhs.variable1) { return Mono(lhs.coefficient * rhs.coefficient, lhs.variable1, lhs.power1 + rhs.power2, lhs.variable2, lhs.power2 + rhs.power1); } throw -1; } Mono pow(char variable, int power) { return Mono(1, variable, power); } class Poly { friend ostream & operator << (ostream & os, const Poly & poly); private: vector<Mono> terms; public: Poly & addTerm(const Mono & term) { terms.push_back(term); return * this; } Poly & operator + (const Mono & term) { addTerm(term); return * this; } void simplify() { for (size_t i = 0; i < terms.size(); i++) { for (size_t j = i + 1; j < terms.size(); j++) { if (terms[i].isSameTerm(terms[j])) { terms[i].coefficient = terms[i].coefficient + terms[j].coefficient; terms.erase(terms.begin() + j); j--; } } } } }; ostream & operator << (ostream & os, const Poly & poly) { for (size_t i = 0; i < poly.terms.size(); i++) { const auto & term = poly.terms[i]; if (term.coefficient != 0) { if (term.power1 == 0 && term.power2 == 0) { os << term.coefficient; } else if (term.power1 == 0) { os << term.coefficient << " * pow(" << term.variable2 << ", " << term.power2 << ")"; } else if (term.power2 == 0) { os << term.coefficient << " * pow(" << term.variable1 << ", " << term.power1 << ")"; } else { os << term.coefficient << " * pow(" << term.variable1 << ", " << term.power1 << ") * " << "pow(" << term.variable2 << ", " << term.power2 << ")"; } if (i < poly.terms.size() - 1) { os << " + "; } } } return os; } int main() { try { Poly poly; poly = poly + (3 * pow('p', 2) * pow('q', 1)) + (5 * pow('p', 2) * pow('q', 1)) + (2 * pow('p', 1) * pow('q', 1)); cout << "Polynomial before simplification:\n" << poly << endl; poly.simplify(); cout << "Polynomial after simplification:\n" << poly << endl; } catch(int err0) { cout << "You must input polynomials of two variables with aligned variables for multiplication!" << endl; cout << "Error number: " << err0 << endl; } return 0; } ``` 问题是我这样写就必须这样定义一个多项式 ``` Poly poly; poly = poly + (3 * pow('p', 2) * pow('q', 1)) + (5 * pow('p', 2) * pow('q', 1)) + (2 * pow('p', 1) * pow('q', 1)); ``` 还有就是无法区分 pow(p, n) * pow(q, m) 和 pow(q, m) * pow(p, n) 这两种形式(除非我指定两个 char 的顺序);不过第二个问题就是我一开始想要的对于非交换的多项式的计算。。(然后我期待可以计算两个多项式的对易子,最后计算得到关于 p q 的对易子的一个多项式) |
6
BRS5672023 OP 上面的程序输出的结果是
``` Polynomial before simplification: 3 * pow(p, 2) * pow(q, 1) + 5 * pow(p, 2) * pow(q, 1) + 2 * pow(p, 1) * pow(q, 1) Polynomial after simplification: 8 * pow(p, 2) * pow(q, 1) + 2 * pow(p, 1) * pow(q, 1) ``` |
7
blacktail 39 天前
看最后的回复,这是要多项式化简?
|
8
BRS5672023 OP |
9
ipwx 39 天前
@BRS5672023 把 Mono 再拆开成为最基本的形式比较好。那样的话自然可以区分 p * q 或者 q * p 了。
|