リンクリストを使用した基本的な多項式読み取り値
-
19-09-2019 - |
質問
わかりました、多項式を読まなかった後、私は最初にこれに対する基本的なアプローチを試みています。
だから私は関数の読み取りと印刷を備えたクラスのポリノムを持っています:
#ifndef _polinom_h
#define _polinom_h
#include <iostream>
#include <list>
#include <cstdlib>
#include <conio.h>
using namespace std;
class polinom
{
class term
{
public:
double coef;
int pow;
term(){
coef = 0;
pow = 0;
}
};
list<term> poly;
list<term>::iterator i;
public:
void read(int id)
{
term t;
double coef = 1;
int pow = 0;
int nr_term = 1;
cout << "P" << id << ":\n";
while (coef != 0) {
cout << "Term" << nr_term << ": ";
cout << "coef = ";
cin >> coef;
if (coef == 0) break;
cout << " grade = ";
cin >> pow;
t.coef = coef;
t.pow = pow;
if (t.coef != 0) poly.push_back(t);
nr_term++;
}
}
void print(char var)
{
for (i=poly.begin() ; i != poly.end(); i++ ) { //going through the entire list to retrieve the terms and print them
if (poly.size() < 2) {
if (i->pow == 0) //if the last term's power is 0 we print only it's coefficient
cout << i->coef;
else if (i->pow == 1) {
if (i->coef == 1)
cout << var;
else if (i->coef == -1)
cout << "-" << var;
else
cout << i->coef << var;
}
else
cout << i->coef << var << "^" << i->pow; //otherwise we print both
}
else {
if (i == poly.end()) { // if we reached the last term
if (i->pow == 0) //if the last term's power is 0 we print only it's coefficient
cout << i->coef;
else if (i->pow == 1)
cout << i->coef << var;
else
cout << i->coef << var << "^" << i->pow; //otherwise we print both
}
else {
if (i->coef > 0) {
if (i->pow == 1)//if the coef value is positive
cout << i->coef << var << " + "; //we also add the '+' sign
else
cout << cout << i->coef << var << "^" << i->pow << " + ";
}
else {
if (i->pow == 1)//if the coef value is positive
cout << i->coef << var << " + "; //we also add the '+' sign
else
cout << cout << i->coef << var << "^" << i->pow << " + ";
}
}
}
}
}
};
#endif
まあ、それは1つの用語のみを読むときに機能しますが、より多くの読み取りの場合は、印刷係数がいくつかのランダム値であり、最後の用語の後には、「+」または「 - 」を印刷する必要があります。
何が悪いのか考えていますか?
ありがとう!
最終更新
わかりました、私はビルのコードを変更することで完全に機能しましたので、ビルと他のすべての人にコメントまたは答えてくれた人に感謝します!
これが最終的な印刷関数です:
void print(char var)
{
list<term>::iterator endCheckIter;
for (i=poly.begin() ; i != poly.end(); i++ )
{
//going through the entire list to retrieve the terms and print them
endCheckIter = i;
++endCheckIter;
if (i->pow == 0)
cout << i->coef;
else if (i->pow == 1)
cout << i->coef << var;
else
cout << i->coef << var << "^" << i->pow;
if (endCheckIter != poly.end()) {
if (endCheckIter->coef > 0)
cout << " + ";
else {
cout << " - ";
endCheckIter->coef *= -1;
}
}
}
}
解決
if (i == poly.end()) { // if we reached the last term
このコメントはあなたのエラーを示しています。特定のアイテムのコレクションについては、 items.end()
最後のアイテムの後にエントリを返します。
たとえば、5項目のstd :: vectorがあるとします。
[0] [1] [2] [3] [4]
次に、begin()ポイント:
[0] [1] [2] [3] [4]
/\
およびend()ポイント:
[0] [1] [2] [3] [4] []
/\
あなたのループのために、それは次のように見えます:
for (i=poly.begin() ; i != poly.end(); i++ )
比較することに注意してください i
に poly.end()
Iterが使用される前に起こります。出来るだけ早く i == poly.end()
, 、あなたは終わった。
内部のコード if (i == poly.end()) {
これは決して真実ではないので、決して実行されません。
以下を使用して最後にテストできます。
// get access to the advance function
#include <iterator>
....
std::list<term>::iterator endCheckIter = i;
std::advance(endCheckIter, 1);
if (endCheckIter == poly.end())
{
...
}
しかし、より簡単な方法は次のとおりです。
std::list<term>::iterator endCheckIter = i;
++endCheckIter;
if (endCheckIter == poly.end())
{
...
}
編集:なぜあなたがゴミを手に入れているのかわかりません。不足しているブレースを追加して、非エンドケースを処理すると、すべてがここで機能します。
void print(char var)
{
list<term>::iterator endCheckIter;
for (i=poly.begin() ; i != poly.end(); i++ )
{ // <- MISSING BRACE
//going through the entire list to retrieve the terms and print them
endCheckIter = i;
++endCheckIter;
cout << i->coef << var << "^" << i->pow; // <- MISSING OUTPUT
if (endCheckIter != poly.end()) {
if (i->coef > 0)
cout << " + ";
else
cout << " - ";
}
} // <- MISSING BRACE
}
他のヒント
さて、今、ヴラッドは彼がどのようになっているかを決めた 行く それをするために、ここに私がそれをする方法があります:
#ifndef _polinom_h
#define _polinom_h
#include <iostream>
#include <list>
#include <cstdlib>
#include <cmath>
#include "infix_iterator.h"
using namespace std;
char var;
class polinom {
class term {
double coef;
int power;
ostream &write(ostream &os) const {
// At least to me, the logic is easier to follow if we
// handle one piece at a time.
// It may be longer, but I think it's easier to understand.
// First, if the coefficient is negative, subtract the term instead of adding it.
if (coef < 0)
// backspace over the "+ " and print '- ' in its place.
os << "\b\b- ";
// Then print the absolute value of the coefficient (if needed).
if (fabs(coef) != 1)
os << fabs(coef);
// Then print the var (if needed)
if (power != 0)
os << var;
// then print the power (if needed)
if (abs(power) > 1)
os << "^" << power;
// And we're done.
return os;
}
// support inserting a term into a stream.
friend std::ostream &operator<<(std::ostream &os, term const &t) {
return t.write(os);
}
public:
term(double c=0.0, int p=0) : coef(c), power(p) {}
bool read(std::ostream &os, std::istream &is, int num) {
// This is only slightly modified from the originally posted question
os << "\nTerm " << num << ": coef = ";
is >> coef;
if (coef == 0.0)
return false;
if (coef != 0.0) {
os << " grade = ";
is >> power;
}
return true;
}
bool operator<(term const &other) const {
// order by descending powers.
return other.power < power;
}
};
list<term> poly;
public:
void read(int id) {
term t;
int nr_term = 1;
std::cout << "P: " << id;
// Read and save individual terms:
while (t.read(std::cout, std::cin, nr_term++))
poly.push_back(t);
}
void write(char var) {
// sort the polynomial so the highest powers come first.
poly.sort();
// save the variable name for later use.
::var = var;
// Print out all the terms:
std::copy(poly.begin(), poly.end(), infix_ostream_iterator<term>(std::cout, " + "));
}
};
#endif
これを使用することはかなり些細なことです:
#include "polynom.h"
int main() {
polinom p;
p.read(1);
p.write('x');
return 0;
}
void print(char var)
{
for (list<term>::const_iterator i = poly.begin(), e = poly.end(); i != e; ++i) {
if (i != poly.begin() || i->coef < 0) {
cout << (i->coef > 0 ? '+' : '-');
}
if (abs(i->coef) != 1) {
cout << abs(i->coef);
}
if (i->pow == 0) {
if (abs(i->coef) == 1) {
cout << 1;
}
} else {
cout << var;
if (i->pow != 1) {
cout << '^' << i->pow;
}
}
}
}