1) 1부터 50까지 짝수만 곱해서 출력하기

-이 문제를 해결하면서 짝수인 i 값을 차례로 더할 때는 정상적으로 출력됐는데,
무심코 넣었던 int 자료형의 크기가 짝수 곱을 담을 수 없자
음수 값이 나온 뒤 0으로 바뀌는 현상 때문에 문제 풀이에 시간이 걸렸다.

-이는 자료형의 크기 때문이였다.
-1차 시도로, int가 안되자 long을 집어넣었는데, long의 자료 크기는 19-20자로, 경 단위 까지밖에 담을 수 없다.
-이 과정에서 long의 데이터 형은 float 값 뒤에 f가 붙는 것 처럼 L이 붙는다는 것을 배웠다.
-그 후 , 구글링으로 무한대 크기의 데이터를 담을 수 있는 BigInteger를 찾았다!
-BigInteger 선언/초기화 : 문자열을 인자 값으로 넘겨주어야 한다
BigInteger big = new BigInteger("1");
-BigInteger 연산법 : BigInteger은 문자열이기에 사칙연산이 안된다. BigIntger 클래스 내부에 있는 메서드를 사용
1. big에 20을 더하는 방법
big = big.add(BigInteger.valueOf(20));
2. big에 2를 빼는 방법
big = big.subtract(BigInteger.valueOf(2));
3. big에 2를 곱하는 방법
big = big.multiply(BigInteger.valueOf(2));
4. big에 3를 나누는 방법
big = big.divide(BigInteger.valueOf(3));
5. big를 5로 나눌 때 나머지를 구하는 방법
big = big.remainder(BigInteger.valueOf(5));
실제 코딩테스트에서는 1부터 100까지 2와 3의 배수이면서, 5의 배수가 아닌 수를 모두 더하는 문제로 출제
2) 특정 정수 이하의 소수 더하기
*소수 : 1과 자기 자신만으로 나누어떨어지는 정수
에라토스테네스의 체 이용하기
1. 2부터 소수를 구하고자 하는 구간의 모든 수를 나열한다.
2. 2는 소수이므로 오른쪽에 2를 쓴다.
3. 자기 자신을 제외한 2의 배수를 모두 지운다.
4. 남아있는 수 가운데 3은 소수이므로 오른쪽에 3을 쓴다.
5. 자기 자신을 제외한 3의 배수를 모두 지운다.
6. 남아있는 수 가운데 5는 소수이므로 오른쪽에 5를 쓴다.
7. 자기 자신을 제외한 5의 배수를 모두 지운다.
8. 남아있는 수 가운데 7은 소수이므로 오른쪽에 7을 쓴다.
9. 자기 자신을 제외한 7의 배수를 모두 지운다.
10. 위의 과정을 반복하면 구하는 구간의 모든 소수가 남는다.
2부터 N까지의 수 중에서 소수를 찾는다고 했을 때,
N의 제곱근(나누어 떨어지지 않는다면 보다 큰 자연수)보다 작은 소수의 배수를 모두 지우고 남는 수는 모두 소수입니다.

-숫자 100을 집어넣었을 때, 100이하의 소수는 100의 제곱근인 10보다 작은 소수(2,3,5,7)의 배수를 모두 지우고 남는 수이다.
-초기에 0과 1은 false로, 나머지는 true로 세팅해둔 뒤
-2부터 100의 제곱근(10)보다 작을 때 까지의 소수를 구한 뒤 배수를 false로 바꾼다.
-i가 2일 때 j는 자신을 제외하기 위해서 2*2=4부터 시작, 다음은 4+2인 6 , 다음은 6+2인 8
실제 코딩테스트에서는 소수를 구하는 알고리즘에서 틀린 점을 디버깅하는 문제로 출제되었다.
3) 대문자 추출하기
대문자 제거
String str = "I Live In South Korea."; str.replaceAll("[A-Z]", ""); // ive n outh orea.
소문자 제거
String str = "I Live In South Korea."; str.replaceAll("[a-z]", ""); //I L I S K.
특정 글자가 대문자인지 소문자인지 확인하는 방법은
Character.isUpperCase(글자);
이렇게 입력하면 대문자일 경우 true 그렇지 않을 경우 false가 뜨는데

