View difference between Paste ID: 2KTasY70 and 3j6jj0n0
SHOW: | | - or go back to the newest paste.
1-
#include <map>
1+
#include <algorithm>
2
#include <iostream>
3
#include <vector>
4
#include <complex>
5
#include <functional>
6
#include <stdexcept>
7
8
using namespace std;
9
class LINP
10
{
11-
	typedef map<int/*Index*/, double/*Coeff*/, greater<int> > value_type;
11+
12
	// Index => Coeff
13
	typedef vector<double> cont_type;
14-
	LINP(): cont() {
14+
15-
		cont[1] = 1;
15+
16-
	};
16+
	LINP(): cont() {}
17-
	LINP(int rhs): cont() {
17+
	LINP(double rhs): cont(1) {
18
		cont[0] = rhs;
19-
	};
19+
20
21-
	LINP operator [](int rhs) const {
21+
	LINP operator [](size_t rhs) const {
22-
		LINP tmp;
22+
		if (rhs == 0)
23-
		tmp.cont.clear();
23+
			return LINP(1);
24-
		tmp.cont[rhs] = getCoeffOfIndex(1);
24+
25
		while (--rhs != 0)
26
			tmp *= *this;
27
		return tmp;
28
	}
29
30-
			v.second *= rhs;
30+
31
		for (auto& v : cont)
32
			v *= rhs;
33
		return *this;
34
	}
35
	LINP operator *(double rhs) const {
36
		LINP tmp(*this);
37
		tmp *= rhs;
38
		return tmp;
39-
	LINP operator *=(const LINP& rhs) const {
39+
40-
		// Unimplimented
40+
41
	LINP& operator *=(const LINP& rhs) {
42
		if (rhs.cont.empty()) {
43
			cont.clear();
44
			return *this;
45
		} else if (this == &rhs) {
46
			return *this *= LINP(*this);
47
		}
48
		shrinkToFit();
49
		cont.reserve(rhs.maxIndex() + maxIndex());
50-
			this->cont[v.first] += v.second;
50+
51
		LINP tmp(*this);
52
		cont.clear();
53-
	
53+
		for (auto& v : rhs.cont) {
54
			if (v != 0)
55
				*this += tmp * v;
56
			tmp.cont.insert(tmp.cont.begin(), 0);
57
		}
58
		return *this;
59
	}
60
	LINP operator *(const LINP& rhs) const {
61
		LINP tmp(*this);
62-
			this->cont[v.first] -= v.second;
62+
63
		return tmp;
64
	}
65
66
	LINP& operator +=(const LINP& rhs) {
67
		// Seems safe when this == &rhs
68
		if (cont.size() < rhs.cont.size())
69
			cont.resize(rhs.cont.size());
70
		auto it = cont.begin();
71
		for (auto& v : rhs.cont)
72
			*it++ += v;
73-
			v.second = -v.second;
73+
74
	}
75
	LINP operator +(const LINP& rhs) const {
76
		LINP tmp(*this);
77
		tmp += rhs;
78-
		for (value_type::const_iterator it=rhs.cont.begin();
78+
79-
			it != rhs.cont.end(); ++it)
79+
80-
		{
80+
81-
			if (it->second != 0)
81+
82-
			{
82+
		if (this == &rhs) {
83-
				if ((it->second == 1 || it->second == -1) && it->first != 0)
83+
			cont.clear();
84-
				{
84+
		} else {
85-
					if (it->second < 0)
85+
			if (cont.size() < rhs.cont.size())
86-
						cout << '-';
86+
				cont.resize(rhs.cont.size());
87
			auto it = cont.begin();
88-
				else
88+
			for (auto& v : rhs.cont)
89-
					os << it->second;
89+
				*it++ -= v;
90-
				if (it->first != 0)
90+
91-
				{
91+
92-
					cout << "x";
92+
93-
					if (it->first != 1)
93+
94-
						cout << '[' << it->first << ']';
94+
95
		tmp -= rhs;
96
		return tmp;
97-
			os << '+';
97+
98
	LINP operator -() const {
99-
		cout << "\b \b";
99+
100
		for (auto& v : tmp.cont)
101
			v = -v;
102
		return tmp;
103-
	int maxIndex() const {
103+
104-
		return cont.begin()->first;
104+
105
	friend ostream& operator <<(ostream& os, const LINP& rhs) {
106-
	int minIndex() const {
106+
		if (rhs.cont.size() > 1) {
107-
		return cont.rbegin()->first;
107+
			for (cont_type::size_type idx = rhs.cont.size() - 1; idx != 0; --idx) {
108
				double coeff = rhs.cont[idx];
109
				if (coeff == 0)
110-
	double getCoeffOfIndex(int Index) const {
110+
					continue;
111-
		value_type::const_iterator it=cont.find(Index);
111+
				if (coeff < 0) {
112-
		return it != cont.end() ? it->second : 0;
112+
					os << "-";
113
					if (coeff != -1)
114
						os << -coeff;
115-
	vector<complex<double> > solve() const throw(exception)	{
115+
				} else {
116-
		if (maxIndex()>2 || minIndex()<0)
116+
					os << "+";
117-
			throw std::exception();
117+
					if (coeff != 1)
118
						os << coeff;
119-
		result.reserve(maxIndex());
119+
120-
		if (maxIndex()==1)
120+
				os << 'X';
121-
			result.push_back(-getCoeffOfIndex(0)/getCoeffOfIndex(1));
121+
				if (idx != 1)
122-
		else	// maxPow()==2
122+
					os << '[' << idx << ']';
123-
		{
123+
124-
			complex<double> delta=pow(getCoeffOfIndex(1), 2)-4*getCoeffOfIndex(2)*getCoeffOfIndex(0);
124+
125-
			result.push_back((-getCoeffOfIndex(1)+sqrt(delta))/(2*getCoeffOfIndex(2)));
125+
		if (!rhs.cont.empty()) {
126-
			result.push_back((-getCoeffOfIndex(1)-sqrt(delta))/(2*getCoeffOfIndex(2)));
126+
			double coeff = rhs.cont.front();
127
			if (coeff != 0) {
128
				if (coeff > 0)
129
					os << '+';
130
				os << coeff;
131
			}
132-
	value_type cont;
132+
		} else {
133
			os << '0';
134
		}
135
		return os;
136
	}
137-
	LINP linp=LINP()-(LINP()*0.5+1)-1;
137+
138
	void shrinkToFit() {
139
		cont.resize(maxIndex() + 1);
140
	}
141-
	LINP linp2=LINP()[2]+LINP()*2+1;
141+
142
	size_t maxIndex() const {
143
		return distance(find_if(cont.rbegin(), cont.rend(), [] (double coeff) {
144
			return coeff != 0;
145-
	LINP linp3=LINP()[2]+1;
145+
		}), cont.rend()) - 1;
146
	}
147
148
	double getCoeffOfIndex(size_t Index) const {
149-
		<< "x2 = " << result[1].real() << " + " << result[1].imag() << 'i' << endl << endl;
149+
		return Index > maxIndex() ? cont[Index] : 0;
150
	}
151
152
	vector<complex<double> > solve() const throw(invalid_argument)	{
153
		size_t maxIdx = maxIndex();
154
		if (maxIdx > 2)
155
			throw invalid_argument("只支持一次和二次多项式");
156
		vector<complex<double> > result;
157
		result.reserve(maxIdx);
158
		if (maxIdx == 1) {
159
			result.push_back(-cont[0] / cont[1]);
160
		} else {
161
			complex<double> delta=pow(cont[1], 2) - 4 * cont[2] * cont[0];
162
			result.push_back((+sqrt(delta) - cont[1]) / (2 * cont[2]));
163
			result.push_back((-sqrt(delta) - cont[1]) / (2 * cont[2]));
164
		}
165
		return result;
166
	}
167
168
	static LINP getX() {
169
		LINP x;
170
		x.cont.resize(2);
171
		x.cont.back() = 1;
172
		return x;
173
	}
174
175
private:
176
	cont_type cont;
177
};
178
179
int main()
180
{
181
	const static LINP X = LINP::getX();
182
	LINP expression = (X + 1)[3];
183
	cout << expression;
184
185
	LINP linp=X-(X*0.5+1)-1;
186
	cout << linp << " = 0" << endl;
187
	cout << "X = " << linp.solve().front().real() << endl << endl;
188
189
	LINP linp2=X[2] + X*2 + 1;
190
	cout << linp2 << " = 0" << endl;
191
	cout << "X1 = X2 = " << linp2.solve().front().real() << endl << endl;
192
193
	LINP linp3=X[2] + 1;
194
	cout << linp3 << " = 0" << endl;
195
	vector<complex<double> > result=linp3.solve();
196
	cout << "x1 = " << result[0].real() << " + " << result[0].imag() << 'i' << endl
197
		 << "x2 = " << result[1].real() << " + " << result[1].imag() << 'i' << endl
198
		 << endl;
199
}