package algorithm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Stack;
public class Algorithm_Practice {
/* 알고리즘 학습전 자료구조 선행
*
* 알고리즘 풀이에 있어 적합한 자료구조를 선택하는 것은 굉장히 중요한 역할
* 동일한 로직일지라도 코드 구현이나 메모리 사용, 소요시간 등에서 많은 차이가 발생할 수 있기 때문
*/
public static void main(String[] args) {
//출처 : https://wikidocs.net/122487
//ArrayList
ArrayList<Integer> mylist=new ArrayList<Integer>();
//1. add
mylist.add(27);
mylist.add(35);
mylist.add(11);
System.out.println(mylist.toString()); //[27,35,11]
mylist.add(0,31);
System.out.println(mylist.toString()); //[31, 27, 35, 11]
//2. remove
mylist.remove(1);
System.out.println(mylist.toString()); //[31, 35, 11]
//3. get
System.out.println(mylist.get(0)); //31
//4. indexOf
System.out.println(mylist.indexOf(11)); //2
//5. size
System.out.println(mylist.size()); //3
//6. contains
System.out.println(mylist.contains(11)); //true
System.out.println("--------------------------");
//큐(Queue)
//크기가 가변성이 뛰어나며, 자료를 넣고 빼는데에 있어 속도가 무척 빠른 특징
//큐 자체가 LinkedList의 인터페이스 형태로 구현
Queue<Integer> myQ=new LinkedList<Integer>();
//1. add
myQ.add(15);
myQ.add(12);
myQ.add(43);
myQ.add(11);
System.out.println(myQ.toString()); //[15, 12, 43, 11]
//2. peek - peek은 가장 앞에 있는 값, 즉 다음에 나올 값을 확인하는 메서드, 단순하게 호출
System.out.println(myQ.peek()); //15
System.out.println(myQ.toString()); //[15, 12, 43, 11]
//3. poll - poll은 값을 호출하는 동시에 제거
System.out.println(myQ.poll()); //15
System.out.println(myQ.toString()); //[12, 43, 11]
//4. size
System.out.println(myQ.size()); //3
//5. clear - 큐의 값들을 모두 비운다는 뜻으로, 큐 자체가 사라지는 것은 아님
myQ.clear();
//6. isEmpty
System.out.println(myQ.isEmpty()); //true
System.out.println("----------------------------");
//스택(Stack)
Stack<Integer> myStack=new Stack<Integer>();
//1. add, push
myStack.add(15);
myStack.push(12);
myStack.add(43);
myStack.add(11);
System.out.println(myStack.toString()); //[15, 12, 43, 11]
//2. peek
System.out.println(myStack.peek()); //11
System.out.println(myStack.toString()); //[15, 12, 43, 11]
//3. pop - 큐의 poll과 같습니다. 값을 호출하는 동시에 제거
System.out.println(myStack.pop()); //11
System.out.println(myStack.toString()); //[15, 12, 43]
//4. size
System.out.println(myStack.size()); //3
//5. clear
myStack.clear();
//6. isEmpty
System.out.println(myStack.isEmpty()); //true
System.out.println("----------------------------");
//Priority Queue - 우선순위 큐
//자동으로 정렬이 되는 자료구조, 이후 고급알고리즘에서 설명할 다익스트라(Dijkstra)에서 사용하기도 한다.
PriorityQueue<Integer> myPQ=new PriorityQueue<Integer>();
//1. add
myPQ.add(3);
myPQ.add(7);
myPQ.add(1);
myPQ.add(4);
System.out.println(myPQ); //[1, 4, 3, 7]
//우선순위 큐는 힙을 사용하여 구성하며 내부 구조는 이진트리 형태로 구성
//값을 삽입할 때 가장 마지막에 넣은 후, 자신보다 작은 부모노드를 찾을 때 까지 이동시키는 과정을 통해 값의 위치를 정한다.
//무엇보다 이진트리 형태로 저장되기 때문에 출력 당시에는 오름차순이 아닌 형태로 보여질 수도 있는 것
//2. peek
int temp=myPQ.peek();
System.out.println(temp); //1
System.out.println(myPQ); //[1, 3, 4, 7]
//3. poll
temp=myPQ.poll();
System.out.println(temp); //1
System.out.println(myPQ); //[3, 4, 7]
while(!myPQ.isEmpty()) {
System.out.println(myPQ.poll()); //3, 4, 7
//PriorityQueue를 사용하여 값을 잔뜩 저장한 후 출력을 해보면, 우리의 예상과는 다른 결과가 나오는 경우가 많습니다.
//예를 들어, 0에서 100까지의 수 중 5개의 수를 랜덤으로 뽑아 Priority Queue에 넣고 toString을 통해 출력해 보면 아래와 같습니다.
}
Random r=new Random();
PriorityQueue<Integer> pq=new PriorityQueue<Integer>();
for(int i=0;i<5;i++) {
pq.add(r.nextInt(100));
}
System.out.println(pq.toString());
//결과: [9, 16, 20, 35, 24]
//poll을 이용하면 자동정렬 출력
for(int i=0;i<5;i++) {
System.out.println(pq.poll());
}
//결과: 9, 16, 20, 35, 24
System.out.println("----------------------------");
//맵(Map) - HashMap
//기본적으로 Map은 key:value 형태로 구성
//시험 성적으로 예를 들면, {국어=90점, 수학=80점} 식으로 구성
//각각의 과목이 key, 점수를 value라고 생각, 그리고 key는 Set와 마찬가지로 중복이 불가능
HashMap<String,Integer> myMap=new HashMap<String, Integer>();
//1. put
myMap.put("Korean", 90);
myMap.put("Math", 80);
myMap.put("English", 87);
myMap.put("Science", 90);
System.out.println(myMap.toString()); //{English=87, Science=90, Korean=90, Math=80}
myMap.put("English", 95);
//기존에 가지고 있던 값을 잃어버리고 새로운 값만 들어감 - 중복불가때문
System.out.println(myMap.toString()); //{English=95, Science=90, Korean=90, Math=80}
//2. remove
myMap.remove("English");
//remove(index의 번호)를 사용하는 것처럼 Map에서는 remove(key), key와 value가 모두 지워짐
System.out.println(myMap.toString()); //{Science=90, Korean=90, Math=80}
//3. get
System.out.println(myMap.get("Korean")); //90
//4. size
System.out.println(myMap.size()); //3
//5. contains
System.out.println(myMap.containsKey("Math")); //true
System.out.println(myMap.containsKey("English")); //false
System.out.println(myMap.containsValue(90)); //true
//6. keySet, Values
System.out.println(myMap.keySet()); //[Science, Korean, Math]
System.out.println(myMap.values()); //[90, 90, 80]
//7. forEach
for(String subject: myMap.keySet()) {
System.out.println(subject); //Science, ...
}
for(String subject: myMap.keySet()) {
System.out.println(subject+" : "+myMap.get(subject)); //Science : 90, ...
}
System.out.println("----------------------------");
}
}