교재: 명품 JAVA ESSENTIAL
125페이지 실습문제
<1. 영문 소문자를 하나 입력받고 그 문자보다 알파벳 순위가 낮은 모든 문자를 출력하기>
java에서는 scanner의 next시리즈를 통해 문자 하나를 입력받을 수 없다고 합니다.
그래서 구글링을 해본 결과,
scanner.next()메소드로 String값을 받은 뒤,
String 메소드에 포함된 charAt()메소드를 다시 이용하는 방법으로 char문자 하나를 입력받을 수 있다고 합니다.
사용은 이런식으로 하면 됩니다.
그냥 사용법만 복붙하기엔 아쉬운 감이 있죠. 교수님은 항상 java도큐먼트를 열심히 보라고 말씀하셨습니다.
그래서 도큐먼트를 찾아보니 charAt메소드의 매개변수는 인덱스라고 하네요. 입력받은 문자열 중 가장 앞에 있는 놈을 가져오는 건가 봅니다.
그리고 이 문제에서는 아스키코드를 꼭 필요로 합니다.
다시 구글링을 해보니
소문자 a가 아스키코드 97로 가장 작네요. 이걸 이용해서 문제를 풀어볼겁니다.
import java.util.Scanner;
public class Alpha {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
char eng;
System.out.print("알파벳 한 문자를 입력하세요: ");
eng = scanner.next().charAt(0);
for (int i = 97; i<=eng; i++)
System.out.print((char)i + " ");
scanner.close();
}
}
코드가 짧아서 그냥 전체 코드를 올렸습니다.
가장 작은 아스키코드 97(a) 부터 입력받은 값까지 점차 출력하도록 만들어줬습니다.
<2. 정수 10개 입력받아 배열에 저장한 후 3의 배수만 골라 출력하는 프로그램>
import java.util.InputMismatchException;
import java.util.Scanner;
public class multipleOfThree {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int arr[] = new int[10];
System.out.println("정수 10개 입력>>");
for (int i = 0; i < 10; i++) {
try {
arr[i] = scanner.nextInt();
}
catch (InputMismatchException e) {
System.out.println("다시 입력하세요!");
i --;
scanner.nextLine();
continue;
}
if (arr[i] %3 == 0)
System.out.print(arr[i] + " ");
}
scanner.close();
}
}
배열에 10개의 값을 입력받으면서 만약 입력값이 3의 배수이면 출력해주면 됩니다.
try catch는 그냥 넣어봤습니다.
어렵지 않네요.
<3.홀수짝수 판별 프로그램>
import java.util.InputMismatchException;
import java.util.Scanner;
public class intoddeven {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int intnum = 0;
System.out.print("정수 입력>>");
try {
intnum = scanner.nextInt();
if (intnum % 2 == 0)
System.out.println("짝수");
else
System.out.println("홀수");
}
catch(InputMismatchException e) {
System.out.println("정수를 입력하지 않아 프로그램을 종료합니다.");
}
finally {
scanner.close();
}
}
}
finally에서 scanner를 닫아줍니다.
얘도 어렵진 않습니다.
<4. 정수를 입력받아 배열 day에 저장된 문자 출력>
어떤 수를 7로 나눈 나머지는 0~6입니다.
여기서 day문자 배열은 요소로 일(0), 월(1), 화(2), 수(3), 목(4), 금(5), 토(6)를 가집니다.
예를 들어 입력값이 15라면, 15%7 = 1로, '월'이 출력될 겁니다.
해당하는 배열 인덱스 값을 출력해주면 되겠네요.
import java.util.InputMismatchException;
import java.util.Scanner;
public class day {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
char day[] = { '일', '월', '화', '수', '목', '금', '토' };
int intnum = 0;
while (true) {
System.out.print("정수를 입력하세요>>");
try {
intnum = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("경고! 정수를 입력하지 않았습니다.");
scanner.next();
continue;
}
if (intnum == -1)
break;
else {
intnum = intnum % 7;
System.out.println(day[intnum]);
}
}
System.out.println("프로그램을 종료합니다.");
scanner.close();
}
}
그냥 입력값에 나머지연산자를 적용한 값을 인덱스로 하는 배열요소를 출력해주면 끝입니다.
그리고 catch문 안에 scanner.next(); 이거 꼭 해줘야합니다.
예외가 발생해도 버퍼에는 값이 계속 남아있으니까요. 잘못 입력받은 값은 꼭 버려줘야합니다!!
<5. 정수를 입력받아 배열에 저장하고 오름차순으로 정렬하여 출력>
정렬알고리즘은 버블정렬, 삽입정렬, 퀵 정렬이 있습니다.
이 중 퀵 정렬이 일반적으로 가장 빠른 정렬로 알려져있는데요.
이 문제에서는 퀵 정렬을 이용해볼겁니다.
저는 함수를 총 4개 사용했습니다.
void swap(int data[], int idx1, int idx2) | 배열과 인덱스 2개를 입력받고, 해당 인덱스의 배열값 2개의 자리를 바꿔주는 함수 |
int Quick_partition(int data[], int left, int right) | 퀵 정렬 한 단계를 위한 함수. 동작을 완료한 후에는 피봇의 인덱스 값을 반환한다. |
int[] Quick_sort(int data[], int left, int right) | Quick_partition함수를 배열값이 모두 정렬될 때까지 반복수행해주는 함수. 동작을 완료한 후에는 배열 레퍼런스를 반환한다. |
int[] makeArr(int data[], int size) | 입력된 size변수의 크기만큼 배열을 만들어주는 함수. 사용자의 입력을 받아 값을 채운다. |
1) 먼저 swap함수
static void swap(int data[], int idx1, int idx2) {
int temp = data[idx1];
data[idx1] = data[idx2];
data[idx2] = temp;
}
2) Quick_partition함수
static int Quick_partition(int data[], int left, int right) {
int low, high, pivot;
low = left + 1;
high = right;
pivot = data[left];
try {
while (low <= high) {
while (data[high] > pivot)
high--;
while (low <= high && data[low] <= pivot)
low++;
if (low <= high) {
swap(data, low, high);
low++;
high--;
}
}
} catch (IndexOutOfBoundsException e) {
System.out.println("에러 발생!");
return -1;
}
swap(data, left, high);
return high;
}
피봇 값은 가장 왼쪽 값으로 설정해줬고, left는 피봇의 바로 옆 값으로 설정해줬습니다.
정렬이 완료된 후에는
파란부분이 피봇보다 작은 부분, 빨간 부분이 피봇보다 큰 부분입니다.
반환은 피봇에 해당하는 인덱스 값을 반환합니다.
여기서 try catch를 꼭 해줘야합니다. 아니면 에러가 뜨더라고요.
여기서는 배열 인덱스의 최댓값을 넘지 않았지만, 넘을 수 있는 위험때문에 뜨는 것 같습니다.
에러는 IndexOutOfBoundsException타입으로 받아줍니다~
catch에서는 -1를 반환하고, 밖에선 -1을 받았을 때 그거대로 에러를 처리해주면 될겁니다.
3) Quick_sort함수
static int[] Quick_sort(int data[], int left, int right) {
int q;
if (left < right) {
q = Quick_partition(data, left, right);
if (q == -1)
return null;
Quick_sort(data, left, q - 1);
Quick_sort(data, q + 1, right);
}
return data;
}
Quick_partition함수를 정렬이 완료될 때까지 재귀적으로 자신을 호출합니다~
q는 피봇해당하는 애라 q를 제외한
left ~ q-1/ q+1 ~ right
이렇게 호출해줍니다.
만약 q에서 -1이 호출된다면 에러가 났다는 뜻이니까 null을 반환해줍니다.
4) makeArr함수
static int[] makeArr(int data[], int size) {
Scanner scanner = new Scanner(System.in);
System.out.print("정수 10개 입력>> ");
for (int i = 0; i < size; i++) {
try {
data[i] = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("정수가 아닙니다. 다시 입력하세요");
scanner.nextLine();
i--;
continue;
}
}
scanner.close();
return data;
}
사용자에게 입력받아 배열을 채우고 반환해줍니다.
5) main함수
public static void main(String[] args) {
int size = 10;
int data[] = new int[size];
data = makeArr(data, 10);
data = Quick_sort(data, 0, size-1);
if (data == null) {
System.out.println("프로그램 에러");
}
else {
for (int i = 0; i < size; i++)
System.out.print(data[i] + " ");
}
}
main은 최대한 간결하게 만들어줬습니다.
배열을 만들고, Quick_sort함수를 이용하여 정렬해줬습니다.
null이 반환된다면 에러를 출력해줍니다.
전체코드입니다.
import java.util.InputMismatchException;
import java.util.Scanner;
public class sorting {
static void swap(int data[], int idx1, int idx2) {
int temp = data[idx1];
data[idx1] = data[idx2];
data[idx2] = temp;
}
static int Quick_partition(int data[], int left, int right) {
int low, high, pivot;
low = left + 1;
high = right;
pivot = data[left];
try {
while (low <= high) {
while (data[high] > pivot)
high--;
while (low <= high && data[low] <= pivot)
low++;
if (low <= high) {
swap(data, low, high);
low++;
high--;
}
}
} catch (IndexOutOfBoundsException e) {
System.out.println("에러 발생!");
return -1;
}
swap(data, left, high);
return high;
}
static int[] Quick_sort(int data[], int left, int right) {
int q;
if (left < right) {
q = Quick_partition(data, left, right);
if (q == -1)
return null;
Quick_sort(data, left, q - 1);
Quick_sort(data, q + 1, right);
}
return data;
}
static int[] makeArr(int data[], int size) {
Scanner scanner = new Scanner(System.in);
System.out.print("정수 10개 입력>> ");
for (int i = 0; i < size; i++) {
try {
data[i] = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("정수가 아닙니다. 다시 입력하세요");
scanner.nextLine();
i--;
continue;
}
}
scanner.close();
return data;
}
public static void main(String[] args) {
int size = 10;
int data[] = new int[size];
data = makeArr(data, 10);
data = Quick_sort(data, 0, size-1);
if (data == null) {
System.out.println("프로그램 에러");
}
else {
for (int i = 0; i < size; i++)
System.out.print(data[i] + " ");
}
}
}
퀵 정렬 너무 어렵네요 ㅜ 다음에 퀵정렬 관련해서 더 공부해보고 글 써야겠습니다.
<bonus. 2차원 배열의 합을 출력하는 프로그램(빈칸 채우기)>
public class array2D {
public static void main(String[] args) {
int intArray[][];
intArray = new int[3][4];
for (int i =0; i<3; i++)
for (int j =0; j<4; j++)
intArray[i][j] = (int)(Math.random()*10);
for (int i =0; i<intArray.length; i++) {
for (int j =0; j<intArray[i].length; j++)
System.out.println(intArray[i][j]);
System.out.println();
}
int i =0, sum = 0;
while (i<3) {
int j = 0;
while (j < 4)
sum += intArray[i][j];
}
System.out.println("합은 " + sum);
}
}
빈칸 채우기라서 어렵지 않았습니다.
다만 마지막 칸은 3줄이라서 for문을 쓰면 2줄 나오길래 while문을 써줬습니다.
뭐 어떻게 만들든 답만 잘 나오면 되죠.
'프로그래밍 언어 > javastudy' 카테고리의 다른 글
명품 Java Essential 4단원 실습문제 #1 (0) | 2021.07.11 |
---|---|
명품 Java Essential 4단원 끝말잇기 게임/ scanner에서 NoSuchElementException 예외발생 대처 (0) | 2021.07.10 |
자바 공부 #5 up&down게임 (3) | 2021.07.05 |
자바 공부 #4 369게임, 커피 주문, 사칙 연산 (4) | 2021.07.05 |
자바 공부 #3 카페 주문하기 (0) | 2021.07.04 |