반응형
다항식을 입력, 출력, 계산하는 프로그램을 구현한다.
다항식은 객체(class)로 생성해야 하며, 다항식 연산을 위하여 연산자 오버로딩 기능을 이용한다.
- 다항식 a, b, c를 입력받아 문제에 주어진 연산을 수행한다.(다양한 입력 예를 테스트하는 것을 추천함)
- 다항식 입력은 (계수, 지수) 표현 형태를 이용한다.
- 다항식의 출력 형식은 첨부파일과 같은 형식을 따른다.
- 첨부파일의 프로그램 코드를 실행한다.
입력물: 다항식 a, b, c, 정수 x
출력물: 첨부파일의 프로그램 코드를 실행한 결과물(출력 결과물).
* 연산자 오버로딩을 구현해야함.
* 프로그램 내용 외에 다른 내용이 출력된다면 감점이 될 수 있으니 유의바람.
입력은 0~9까지로 음수 예외처리는 하지 않으셔도 됩니다.
Code
#include <iostream>
#include <cmath>
using namespace std;
class Polynomial; // 전방선언
class Term { // (계수,지수)
friend Polynomial;
friend istream& operator>>(istream& in, Polynomial& p); // 다항식의 입력. 연산자 오버로딩
friend ostream& operator<<(ostream& out, Polynomial& p); // 다항식의 출력. 연산자 오버로딩
private:
int coef; // 계수 0~9
int exp; // 지수 0~9, 음수 입력시 처음으로
};
class Polynomial {
private:
Term* termArray; // nonzero term들의 배열
int capacity; // termArray의 최대크기
int terms; // nonzero term의 수
public:
Polynomial(); // 생성자. 다항식 p(x) = 0을 반환
//~Polynomial();
friend istream& operator>>(istream& in, Polynomial& p); // 다항식의 입력. 연산자 오버로딩
friend ostream& operator<<(ostream& out, Polynomial& p); // 다항식의 출력. 연산자 오버로딩
void NewTerm(const int theCoeff, const int theExp); // 새로운 항을 termArray에 끝에 첨가
Polynomial operator+(Polynomial& B); // *this와 B(x)를 더한 결과 반환, 연산자 오버로딩
Polynomial operator*(Polynomial& B); // *this와 B(x)를 곱한 결과 반환, 연산자 오버로딩
Polynomial sMultPoly(int single_Coef, int single_Exp); // 다항식의 단항 곱셈
void sortPoly(); // 지수의 내림차순으로 출력 - 선택정렬
int evalPoly(int x); // *this에 x를 대입해서 계산한 결과 반환
int polyterms() { return terms; }
};
Polynomial::Polynomial() : capacity(1), terms(0)
{
// capacity = 1, terms = 0 으로 초기화
termArray = new Term[capacity];
}
void Polynomial::NewTerm(const int theCoeff, const int theExp)
{
if (terms == capacity) // termArray가 꽉 차면 두배로 확장
{
capacity *= 2;
Term* temp = new Term[capacity]; // 새로운 배열
copy(termArray, termArray + terms, temp); // 기존 termArray에 있던 내용을 새로 확장된 termArray로 옮겨줌
delete[] termArray; // 그 전 메모리 반환
termArray = temp;
}
// termArray의 크기에 문제 없으면, 배열 끝에 값들 첨가
termArray[terms].coef = theCoeff;
termArray[terms++].exp = theExp;
}
istream& operator>>(istream& in, Polynomial& p) // 6. >> 오버로딩
{
string poly;
int coef = 0;
int exp = 0;
int count = 1;
poly.clear(); // string poly 초기화
in >> poly; // (계수,지수)(계수,지수)...꼴의 입력을 통째로 string으로 받아옴
if (poly[0] == '.') exit(0); // 1. . 종료
for (int i = 0; i < poly.length(); i++) // 계수, 지수는 0~9 정수
{
if (isdigit(poly[i])) { // isdigit : 문자가 숫자 0~9 사이에 속하는지 검사하는 함수
// isdigit 성립하면서 count가 홀수면 그것은 계수, 짝수면 지수
if (count % 2 == 1) coef = poly[i] - '0'; // char 데이터형을 int로 변환하기 위해 -'0'
if (count % 2 == 0) {
exp = poly[i] - '0';
// 이미 입력한 항들 중, 현재 입력된 항과 지수가 같은 항이 존재하는지 확인
int sameornot = -1;
for (int check_exp = 0; check_exp < p.polyterms() ; check_exp++) {
if (exp == p.termArray[check_exp].exp) sameornot = check_exp;
}
if ((sameornot == -1) && coef != 0) p.NewTerm(coef, exp); // 없다면 NewTerm으로 새로 추가 (단, 계수가 0이 아닐 때)
else p.termArray[sameornot].coef += coef; // 같은 항이 존재한다면 거기에 계수만 더해줌
}
count++;
}
}
return in;
}
void Polynomial::sortPoly() // 지수 내림차순 선택정렬
{
for (int i = 0; i < terms; i++)
{
int j = i;
for (int k = i + 1; k < terms; k++) {
if (termArray[k].exp > termArray[j].exp) j = k;
}
swap(termArray[i].exp, termArray[j].exp);
swap(termArray[i].coef, termArray[j].coef); // 지수가 swap됨에 따라 계수도 같이 swap 해준다.
}
}
ostream& operator<<(ostream& out, Polynomial& p) // 6. << 오버로딩
{
p.sortPoly(); // 지수의 내림차순으로 먼저 정렬
// 계수, x^ or x or none, 지수, +연산자 순으로 차례대로 출력
for (int i = 0; i < p.terms; i++)
{
if (p.termArray[i].coef > 1) out << p.termArray[i].coef; // possible coef 1~9 중 1보다 큰 계수만 출력
if ((p.termArray[i].coef == 1) && (p.termArray[i].exp == 0)) out << p.termArray[i].coef; // 상수항이 1일 때의 예외처리
if (p.termArray[i].exp > 1) out << "x^"; // 지수가 2 이상이어야 x^num 꼴로 출력
if (p.termArray[i].exp == 1) out << "x"; // 지수가 1일땐 x만 출력
if (p.termArray[i].exp > 1) out << p.termArray[i].exp; // 지수가 2 이상일 때만 지수 따로 출력
if (i != p.terms - 1) out << " + "; // 계수가 1~9(양수)니까 +만 출력 (종료시까지, 마지막 항 뒤에 + 출력 되지 않도록 주의)
}
out << endl;
return out;
}
Polynomial Polynomial::operator+(Polynomial& B) // 5. + 오버로딩
{
Polynomial AddResult; // 계산 결과 저장
int aPos = 0, bPos = 0; // 각 A,B 에서 계산할 항
while ((aPos < terms) && (bPos < B.terms)) // A,B 지수가 같은 경우
{
if (termArray[aPos].exp == B.termArray[bPos].exp)
{
int t = termArray[aPos].coef + B.termArray[bPos].coef; // 계수 더한 결과, 0이면 버림
if (t) AddResult.NewTerm(t, termArray[aPos].exp);
aPos++; bPos++;
}
else if (termArray[aPos].exp < B.termArray[bPos].exp) // A 지수가 더 큰 경우
{
AddResult.NewTerm(B.termArray[bPos].coef, B.termArray[bPos].exp);
bPos++;
}
else // B 지수가 더 큰 경우
{
AddResult.NewTerm(termArray[aPos].coef, termArray[aPos].exp);
aPos++;
}
}
for (; aPos < terms; aPos++) // B의 항 다 쓰고 A에 항들이 남은 경우
AddResult.NewTerm(termArray[aPos].coef, termArray[aPos].exp);
for (; bPos < B.terms; bPos++) // A의 항 다 쓰고 B에 항들이 남은 경우
AddResult.NewTerm(B.termArray[bPos].coef, B.termArray[bPos].exp);
return AddResult;
}
Polynomial Polynomial::sMultPoly(int single_Coef, int single_Exp) // 2. sMultPoly(c,e)
{
Polynomial sMultResult; // 계산 결과 저장
int pos;
// 기준이 되는 다항식의 각 항에, 입력된 단항식의 계수를 곱하고, 지수는 더해준다.
for (pos = 0; pos < terms; pos++)
{
int smult_coef = termArray[pos].coef * single_Coef;
int smult_exp = termArray[pos].exp + single_Exp;
int place = -1; // 새로운 항을 저장할 인덱스
for (int i = 0; i < sMultResult.terms; i++) {
if (sMultResult.termArray[i].exp == smult_exp) place = i; // 같은 지수인 인덱스가 있다면 place에 저장
}
if (place == -1) sMultResult.NewTerm(smult_coef, smult_exp); // 같은 지수인 인덱스가 없다면 끝에 새로 추가
else sMultResult.termArray[place].coef += smult_coef; // 같은 지수인 인덱스 있으면 계수끼리만 더해준다.
}
return sMultResult;
}
Polynomial Polynomial::operator*(Polynomial& B) // 4. * 오버로딩
{
Polynomial tempMult; // sMultPoly이 return하는 polynomial 임시로 저장
Polynomial MultResult; // 계산 결과 저장
int pos = 0; // B에 곱해줄 A의 항
// B(x)에 A(x)의 단항식을 차례대로 곱한다. 그 곱셈 결과들을 다 더해준다.
for (pos = 0; pos < terms; pos++)
{
tempMult = B.sMultPoly(termArray[pos].coef, termArray[pos].exp);
MultResult = MultResult + tempMult;
}
return MultResult;
}
int Polynomial::evalPoly(int x) // 3. evalPoly(c)
{
int eval = 0;
for (int i = 0; i < terms; i++)
{
eval += termArray[i].coef * pow(x, termArray[i].exp);
}
return eval;
}
int main()
{
cout << "다항식 A,B,C 와 x 값을 입력하세요 >> ";
while (1) {
Polynomial a, b, c, d, t; // a,b,c 다항식 읽고 생성, t=a*b, d=t+c
int x; // 다항식의 x에 대입할 값
cin >> a;
cin >> b;
cin >> c;
cout << "A(x) = " << a;
cout << "B(x) = " << b;
cout << "C(x) = " << c;
t = a * b;
d = t + c;
cout << "T(x) = " << t;
cout << "D(x) = " << d;
cin >> x;
cout << "x = " << x << " --> " << d.evalPoly(x) << '\n' << endl;
cout << "다항식 A,B,C 와 x 값을 입력하세요 >> ";
}
return 0;
}
실행결과
점수 10/10
❤와 댓글은 큰 힘이 됩니다. 감사합니다 :-)
반응형
'Schoolwork > 자료구조와 C++프로그래밍' 카테고리의 다른 글
[C++] 9주차 과제6 (0) | 2020.08.05 |
---|---|
[C++] 7주차 과제5 (0) | 2020.08.05 |
[C++] 3주차 과제3 (0) | 2020.08.05 |
[C++] 2주차 과제2 (0) | 2020.08.05 |
[C++] 1주차 과제1 (0) | 2020.08.05 |