IT 프로그래밍/객체지향프로그래밍

[C++] 다항함수 계산기 [5-2]

기술1 2024. 6. 15. 12:02
반응형

다항함수 계산기 C++

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

class Term {
	friend class Polynomial;
private:
	int coef;
	int expo;
	Term() = default;
	Term(int c, int e) : coef(c), expo(e) {}
public:
	int calc(int x) {
		return coef * pow(x, expo);
	}
	void print(ostream& out) {
		out << coef << "x^" << expo;
	}
};

class Polynomial {
	friend void print_poly(Polynomial p, ostream& out);
private:
	char name;
	vector<Term> terms;
public:
	Polynomial() = default;
	Polynomial(char pname) : name(pname) {}

	char get_name() {
		return name;
	}
	void set_name(char c) { //내부에서 이름 변경 
		name = c;
	}
	int calc(int x) {
		int result = 0;
		for (auto t : terms)
			result += t.calc(x);
		return result;
	}

	void add_term(int coef, int expo) {
		auto it = terms.begin();
		while (it != terms.end() && it->expo > expo)
			it++;

		if (it != terms.end() && it->expo == expo) {
			it->coef += coef;
			if (it->coef == 0)
				terms.erase(it);
		}
		else {
			terms.insert(it, Term(coef, expo));
		}
	}
};

void print_poly(Polynomial p, ostream& out) {
	cout << p.name << "=";
	for (auto t : p.terms) {
		t.print(out);
		out << " + ";
	}
}

class PolyCalculator {
private:
	vector<Polynomial> polys;

	vector<Polynomial>::iterator find(char name) {
		for (auto it = polys.begin(); it != polys.end(); it++) {
			if (it->get_name() == name)
				return it;
		}
		return polys.end();
	}
public:
	void create_or_update_poly(char name) {
		Polynomial p(name);
		auto it = find(name);
		if (it != polys.end())
			*it = p;
		else
			polys.push_back(p);
	}
	void add_term_to(char name, int coef, int expo) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefiened polynomial !" << endl;
		else
			it->add_term(coef, expo);
	}
	void calc_poly(char name, int x) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefiened polynomial !" << endl;
		else
			cout << it->calc(x) << endl;
	}
	void print_pol(ostream& out, char name) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefined polynomial !" << endl;
		else {
			print_poly(*it, out);
			out << endl;
		} 
	}
	void copy_poly(char name, char new_name) {
		auto it = find(name);
		if (it == polys.end()) {
			cout << "Undefined polynomial" << endl;
			return;
		}
		Polynomial q = *it;
		q.set_name(new_name);
		it = find(new_name);
		if (it == polys.end())
			polys.push_back(q);
		else
			*it = q;
	}
	void delete_poly(char name) {
		auto it = find(name);
		if (it == polys.end()) {
			cout << "Undefined polynomial !" << endl;
			return;
		}
		polys.erase(it);
	}
	void list_polys(ostream& out) {
		for (auto p : polys) {
			print_poly(p, out);
			out << endl;
		}
	}
};

void process_command(PolyCalculator& calculator) {
	char name, new_name;
	int coef, expo, x;
	string command;
	while (true) {
		cout << "$ ";
		cin >> command;
		if (command == "print") {
			cin >> name;
			calculator.print_pol(cout, name);
		}
		else if (command == "calc") {
			cin >> name >> x;
			calculator.calc_poly(name, x);
		}
		else if (command == "create") {
			cin >> name;
			calculator.create_or_update_poly(name);
		}
		else if (command == "add") {
			cin >> name >> coef >> expo;
			calculator.add_term_to(name, coef, expo);
		}
		else if (command == "copy") {
			cin >> name >> new_name;
			calculator.copy_poly(name, new_name);
		}
		else if (command == "delete") {
			cin >> name;
			calculator.delete_poly(name);
		}
		else if (command == "list") {
			calculator.list_polys(cout);
		}
		else if (command == "exit")
			break;
	}
}

int main() {
	PolyCalculator calculator;
	process_command(calculator);
	return 0;
}

 이 코드는 다항식을 관리하고 계산하는 프로그램입니다. 클래스와 함수들을 이용해 다항식을 생성, 수정, 삭제하고, 이를 통해 주어진 값을 계산하거나 출력할 수 있습니다. 각 부분을 하나씩 설명하겠습니다.

