[Java] Day04 - 제어문
2021-01-25 # Java

Day04 제어문

Review Day03


Q1. mid = (start + end) / 2의 문제점은?


만약 int start = 2_100_000_000, int end = 2_100_000_000 이라면 start와 end를 더하면 오버플로우가 일어날 수 있다.
따라서 중간값을 구하는 방법은 대체로 mid = start + (end-start) / 2로 한다.
한가지 신박한 방법은 java에서 제공하는 >>>연산자인데 양수일 때, mid = (start+end) >>> 1로 한다면 중간값을 구할 수 있다.
하지만 앞선 방법을 사용하는 것이 가장 안전하고 직관적이다.


Q2. numbers라는 int형 배열이 있다.
해당 배열이 들어있는 숫자들은 오직 한 숫자를 제외하고는 모두 두번씩 들어있다.
오직 한 번만 등장하는 숫자를 찾는 코드를 작성하여라.


C++의 sstream을 사용하는 방법이 떠올랐지만(Java에도 있다), 선장님께서 비트연산으로 푸는 방법을 알려주셨다.


1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args){
Hello hello = new Hello();
int result = hello.solution(new int[] {5,2,4,1,2,4,5});
System.out.println(result);
}

private int solution(int[] numbers){
int result = 0;
for (int number : numbers) {
result ^= number;
}
return result;
}

간단하다. 모든 배열안에 있는 것들끼리 XOR연산을 하게 된다면 두개가 존재하지 않는 한개의 원소만 반환하게되기 때문이다. (5 ^ 5 = 0, 5 ^ 0 = 5다.)


java13의 switch연산자


일단 switch operator는 switch statement와 다른 것이다.

  1. switch statement
1
2
3
4
5
6
7
8
9
10
11
switch(num){
case 1:
returnNum = 1;
break;
case 2:
returnNum = 2;
break;
case 3:
returnNum = 3;
break;
}

  1. switch operator
1
2
3
4
5
6
7
8
int value = switch(str){
case "hello?":
yield 1;
case "hi?":
yield 2;
default:
yield 3;
}

직관적으로 어떤의미인지 알 수 있는데, 값을 반환하는 operator이라는 것이다. 앞선방법으로 break을 사용하지 않고 yield로 값을 산출할 수 있다. 또한, var을 사용하여 각각의 경우 다른 변수타입을 반환하는 것 또한 가능하다.


Day04. 제어문


저번시간과 마찬가지로 시간이 없기 때문에.. if, while, 기타 등등 다양한 반복문과 조건문은 생략하도록 하겠다. 다음의링크에서 좋은 설명을 볼 수 있을 것이다.

for each문


for each는 J2SE 5.0 부터 추가되었다. for each 라는 키워드가 따로 있는 것은 아니고 동일한 for를 이용한다. 하지만 조건식 부분이 조금 다르다. 보통 다른 언어에서 for each 라고 많이 하므로 자바에서도 보통 for each문이라고 말한다.


기존의 for문

1
2
3
4
String[] numbers = {"one", "two", "three"};
for(int i=0; i<numbers.length; i++){
System.out.println(numbers[i]);
}

for each문

1
2
3
4
String[] numbers = {"one", "two", "three"};
for(String number: numbers) {
System.out.println(number);
}

단, for each문 같은경우에는 index로 iteration하는 것이 아니기 때문에 두개씩 건너뛰는 것이 불가능하다. 상황에 맞추어 사용하면 된다.


LinkedList 구현하기

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public class makeLinkedList {
interface LinkedList {
ListNode add(ListNode head, ListNode nodeToAdd, int position);
ListNode remove(ListNode head, int positionToRemove);
boolean contains(ListNode head, ListNode nodeTocheck);
void printList(ListNode head);
}

static class ListNode {
private int data;
private ListNode next;

public ListNode(int input) {
this.data = input;
this.next = null;
}
}

static class LinkedListImpl implements LinkedList {

public void printList(ListNode head) {
while (head != null) {
System.out.println(head.data);
head = head.next;
}
}

public int size(ListNode head) {
ListNode node = head;
int size = 1;
while (node.next != null) {
node = node.next;
size++;
}
return size;
}

public ListNode add(ListNode head, ListNode nodeToAdd, int position) {

ListNode node = head;
if (position == 0) {
if (head == null) {
return nodeToAdd;
}
ListNode add = nodeToAdd;
add.next = head;
head = add;
return head;
}

for (int i = 0; i < position - 1; i++) {
node = node.next;
}
nodeToAdd.next = node.next;
node.next = nodeToAdd;
return head;
}

public boolean contains(ListNode head, ListNode nodeTocheck) {
while (head != null) {

if (head.data == nodeTocheck.data) {
return true;
}
head = head.next;
}
return false;
}

public ListNode remove(ListNode head, int positionToRemove) {
ListNode node = head;
if (positionToRemove == 0) {
head = head.next;
} else {
for (int i = 0; i < positionToRemove - 1; i++) {
node = node.next;
}
ListNode delNode = node.next;
node.next = node.next.next;
}
return head;
}
}
}

다른것들도 천천히 구현해보겠다.