Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- java
- D Flip Flop
- structural modeling
- Recursion
- soc 설계
- half adder
- stop watch
- atmega 128a
- DHT11
- ring counter
- KEYPAD
- Edge Detector
- i2c 통신
- prescaling
- pwm
- test bench
- Linked List
- Algorithm
- uart 통신
- gpio
- dataflow modeling
- hc-sr04
- Pspice
- FND
- LED
- ATMEGA128A
- behavioral modeling
- vivado
- verilog
- BASYS3
Archives
- Today
- Total
거북이처럼 천천히
알고리즘 (6월 29일) 본문
1. 문제 (다항식 계산)
2. 생각
- 변수 타입(다항식)에 대해서 먼저 생각해볼 필요가 있다.
▶ 다항식은 여러 개의 항들이 모여서 만든 식이라는 점을 생각
▶ 각 항들은 계수와 차수 값을 저장할 수 있는 인스턴스 변수들이 존재하는 Term 클래스 정의▶ 다항식은 여러 개의 항들을 배열 형태로 저장하고, 실제 항들의 갯수와 다항식의 이름을 저장할 수 있는
Polynomial 클래스 정의 - add 명령어를 통해 새로운 항이 들어오면 어떻게 저장할 것인가?
▶ 미리 차수를 기준으로 내림차순 저장하는 것이 나중에 출력할 때, 편리할 거 같다.
▶ 새로운 항의 차수를 통해 위치를 찾는다.
▶ for문을 이용하여 차수가 낮은 항들을 한 칸씩 뒤로 옮긴다. - 하지만, add 했는데, 이전 계수와 더해져서 계수가 0이 된 경우에는? (ex, -4x + 4x = 0*x)
▶ 더해져서 계수가 0이 될 경우, 해당항을 삭제하기 위해서 다음 항의 참조 변수를 한 칸씩 앞으로 옮긴다. - print 명령어 과정에서 계수가 -1과 1인 경우에 대해서 생각해 볼 필요가 있다.
3. 풀이 및 코드 분석
package Chapter2;
import java.util.Scanner;
public class CalculatePolynomial {
static Polynomial[] polynomial = new Polynomial[100];
static int countPolynomial = 0;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(true) {
System.out.print("$");
String command = scan.next();
if(command.equalsIgnoreCase("create")) {
char name = scan.next().charAt(0);
int result =checkPolynomial(name);
if(result >= 0)
System.out.println("That name of polynomial alreay existed.");
else {
polynomial[countPolynomial] = new Polynomial();
polynomial[countPolynomial].name = name;
countPolynomial++;
}
}else if(command.equalsIgnoreCase("add")) {
char name = scan.next().charAt(0);
int nPoly = checkPolynomial(name);
if(nPoly==-1)
System.out.println("No such Polynomial exists");
else {
int newCoeff = scan.nextInt();
int newExpo = scan.nextInt();
addTerm(nPoly, newCoeff, newExpo);
}
}else if(command.equalsIgnoreCase("calc")) {
char nameOfPoly = scan.next().charAt(0);
int result = checkPolynomial(nameOfPoly);
if(result == -1)
System.out.println("No such Polynomial exists");
else {
int inputData = scan.nextInt();
calculate(polynomial[result], inputData);
}
}else if(command.equalsIgnoreCase("print")) {
char nameOfPoly = scan.next().charAt(0);
printPolynnomial(nameOfPoly);
}else if(command.equalsIgnoreCase("exit")) {
System.exit(0);
}else {
System.out.println("You entered an wrong command.");
}
}
}
public static int checkPolynomial(char name) {
for(int i=0; i<countPolynomial; i++) {
if(polynomial[i].name == name)
return i;
}
return -1;
}
public static void addTerm(int nPoly, int newCoeff, int newExpo) {
int checkExpo = -1;
Polynomial poly = polynomial[nPoly];
for(int i=0; i<poly.nTerm; i++) {
if(poly.terms[i].expo==newExpo) {
checkExpo = i;
break;
}
}
if(checkExpo != -1) {
int sumCoeff = newCoeff+poly.terms[checkExpo].coeff;
if(sumCoeff==0) {
for(int i=checkExpo+1; i<poly.nTerm; i++)
poly.terms[i-1] = poly.terms[i];
poly.terms[poly.nTerm-1] = null;
poly.nTerm--;
}
else
poly.terms[checkExpo].coeff = sumCoeff;
}else {
int i = poly.nTerm - 1;
while(i>=0&&poly.terms[i].expo<newExpo) {
poly.terms[i+1]=poly.terms[i];
i--;
}
poly.terms[i+1] = new Term();
poly.terms[i+1].coeff=newCoeff;
poly.terms[i+1].expo=newExpo;
poly.nTerm++;
}
}
public static void printPolynnomial(char nameOfPoly) {
int result = checkPolynomial(nameOfPoly);
if(result == -1) {
System.out.println("No such polynomial exists");
return;
}else {
printTerms(polynomial[result]);
}
}
public static void printTerms(Polynomial poly) {
if(poly.nTerm == 0) {
System.out.printf("%c = 0\n", poly.name);
return;
}
System.out.printf("%c=", poly.name);
for(int i=0; i<poly.nTerm; i++) {
int getCoeff = poly.terms[i].coeff;
int getExpo = poly.terms[i].expo;
if(i!=0&&getCoeff>0)
System.out.print("+");
if(getExpo==1)
if(getCoeff==1)
System.out.print("x");
else if(getCoeff==-1)
System.out.print("-x");
else
System.out.printf("%dx",getCoeff);
else if(getExpo==0)
System.out.printf("%d",getCoeff);
else
if(getCoeff==1)
System.out.printf("x^%d", getExpo);
else if(getCoeff==-1)
System.out.printf("-x^%d", getExpo);
else
System.out.printf("%dx^%d",getCoeff, getExpo);
if(i==poly.nTerm-1)
System.out.println();
}
}
public static void calculate(Polynomial poly, int input) {
int sum = 0;
for(int i=0; i<poly.nTerm; i++) {
int getCoeff = poly.terms[i].coeff;
int getExpo = poly.terms[i].expo;
sum += getCoeff*(Math.pow(input, getExpo));
}
System.out.printf("The result of calculation is %d. \n",sum);
return;
}
}
package Chapter2;
public class Polynomial {
public char name;
public int nTerm=0;
public Term[] terms = new Term[100];
}
package Chapter2;
public class Term {
public int coeff;
public int expo;
}
4. 메모
int i = poly.nTerm - 1;
while(i>=0&&poly.terms[i].expo<newExpo) {
poly.terms[i+1]=poly.terms[i];
i--;
}
int i = poly.nTerm - 1;
while(poly.terms[i].expo<newExpo&&i>=0) {
poly.terms[i+1]=poly.terms[i];
i--;
}
- 위 두 코드는 같은 것 같지만, 약간의 차이점이 존재한다. (이 부분때문에 문제점 찾는데, 20~30분 소요 ㅠ)
- 목표 : poly.nTerm = 0이면 i=-1 이기 때문에 while문을 실행하지 않고, 통과시키고 싶다.
- 문제점 : 아래 코드에서 "poly.terms[-1]은 존재하지 않는다."라는 문제가 발생
(And 연산자를 기준으로 앞뒤가 바뀌었을 뿐, 같은 코드인거 같은데, 무엇이 문제인가?) - 이유 : while문의 조건문에서 앞에서 조건을 따지기 때문에 위 코드인 경우에는 i가 0보다 크거나 같은지를 먼저 생각하지만, 아래 코드인 경우에는 poly.terms[i].expo<newExpo 인지를 먼저 생각한다.
▶ 이러한 이유로 위 코드은 원래 목표에 대해서 정상적으로 작동하지만, 아래 코드인 경우에는 i>=0인지를 따지기 전
에 poly.terms[i].expo<newExpo 인지를 먼저 따져서 문제점 발생
'Algorithm > 알고리즘 문제 풀이' 카테고리의 다른 글
Java - 싱글 연결리스트를 통해 다항식 계산 (0) | 2022.08.11 |
---|---|
알고리즘 (6월 30일) (0) | 2022.06.30 |
알고리즘 (6월 22일) (0) | 2022.06.23 |
알고리즘 (6월 19일) (0) | 2022.06.19 |
알고리즘 (6월 16일) (0) | 2022.06.16 |