Practice3
===
문제 설명
---
간단한 편집기를 구현하려고 한다.
편집기에는 문자열과 편집 명령어가 주어지는데, 명령어의 동작은 다음과 같다.
- L : 커서를 왼쪽으로 한 칸 옮김 (커서가 문장의 맨 앞이면 무시)
- D : 커서를 오른쪽으로 한 칸 옮김 (커서가 문장의 맨 뒤이면 무시)
- B : 커서 왼쪽에 있는 문자를 삭제 (커서가 문장의 맨 앞이면 무시)
- P x : x라는 문자를 커서 왼쪽에 추가
여기서 커서는 문자열에서 편집이 시작되는 기준 위치로,
문장의 맨 앞, 맨 뒤, 중간에 위치할 수 있다.
편집기에 문자열과 명령어들이 주어졌을 때,
편집을 완료한 후의 문자열을 출력하는 프로그램을 작성하시오.
(초기 커서의 위치는 문장의 맨 뒤에서 시작한다.)
(문자열은 소문자만 입력 가능하다.)
package Java_18_2.src;
import java.util.ArrayList;
public class Practice3 {
public static String solution(String input, String cmd) {
//문자열이 빈번하게 바뀔 때 StringBuffer 사용
StringBuffer sb = new StringBuffer(input);
ArrayList<String> cmdArr = new ArrayList<>();
for (String s : cmd.split(" ")) {
cmdArr.add(s);
}
int curSor = sb.length();
int cmdIdx = 0;
while (cmdIdx != cmdArr.size()) {
String current = cmdArr.get(cmdIdx);
//커서를 왼쪽으로 한 칸 옮김
if (current.equals("L")) {
// 커서 음수 방지를 위해 Math.max 함수로 0보장
curSor = Math.max(0, curSor - 1);
}
// 커서를 오른쪽으로 한 칸 옮김
else if (current.equals("D")) {
curSor = Math.min(sb.length(), curSor + 1);
}
// 커서 왼쪽에 있는 문자를 삭제
else if (current.equals("B")) {
// 커서가 맨 앞이면 지울 문자 X
if (curSor == 0) {
cmdIdx++;
continue;
}
// 커서 이전 문자 ~ 커서까지 지움
sb.delete(curSor - 1, curSor);
curSor = Math.max(0, curSor - 1);
}
// P 다음 문자를 커서 왼쪽에 추가
else if (current.equals("P")) {
String s = cmdArr.get(++cmdIdx); // idx도 같이 증가
sb.insert(curSor, s); //커서 위치에 s 삽입
curSor += 1;
}
cmdIdx++;
}
return sb.toString();
}
public static void main(String[] args) {
// test code
System.out.println(solution("aba", "L B")); // aa
System.out.println(solution("abcd", "P x L P y")); // abcdyx
System.out.println(solution("abc", "L L L P x L B P y")); // yxabc
System.out.println(solution("a", "B B L L D D P a P b P c")); // abc
}
}
Practice4
===
문제 설명
---
특수 작전을 위해 상대방의 PC에 키보드 입력 내용을 얻을 수 있는 키로깅 프로그램을 설치했다.
해당 키로깅 프로그램으로부터는 아래와 같이 특정 값으로 내용이 수신된다.
* 8 : Backspace
* 16 : Shift
* 20 : Caps Lock
* 32 : Space bar
* 37 : 키보드 왼쪽 화살표
* 39 : 키보드 오른쪽 화살표
* 155: Insert
* 127: Delete
* 97~122: 알파벳 소문자 (기본 입력은 소문자 기준, Shift 나 Caps Lock 에 의해 변경)
* 48~57: 숫자 0~9
(이 외의 값은 들어오지 않는다고 가정)
키로깅 프로그램으로부터 수신된 데이터를 원래 내용으로 복구하는 프로그램을 작성하세요.
package Java_18_2.src;
public class Practice4 {
public static String solution(int[] keyLog) {
// 상수
final int BACK_SPACE = 8;
final int SHIFT = 16;
final int CAPS_LOCK = 20;
final int SPACE_BAR = 32;
final int KEY_LEFT = 37;
final int KEY_RIGHT = 39;
final int INSERT = 155;
final int DELETE = 127;
// 빈번한 변경이 있을 것이니 StringBuffer 사용
StringBuffer sb = new StringBuffer();
int step = (int) ('a' - 'A');
int curSor = 0;
int cmdIdx = 0;
boolean isShift = false;
boolean isCapsLock = false;
boolean isInsert = false;
//cmdIdx.length가 될 때까지 반복문
while (cmdIdx != keyLog.length) {
int current = keyLog[cmdIdx];
if (current == BACK_SPACE) {
if (curSor == 0) {
cmdIdx++;
continue;
}
sb.delete(curSor - 1, curSor);
curSor = Math.max(0, curSor - 1);
} else if (current == SHIFT) {
isShift = true;
} else if (current == CAPS_LOCK) {
isCapsLock = !isCapsLock;
} else if (current == SPACE_BAR) {
inputData(sb, ' ', curSor, isInsert);
curSor += 1;
} else if (current == KEY_LEFT) {
curSor = Math.max(0, curSor - 1);
} else if (current == KEY_RIGHT) {
curSor = Math.min(sb.length(), curSor + 1);
} else if (current == INSERT) {
isInsert = !isInsert;
} else if (current == DELETE) {
if (curSor == sb.length()) {
cmdIdx++;
continue;
}
sb.delete(curSor, curSor + 1);
} else if (current >= 97 && current <= 122) {
int data = current;
if (isCapsLock && isShift) {
data = current;
} else if (isCapsLock || isShift) {
data -= step;
}
inputData(sb, (char) data, curSor, isInsert);
isShift = false;
curSor += 1;
} else if (current >= 48 && current <= 57) {
if (isShift) { //'0' = 48
char[] specialKey = {')', '!', '@', '#', '$', '%', '^', '&', '*', '('};
inputData(sb, specialKey[current - '0'], curSor, isInsert);
} else {
inputData(sb, (char) current, curSor, isInsert);
}
isShift = false;
curSor += 1;
}
cmdIdx++;
}
return sb.toString();
}
public static void inputData(StringBuffer sb, char data, int curSor, boolean isInsert) {
if (isInsert == false) {
sb.insert(curSor, data);
} else {
sb.setCharAt(curSor, data);
}
}
public static void main(String[] args) {
// Test code
int[] keyLog = {16, 106, 101, 108, 108, 111, 37, 37, 37, 37, 37, 155, 16, 104};
System.out.println(solution(keyLog));
keyLog = new int[]{20, 104, 16, 105, 32, 20, 16, 106, 97, 118, 97};
System.out.println(solution(keyLog));
keyLog = new int[]{49, 51, 8, 50, 51, 53, 55, 37, 37, 127, 127, 52, 53};
System.out.println(solution(keyLog));
keyLog = new int[]{20, 97, 98, 16, 99, 16, 100, 16, 49, 16, 50, 16, 51};
System.out.println(solution(keyLog));
}
}
Practice5
===
문제 설명
---
N 명의 아이들이 한 줄로 서있다.
각각의 아이들은 점수 표를 가지고 있는데 점수 표에 따라 다음과 같은 규칙으로 사탕을 나누어 줘야 한다.
* 적어도 1개 이상의 사탕을 나누어줘야 한다.
* 점수가 높은 아이에게는 바로 옆의 아이 보다는 사탕을 많이 줘야 한다.
N 명의 아이들에 대한 점수 표가 ratings 배열에 주어질 때,
나누어 줘야하는 최소한의 사탕 개수를 출력하세요.
package Java_18_2.src;
public class Practice5 {
public static int solution(int[] ratings) {
if (ratings == null || ratings.length == 0) {
return 0;
}
int result = 1;
int upCnt = 1;
int downCnt = 0;
int peek = 0;
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1]) {
upCnt++;
peek = upCnt;
downCnt = 0;
result += upCnt;
} else if (ratings[i] == ratings[i - 1]) {
upCnt = 1;
downCnt = 0;
peek = 0;
result += 1;
} else {
downCnt++;
upCnt = 1;
result += downCnt;
if (peek <= downCnt) {
result += 1;
}
}
}
return result;
}
public static void main(String[] args) {
// Test code
int[] ratings = {1, 2, 3};
System.out.println(solution(ratings));
ratings = new int[]{3, 2, 1};
System.out.println(solution(ratings));
ratings = new int[]{1, 0, 2};
System.out.println(solution(ratings));
ratings = new int[]{1, 2, 2};
System.out.println(solution(ratings));
ratings = new int[]{1, 3, 5, 3, 1, 3, 5, 7, 5, 3, 1, 0};
System.out.println(solution(ratings));
}
}
'개발 공부 > 문제와 풀이' 카테고리의 다른 글
Java) 연습문제 3-2 (0) | 2024.08.10 |
---|---|
Java) 연습문제 3-1 (0) | 2024.08.10 |
Java) 연습문제 2-1 (0) | 2024.08.10 |
Java) 물을 가장 많이 담을 수 있는 면적 구하기 (0) | 2024.08.09 |
Java) replace 구현 문제 (0) | 2024.08.09 |