-이를 이용해 문자열에서 대문자만 추출 해 출력해 봤다.

-isUpperCase, isLowerCase를 사용하여 a.charAt의 길이만한 배열을 true/false로 채워준 뒤 , true만 출력한다.
-출력결과 :

4) 문자열 아스키 코드 순으로 정렬하기


-먼저 문자열을 toCharArray를 사용하여 배열에 담아준다. 여기서는 두 개의 for문이 사용된다.
첫 번째는 문자 배열을 반복하는 것이고, 두 번째는 비교에서 반복을 피한다.
두 번째 반복문 안에서 조건 (StringtoChar[j] <StringtoChar[j+1])이 참이면 치환을 통해 배열을 정렬
실제 문제에서는 String 형태로 된 숫자를 int 배열로 만들어 오름차순 정렬하는 문제로 출제되었다.
5) 문자열에서 숫자 제거하기

48은 아스키코드 숫자 0, 57은 아스키코드 숫자 9를 의미하므로, 문자열에서 0-9사이의 숫자만 추출 가능
6) 피보나치 수열에서 N번째 값 뽑아내기

7) 숫자 버블정렬 하기

이 때, 각 라운드를 진행 할 때마다 뒤에서부터 한 개씩 정렬되기 때문에, 라운드가 진행 될 때마다 한 번씩 줄면서 비교하게 된다.
한마디로 정리하자면 이렇다.
총 라운드는 배열 크기 - 1 번 진행되고,
각 라운드별 비교 횟수는 배열 크기 - 라운드 횟수 만큼 비교한다.
버블정렬 연습해놓길 잘함! 정렬 문제가 출제되었다.
8) STACK 구현하기
interface Stack
{
boolean isEmpty();
boolean isFull();
void push(char item);
char pop();
char peek();
void clear();
}
public class ArrayStack implements Stack
{
private int top;
private int stackSize;
private char stackArr[];
// 스택을 생성하는 생성자
public ArrayStack(int stackSize)
{
top = -1; // 스택 포인터 초기화
this.stackSize = stackSize; // 스택 사이즈 설정
stackArr = new char[this.stackSize]; // 스택 배열 생성
}
// 스택이 비어있는 상태인지 확인
public boolean isEmpty()
{
// 스택 포인터가 -1인 경우 데이터가 없는 상태이므로 true 아닌 경우 false를 return
return (top == -1);
}
// 스택이 가득찬 상태인지 확인
public boolean isFull()
{
// 스택 포인터가 스택의 마지막 인덱스와 동일한 경우 true 아닌 경우 false를 return
return (top == this.stackSize-1);
}
// 스택에 데이터를 추가
public void push(char item)
{
if(isFull())
{
System.out.println("Stack is full!");
}
else
{
stackArr[++top] = item;
// 다음 스택 포인터가 가리키는 인덱스에 데이터 추가
}
}
// 스택의 최상위(마지막) 데이터 추출 후 삭제
public char pop()
{
if(isEmpty())
{
System.out.println("Empty");
return 0;
}
else
{
System.out.println("Deleted Item : " + stackArr[top]);
return stackArr[top--];
}
}
// 스택의 최상위(마지막) 데이터 추출
public char peek()
{
if(isEmpty())
{
System.out.println("Peeking fail! Stack is empty!");
return 0;
}
else
{
System.out.println("Peeked Item : " + stackArr[top]);
return stackArr[top];
}
}
// 스택 초기화
public void clear()
{
if(isEmpty())
{
System.out.println("Stack is already empty!");
}
else
{
top = -1;
// 스택 포인터 초기화
stackArr = new char[this.stackSize];
// 새로운 스택 배열 생성
System.out.println("Stack is clear!");
}
}
// 스택에 저장된 모든 데이터를 출력
public void printStack()
{
if(isEmpty())
{
System.out.println("Empty");
}
else
{
System.out.print("Stack elements : ");
for(int i=0; i<=top; i++)
{
System.out.print(stackArr[i] + " ");
}
System.out.println();
}
}
public static void main(String args[]) {
int stackSize = 5;
ArrayStack arrStack = new ArrayStack(stackSize);
arrStack.push('A');
arrStack.printStack();
arrStack.push('B');
arrStack.printStack();
arrStack.push('C');
arrStack.printStack();
arrStack.pop();
arrStack.printStack();
}
}
9) 팩토리얼
public class Factorial {
public static void main(String[] args) {
int input = 4; // 4!
System.out.println(fact(input));
}
public static int fact(int n) {
if (n <= 1)
return n;
else
return fact(n-1) * n;
}
}
4. 원리
1) 처음 fact 메소드가 불린 것은 main 함수에서이다.
fact(4) 가 실행될 것이다.
2) fact(4)
n은 현재 4이다.
n은 1보다 크므로 else를 타고,
fact(3)이 호출된다.
3) 여기서 처음 호출된 fact(4)는 종료되지 않고 Stack에 쌓인상태로,
fact(4)가 호출한 fact(3)이 실행된다.
Stack
| fact(4) |
4) fact(3)
n은 현재 3이다.
n은 1보다 크므로 else를 타고,
fact(2)이 호출된다.
5) 여기서 두번째로 호출된 fact(3)은 종료되지 않은 상태로 Stack에 쌓이고,
fact(3)이 호출한 fact(2)이 실행된다.
Stack
| fact(3) |
| fact(4) |
6) fact(2)
n은 현재 2이다.
n은 1보다 크므로 else를 타고,
fact(1)이 호출된다.
7) 세번째로 호출된 fact(2)는 종료되지 않은 상태로 Stack에 쌓이고
fact(2)가 호출한 fact(1)이 실행된다.
Stack
| fact(2) |
| fact(3) |
| fact(4) |
8) fact(1)
n은 현재 1이다.
n이 1과 같으므로 if문을 타고, n 즉, 1을 return 한다.
9) fact(1)이 종료되면서, Stack의 가장 위에 있는 fact(2)가 실행된다.
8번에서 리턴 받은 값과 n을 곱하며 return 하고 fact(2)가 종료될 것이다.
fact(2) 에서는 n이 2이다.
8번에서 fact(1)은 1을 리턴했었다.
| fact(2-1) * n 즉, 1 * 2 |
그래서 fact(2)에서는 1*2 한 값을 return 한다.
Stack은 이제 아래와 같은 상태가 된다.
| fact(3) |
| fact(4) |
10) 스택에 있던 fact(3)이 실행된다.
9번에서 리턴 받은 1*2 = 2 와 n을 곱하며 리턴하고 종료한다.
| fact(3-1) * n 즉, 2 * 3 |
fact(3)은 1*2*3 한 값 6을 리턴한다.
11) 마지막으로, 처음 불리워졌었던 fact(4)가 리턴할 차례가 왔다.
10번에서 리턴받은 6과 n을 곱하고 리턴하고 종료될 것이다.
| fact(4-1) * n 즉, 6 * 4 = 24 |
이렇게 4! 을 구했고, 리턴 받은 값은 main 함수에서 출력된다.
결론적으로 따져보면
1*2*3*4 를 하게 된 것이다.
실제 문제에서는 주어진 알고리즘을 디버깅하는 문제로 출제되었으며, return 부분에 n * fact(n--); 비슷하게 나와있어서 숫자를 감소시킨 후 재귀되어야 하기 때문에 n-1로 수정했다. 또한 if문의 구조적 문제도 수정했음!
- 실제 손코딩을 해보니, public class 부터 모든 클래스를 직접 작성하는 문제보다는 내부에 매서드를 작성하여 비워진 부분을 완성시키는 형태가 많았다.
- SQL문제는 거의 조인으로 나왔는데, 그부분이 많이 약하다는 것을 느낄 수 있었다. 조인에서 점수를 다 까먹음
'개발자가 되는 길' 카테고리의 다른 글
| API 테스트 툴 - POSTMAN (0) | 2021.08.23 |
|---|---|
| 알고리즘 공부를 왜 해야 하나요? (1) | 2021.08.11 |
| 개발자 면접 질문(자바, 스프링) (0) | 2021.07.28 |
| [번역]더 이상 배우려 하지 않는 개발자 : Expert Beginner의 등장 (2) | 2021.07.25 |
| 개발자로서의 마음가짐 (0) | 2021.07.24 |
댓글