Term 클래스
Term 클래스는 다항식의 항(term)을 나타냅니다.

coef: 항의 계수(coefficient)
expo: 항의 지수(exponent)
calc(int x): 주어진 x 값에 대해 항의 값을 계산합니다.
print(ostream& out): 항을 "coef x^expo" 형식으로 출력합니다.
Polynomial 클래스
Polynomial 클래스는 다항식을 나타냅니다.

name: 다항식의 이름
terms: 다항식을 구성하는 항들의 벡터
get_name(): 다항식의 이름을 반환합니다.
set_name(char c): 다항식의 이름을 설정합니다.
calc(int x): 주어진 x 값에 대해 다항식의 값을 계산합니다.
add_term(int coef, int expo): 다항식에 항을 추가합니다. 만약 같은 지수의 항이 존재하면 계수를 더하고, 그렇지 않으면 새로운 항을 추가합니다.

print_poly 함수
다항식을 출력하는 함수로, 다항식의 이름과 항들을 "coef x^expo + ..." 형식으로 출력합니다.

PolyCalculator 클래스
다항식을 관리하는 클래스입니다.

polys: 다항식 객체들을 저장하는 벡터
find(char name): 주어진 이름의 다항식을 찾아서 반환합니다.
create_or_update_poly(char name): 주어진 이름의 다항식을 생성하거나 업데이트합니다.
add_term_to(char name, int coef, int expo): 주어진 이름의 다항식에 항을 추가합니다.
calc_poly(char name, int x): 주어진 이름의 다항식을 계산합니다.
print_pol(ostream& out, char name): 주어진 이름의 다항식을 출력합니다.
copy_poly(char name, char new_name): 다항식을 복사합니다.
delete_poly(char name): 주어진 이름의 다항식을 삭제합니다.
list_polys(ostream& out): 저장된 모든 다항식을 출력합니다.


process_command 함수
사용자의 명령을 처리하는 함수입니다. 명령에 따라 적절한 작업을 수행합니다.

print: 주어진 이름의 다항식을 출력합니다.
calc: 주어진 이름의 다항식을 주어진 x 값으로 계산합니다.
create: 새로운 다항식을 생성합니다.
add: 다항식에 항을 추가합니다.
copy: 다항식을 복사합니다.
delete: 다항식을 삭제합니다.
list: 모든 다항식을 출력합니다.
exit: 프로그램을 종료합니다.


main 함수
PolyCalculator 객체를 생성하고, process_command 함수를 호출하여 명령을 처리합니다.

이 프로그램은 사용자가 명령어를 통해 다항식을 생성, 수정, 계산, 삭제, 출력할 수 있도록 설계되어 있습니다.

 

find save 추가 전체 코드

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;

class Term {
	friend class Polynomial;
private:
	int coef;
	int expo;
	Term() = default;
	Term(int c, int e) : coef(c), expo(e) {}
public:
	int calc(int x) {
		return coef * pow(x, expo);
	}
	void print(ostream& out) {
		out << coef << "x^" << expo;
	}
};

class Polynomial {
	friend void print_poly(Polynomial p, ostream& out);
private:
	char name;
	vector<Term> terms;
public:
	Polynomial() = default;
	Polynomial(char pname) : name(pname) {}

	char get_name() {
		return name;
	}
	void set_name(char c) { //내부에서 이름 변경 
		name = c;
	}
	int calc(int x) {
		int result = 0;
		for (auto t : terms)
			result += t.calc(x);
		return result;
	}

	void add_term(int coef, int expo) {
		auto it = terms.begin();
		while (it != terms.end() && it->expo > expo)
			it++;

		if (it != terms.end() && it->expo == expo) {
			it->coef += coef;
			if (it->coef == 0)
				terms.erase(it);
		}
		else {
			terms.insert(it, Term(coef, expo));
		}
	}

	void save(ostream& out) {
		out << name << ' ' << terms.size() << ' ';
		for (const auto& t : terms) {
			out << t.coef << ' ' << t.expo << ' ';
		}
		out << endl;
	}

	void load(istream& in) {
		int term_count;
		in >> name >> term_count;
		terms.clear();
		for (int i = 0; i < term_count; ++i) {
			int coef, expo;
			in >> coef >> expo;
			terms.push_back(Term(coef, expo));
		}
	}
};

