5번
- 사용자 입력을 받아 해당 년 월의 달력을 출력하는 문제
- Java에서 날자 관련 기능을 가진 클래스인 LocalDate클래스를 사용해 구현하였다.
- 먼저 년 월을 입력으로 받고 해당 년과 월의 1일에 대한 정보를 LocalDate를 통해 가져온다.
- 이후 1일이 무슨 요일인지를 받은 뒤 해당 요일보다 앞에 있는 요일들은 아무것도 출력하지 않고 공백으로 출력한다.
- 이후 1일부터 시작하여 점점 증가하며 일수를 출력시킨다.
import java.util.Scanner;
import java.time.LocalDate;
public class JavaStudy05 {
public static void main(String[] args){
System.out.println("[달력 출력 프로그램]");
System.out.print("달력의 년도를 입력해 주세요.(yyyy):");
Scanner sc = new Scanner(System.in);
int year = sc.nextInt();
System.out.print("달력의 월을 입력해 주세요.(mm):");
int month = sc.nextInt();
if (month < 1 || month > 12){
System.out.println("잘못된 값입니다.");
return;
}
System.out.print("\n\n");
System.out.printf("[%d년 %02d월]\n", year, month);
int date = 1;
int day;
LocalDate firstDate = LocalDate.of(year, month, date);
day = firstDate.getDayOfWeek().getValue();
System.out.print("일\t월\t화\t수\t목\t금\t토\n");
for (int i = 0; i < day % 7; i++){
System.out.print("\t");
}
for (int i = 1; i <= firstDate.lengthOfMonth(); i++){
System.out.printf("%02d\t", date++);
day++;
if (day % 7 == 0){
System.out.println();
}
}
}
}
6번 문제
- 랜덤을 통한 투표 시뮬레이터
- 문제에는 1만회와 10만회가 섞여있어 10만회를 기준으로 하여 구현하였다.
- 동률이 나오면 안되기 때문에 동률이 존재하는 경우, 시뮬레이션을 다시 수행하도록 하였다.
- 0 ~ 3까지의 수를 랜덤으로 돌려 해당 수를 인덱스로 하는 배열에 1씩 더해주면 투표의 로직이 완성된다.
import java.util.Random;
public class JavaStudy06 {
public static void main(String[] args){
Random random = new Random();
String[] applicantName = {"이재명", "윤석열", "심상정", "안철수"};
while(true){
boolean isVoteRatioSame = false;
int[] applicantNum = new int[4];
for (int i = 1; i <= 100000; i++){
int voteData = random.nextInt(4);
applicantNum[voteData]++;
System.out.println("[투표진행율]: " + String.format("%.2f", ((float)i / 100000) * 100) + "%, " + i + "명 투표 => " + applicantName[voteData]);
System.out.println("[기호: 1] " + applicantName[0] + ": " + String.format("%02.2f", ((float)applicantNum[0] / 100000) * 100) + "%, " + "(투표수: " + applicantNum[0] + ")");
System.out.println("[기호: 2] " + applicantName[1] + ": " + String.format("%02.2f", ((float)applicantNum[1] / 100000) * 100) + "%, " + "(투표수: " + applicantNum[1] + ")");
System.out.println("[기호: 3] " + applicantName[2] + ": " + String.format("%02.2f", ((float)applicantNum[2] / 100000) * 100) + "%, " + "(투표수: " + applicantNum[2] + ")");
System.out.println("[기호: 4] " + applicantName[3] + ": " + String.format("%02.2f", ((float)applicantNum[3] / 100000) * 100) + "%, " + "(투표수: " + applicantNum[3] + ")");
}
int max = -1;
int maxIdx = -1;
for (int i = 0; i < 4; i++){
// 동률이 발생한다면 다시 시뮬레이션 진행
if (applicantNum[i] == max){
isVoteRatioSame = true;
break;
}
if (applicantNum[i] > max){
max = applicantNum[i];
maxIdx = i;
}
}
if (isVoteRatioSame){
continue;
}
System.out.printf("[투표결과] 당선인: %s", applicantName[maxIdx]);
break;
}
}
}
7번 문제
- 로또 시뮬레이터이다.
- 로또의 개수를 입력받아 개수만큼 로또를 만들고, 당첨 번호를 만든 뒤 몇 개가 일치하는지 검사한다.
- 로또의 특성 상 중복이 허용되지 않는다. 따라서 중복된 수를 체크해야할 필요가 존재한다.
- 로또의 특성 상 오름차순으로 수가 배열되어 있다. 따라서 수를 랜덤하게 뽑은 뒤, 그 배열을 한번 정렬할 필요가 있다.
- 로또의 결과 비교는 1부터 45까지의 배열에 당첨 번호가 있는 인덱스의 값을 1로 설정하고, 이후 로또 번호를 인덱스로 해 참조하여 true인지 아닌지 비교함으로서 for루프를 사용하지 않고 O(1)에 비교가 가능하다. (대신 1부터 45까지의 배열에 대한 메모리를 trade - off 해야한다.)
- 메서드의 경우 동일한 부분이 많기 때문에 메서드 오버로딩을 통해 로또 만들기와 출력을 구현하였다.
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class JavaStudy07 {
static boolean[] chk;
static boolean[] resultArea = new boolean[46];
static Random random = new Random();
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("[로또 당첨 프로그램]");
System.out.print("로또 개수를 입력해 주세요.(숫자 1 ~ 10):");
int lottoCnt = sc.nextInt();
int[][] lottoArray = new int[lottoCnt][6];
makeLotto(lottoArray, lottoCnt);
printLotto(lottoArray, lottoCnt);
int[] result = new int[6];
makeLotto(result);
printLotto(result);
printResult(lottoArray, lottoCnt);
}
static void makeLotto(int[][] lottoArray, int lottoCnt){
for (int i = 0; i < lottoCnt; i++){
chk = new boolean[46];
for (int j = 0; j < 6; j++){
int lottoData;
while(true){
lottoData = random.nextInt(45) + 1;
if (!chk[lottoData]){
chk[lottoData] = true;
break;
}
}
lottoArray[i][j] = lottoData;
}
Arrays.sort(lottoArray[i]);
}
}
static void makeLotto(int[] lottoArray){
chk = new boolean[46];
for (int i = 0; i < 6; i++){
int lottoData;
while(true){
lottoData = random.nextInt(45) + 1;
if (!chk[lottoData]){
chk[lottoData] = true;
break;
}
}
lottoArray[i] = lottoData;
resultArea[lottoData] = true;
}
Arrays.sort(lottoArray);
}
static void printLotto(int[][] lottoArray, int lottoCnt){
for (int i = 0; i < lottoCnt; i++){
System.out.printf("%c\t", i + 'A');
for (int j = 0; j < 6; j++){
System.out.print(lottoArray[i][j]);
if (j != 5){
System.out.print(",");
}
}
System.out.println();
}
}
static void printLotto(int[] lottoArray){
System.out.println("\n[로또 발표]");
System.out.print("\t");
for (int i = 0; i < 6; i++){
System.out.print(lottoArray[i]);
if (i != 5){
System.out.print(",");
}
}
}
static void printResult(int[][] lottoArray, int lottoCnt){
System.out.println("\n\n[내 로또 결과]");
for (int i = 0; i < lottoCnt; i++){
System.out.printf("%c\t", i + 'A');
int correctCnt = 0;
for (int j = 0; j < 6; j++){
if (resultArea[lottoArray[i][j]]){
correctCnt++;
}
System.out.print(lottoArray[i][j]);
if (j != 5){
System.out.print(",");
}
}
System.out.printf(" => %d개 일치\n", correctCnt);
}
}
}
8번 문제
- 주어진 세법에 맞게 연 수입에 대한 세금을 계산하는 문제
- 2가지 방법이 있으며 2가지 방법 모두 구현해야 한다.
- 과세 표준과 세율을 배열로 만들어 관리하고, 반복문을 응용하여 if문의 많은 사용을 줄이며 구현하였다.
- 사실 출력 포멧하는것이 제일 어려웠다...
import java.util.Scanner;
public class JavaStudy08 {
static long[] stdValue = { // 과세 표준
1000000000, 500000000, 300000000, 150000000, 88000000, 46000000, 12000000
};
static double[] ratio = {0.45d, 0.42d, 0.4d, 0.38d, 0.35d, 0.24d, 0.15d}; // 세율
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("[과세금액 계산 프로그램]");
System.out.print("연소득을 입력해 주세요.:");
long incomeOfYear = sc.nextLong();
System.out.println("[세율에 의한 세금]: \t\t\t" + getTaxByTable(incomeOfYear));
System.out.println("[누진공제 계산에 의한 세금]: \t" + getTaxByDeduction(incomeOfYear));
}
static long getTaxByTable(long incomeOfYear){
long incomeTax = (long)(stdValue[6] * 0.06);
// 맨 처음 1200만인지 아닌지를 체크하고 세율 계산
if (incomeOfYear < stdValue[6]){
System.out.print(String.format("%10d", incomeOfYear) + " * " + String.format("%2d", 6) + "% = " + String.format("%10d", incomeTax) + "\n");
return (long)(incomeOfYear * 0.06);
} else{
System.out.print(String.format("%10d", stdValue[6]) + " * " + String.format("%2d", 6) + "% = " + String.format("%10d", incomeTax) + "\n");
}
incomeOfYear -= stdValue[6];
int stdValIdx = 5;
// 이후 각 구간을 돌면서 세금 계산
while(true){
if (stdValIdx < 0){
break;
}
long incomeGap = stdValue[stdValIdx] - stdValue[stdValIdx + 1];
long tax;
if (incomeOfYear <= incomeGap){
System.out.print(String.format("%10d", incomeOfYear) + " * " + String.format("%2d", (int)(ratio[stdValIdx + 1] * 100)) + "% = ");
tax = (long)(incomeOfYear * ratio[stdValIdx + 1]);
incomeTax += tax;
System.out.print(String.format("%10d", tax) + "\n");
incomeOfYear = 0;
break;
} else {
System.out.print(String.format("%10d", incomeGap) + " * " + String.format("%2d", (int)(ratio[stdValIdx + 1] * 100)) + "% = ");
tax = (long)(incomeGap * ratio[stdValIdx + 1]);
incomeTax += tax;
incomeOfYear -= incomeGap;
System.out.print(String.format("%10d", tax) + "\n");
stdValIdx--;
}
}
if (incomeOfYear != 0){
incomeTax += incomeOfYear * 0.45;
}
System.out.println("\n");
return incomeTax;
}
static long getTaxByDeduction(long incomeOfYear){
long[] deductionValue = {65400000, 35400000, 25400000, 19400000, 14900000, 5220000, 1080000}; // 누진공제
long incomeTax = 0;
for (int i = 0; i < 7; i++){
if (incomeOfYear > stdValue[i]){
incomeTax = Math.round(incomeOfYear * ratio[i]) - deductionValue[i]; // 소숫점이 나올 경우 사사오입으로 계산(반올림)
break;
}
}
if (incomeTax == 0){
incomeTax = (long)(incomeOfYear * 0.06);
}
return incomeTax;
}
}
정리
- 미리 해놓은 것들이 있어 크게 어렵지 않았다. 배열, 반복문, 조건문과 더불어 약간의 로직구현을 요구하는 과제였기 때문인 것으로 생각된다.
- 때문에 무턱대고 구현하기 보다는 어떻게 구현해야 효율적으로 구현할 수 있을 것인지에 대해 어느 정도 생각하면서 구현했던것 같다.
'Java' 카테고리의 다른 글
Java 미니 과제 리뷰 - (1) (0) | 2023.03.02 |
---|