void print_poly(Polynomial p, ostream& out) {
	cout << p.name << "=";
	for (auto t : p.terms) {
		t.print(out);
		out << " + ";
	}
}

class PolyCalculator {
private:
	vector<Polynomial> polys;

	vector<Polynomial>::iterator find(char name) {
		for (auto it = polys.begin(); it != polys.end(); it++) {
			if (it->get_name() == name)
				return it;
		}
		return polys.end();
	}
public:
	void create_or_update_poly(char name) {
		Polynomial p(name);
		auto it = find(name);
		if (it != polys.end())
			*it = p;
		else
			polys.push_back(p);
	}
	void add_term_to(char name, int coef, int expo) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefined polynomial !" << endl;
		else
			it->add_term(coef, expo);
	}
	void calc_poly(char name, int x) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefined polynomial !" << endl;
		else
			cout << it->calc(x) << endl;
	}
	void print_pol(ostream& out, char name) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefined polynomial !" << endl;
		else {
			print_poly(*it, out);
			out << endl;
		} 
	}
	void copy_poly(char name, char new_name) {
		auto it = find(name);
		if (it == polys.end()) {
			cout << "Undefined polynomial" << endl;
			return;
		}
		Polynomial q = *it;
		q.set_name(new_name);
		it = find(new_name);
		if (it == polys.end())
			polys.push_back(q);
		else
			*it = q;
	}
	void delete_poly(char name) {
		auto it = find(name);
		if (it == polys.end()) {
			cout << "Undefined polynomial !" << endl;
			return;
		}
		polys.erase(it);
	}
	void list_polys(ostream& out) {
		for (auto p : polys) {
			print_poly(p, out);
			out << endl;
		}
	}
	void save_to_file(const string& filename) {
		ofstream file(filename);
		if (!file.is_open()) {
			cout << "Failed to open file for writing" << endl;
			return;
		}
		for (const auto& p : polys) {
			p.save(file);
		}
		file.close();
	}

	void load_from_file(const string& filename) {
		ifstream file(filename);
		if (!file.is_open()) {
			cout << "Failed to open file for reading" << endl;
			return;
		}
		polys.clear();
		while (file) {
			Polynomial p;
			p.load(file);
			if (file) {
				polys.push_back(p);
			}
		}
		file.close();
	}
	void find_poly(char name) {
		auto it = find(name);
		if (it == polys.end())
			cout << "Undefined polynomial!" << endl;
		else {
			print_poly(*it, cout);
			cout << endl;
		}
	}
};

void process_command(PolyCalculator& calculator) {
	char name, new_name;
	int coef, expo, x;
	string command, filename;
	while (true) {
		cout << "$ ";
		cin >> command;
		if (command == "print") {
			cin >> name;
			calculator.print_pol(cout, name);
		}
		else if (command == "calc") {
			cin >> name >> x;
			calculator.calc_poly(name, x);
		}
		else if (command == "create") {
			cin >> name;
			calculator.create_or_update_poly(name);
		}
		else if (command == "add") {
			cin >> name >> coef >> expo;
			calculator.add_term_to(name, coef, expo);
		}
		else if (command == "copy") {
			cin >> name >> new_name;
			calculator.copy_poly(name, new_name);
		}
		else if (command == "delete") {
			cin >> name;
			calculator.delete_poly(name);
		}
		else if (command == "list") {
			calculator.list_polys(cout);
		}
		else if (command == "save") {
			cin >> filename;
			calculator.save_to_file(filename);
		}
		else if (command == "load") {
			cin >> filename;
			calculator.load_from_file(filename);
		}
		else if (command == "find") {
			cin >> name;
			calculator.find_poly(name);
		}
		else if (command == "exit")
			break;
	}
}

int main() {
	PolyCalculator calculator;
	process_command(calculator);
	return 0;
}

이제 save, load, find 명령을 통해 다항식을 파일에 저장하거나 파일에서 불러오고, 다항식을 찾을 수 있습니다. save 명령은 파일 이름을 받아 현재 다항식 목록을 파일에 저장하며, load 명령은 파일 이름을 받아 파일에서 다항식 목록을 불러옵니다. find 명령은 주어진 이름의 다항식을 찾아 출력합니다.

반응형