public class IntStack {
private int max;
private int ptr;
private int[] stk;
public class EmptyIntStackException extends RuntimeException {
public EmptyIntStackException() { }
}
public class OverflowIntStackException extends RuntimeException {
public OverflowIntStackException() { }
}
//--- 생성자 ---//
public IntStack(int capacity) {
ptr = 0;
max = capacity;
try {
stk = new int[max]; // 스택본체용의 배열을 생성
} catch (OutOfMemoryError e) { // 생성할 수 없음
max = 0;
}
}
public int push(int x) throws OverflowIntStackException {
if (ptr >= max) // 스택은 가득 참
throw new OverflowIntStackException();
return stk[ptr++] = x;
}
public int pop() throws EmptyIntStackException {
if (ptr <= 0)
throw new EmptyIntStackException();
return stk[--ptr];
}
public int peek() throws EmptyIntStackException {
if (ptr <= 0)
throw new EmptyIntStackException();
return stk[ptr - 1];
}
public int indexOf(int x) {
for (int i = ptr - 1; i >= 0; i--)
if (stk[i] == x)
return i;
return -1;
}
public void clear() {
ptr = 0;
}
public int capacity() {
return max;
}
public int size() {
return ptr;
}
public boolean isEmpty() {
return ptr <= 0;
}
public boolean isFull() {
return ptr >= max;
}
public void dump() {
if (ptr <= 0)
System.out.println("스택이 비어있습니다..");
else {
for (int i = 0; i < ptr; i++)
System.out.print(stk[i] + " ");
System.out.println();
}
}
}
재귀를 제거한 메소드
static void recur(int n)
{
IntStack s = new IntStack(n);
while (true) {
if (n > 0) {
s.push(n);
n = n - 1;
continue;
}
if (s.isEmpty() != true) {
n = s.pop();
System.out.println(n);
n = n - 2;
continue;
}
break;
}
}
실행 예제
public class Main{
static void recur(int n) {
IntStack s = new IntStack(n);
while (true) {
if (n > 0) {
s.push(n);
n = n - 1;
continue;
}
if (s.isEmpty() != true) {
n = s.pop();
System.out.println(n);
n = n - 2;
continue;
}
break;
}
}
public static void main(String[] args) {
recur(4);
}
}
/*
1
2
3
1
4
1
2
*/
아래의 그림에서 상자는 recur 메서드의 동작을 나타낸다. 전달받은 값이 0 이하면 아무 일도 하지 않으므로 검은색 상자로 표시되어 있다.
위의 그림은 맨 꼭대기에서 왼쪽 화살표를 따라 하나 아래 상자로 이동하고, 다시 원래의 상자로 돌아오면 회색박스의 내용을 출력하고 이어서 오른쪽 화살표를 따라 한 칸 아래 상자로 이동하면서 해석하면 된다.
이처럼 가장 위쪽에 위치한 상자의 메소드 호출부터 시작해 계단식으로 자세히 조사하는 분석 기법을 하향식 분석이라고 한다. 그런데 이 그림 안에는 recur(1), recur(2)와 같은 동일한 호출이 여러 번 있다. 꼭대기부터 분석하면 이렇게 같은 메소드의 호출이 여러 번 나올 수 있기 때문에 하향식 분석이 반드시 효율적이라고 말할 수 없다.
상향식 분석
위쪽부터 분석하는 하향식 분석과는 대조적으로 아래쪽부터 쌓아 올리며 분석하는 방법이 상향식 분석이다.
static int factorial(int n)
{
if(n == 0) return 1;
int tmp = 1;
for(int i = 1; i <= n; ++i) tmp *= i;
return tmp;
}
두 정수의 최대공약수 구하기
static int gcd(int x, int y)
{
if(y == 0) return x;
else return gcd(y, x % y);
}
실행 예제
public class Main{
static int gcd(int x, int y)
{
if(y == 0) return x;
else return gcd(y, x % y);
}
public static void main(String[] args) {
System.out.println("22와 8의 최대공약수 : " + gcd(22, 8));
}
}
/*
22와 8의 최대공약수 : 2
*/
유클리드 호제법 위 알고리즘은 유클리드 호제법을 이용한 것이다. 두 정수를 직사각형의 두 변의 길이라고 생각하면 두 정수의 최대공약수를 구하는 문제는 직사각형을 정사각형으로 완전히 채우고 이렇게 만들 수 있는 정사각형의 가장 긴 변의 길이를 구하면 된다.
1. 짧은 변의 길이를 한 번으로 하는 정사각형으로 채운다. 2. 남은 직사각형에 대해 같은 작업을 반복 3. 정사각형만으로 구성되었을 때의 변의길이가 최대공약수
재귀를 사용하지 않은 두 정수의 최대공약수를 구하는 알고리즘은 아래와 같다.
static int gcd(int x, int y)
{
while(y != 0)
{
int temp = y;
System.out.println(y + " " + x);
y = x % y; //y에 나머지 저장
x = temp;
}
return x;
}
배열의 모든 원소의 최대공약수 구하기
import java.util.Scanner;
public class Main{
static int gcd(int x, int y) {
if(y == 0) return x;
else return gcd(y, x % y);
}
static int gcdArray(int arr[], int start, int no) {
if (no == 1) return arr[start];
else if (no == 2) return gcd(arr[start], arr[start + 1]);
else return gcd(arr[start], gcdArray(arr, start + 1, no - 1));
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("정수 몇 개의 최대 공약수를 구할까요?:");
int num;
do {
num = sc.nextInt();
} while (num <= 1);
int[] arr = new int[num];
for (int i = 0; i < num; i++) {
System.out.print("x[" + i + "]:");
arr[i] = sc.nextInt();
}
System.out.println("최대 공약수는 " + gcdArray(arr, 0, num) + "입니다.");
}
}
/*
정수 몇 개의 최대 공약수를 구할까요?:3
x[0]:25
x[1]:1525
x[2]:2000
최대 공약수는 25입니다.
*/
본 게시글은 유튜브 : 경제 TV 너무경 : 너무 쉬운 경제 윤성종 님의 유튜브 영상을 참고하였습니다. 개인적으로 정리하는 글임을 알립니다.
금융용어정리 - 공매도, 대주거래, 대차거래, 대차잔고, 대차잔액
공매도
주식을 빌려서 미리 판 후에 주식으로 되갚아야 하는 매도
공매도는 주가가 하락할 것을 예상하는 경우에 실행한다.
수익은 최대100%까지이고 손해는 무한대로 클 수 있다.
예를 들어 ㈜코딩의 주가가 현재 10,000원이고, A씨는 ㈜코딩의 주식을 1주 갖고 있다. B씨는 A씨에게 ㈜코딩의 주식 1주를 빌리고 한 달 뒤에 갚기로 했다. B씨는 ㈜코딩의 주식을 만 원에 매도해서 현재 현금 만 원을 보유하고 있다. 이때 두 가지의 경우가 있다.
㈜코딩의 주가가 하락했을 때 한 달뒤, A씨에게 빌린 주식을 갚기 위해 ㈜코딩의 주가를 봤더니 7천 원으로 하락했다. 1주를 7천원에 매수하여 A씨에게 갚았다. 이 경우 B씨는 3천 원의 이득을 본 셈이다.
㈜코딩의 주가가 상승했을 때 한 달뒤, A씨에게 빌린 주식을 갚기 위해 ㈜코딩의 주가를 봤더니 1만 3천 원으로 상승했다. 1주를 1만 3천원에 매수하여 A씨에게 갚았다. 이 경우 B씨는 3천 원의 손해를 본 셈이다.
㈜코딩의 주가가 최대로 하락했을 때의 가격은 0원이다. 따라서 최대 100%의 이득을 보는 것이지만, ㈜코딩의 주가가 최대로 상승했을 때의 가격은 알 수 없다. 즉, 수익은 최대 100%까지이고 손해는 무한대로 클 수 있다.
공매도를 할 때 주식을 빌린다. 주식을 빌리는 것을 크게 대주거래와 대차거래로 나눌 수 있다.
대주거래
기관이 개인투자자에게 주식을 빌려주는 거래
특징 : 소규모, 장내거래, 이자가 높다, 대여기간이 짧다(1~2개월)
대차거래
기관이 기관에게 주식을 빌려주는 거래
특징 :대규모,장외거래, 이자가 낮다, 대여기간이 길다(1년)
대주거래나 대차거래에서는 빌려주는 사람이나 빌리는 사람이나 의결권은 모두 잃는다. 하지만 배당금은 어쨌든 소유자는 빌려주는 사람이므로 배당금은 빌려주는 사람이 받는다.
본 게시글은 유튜브 : 경제 TV 너무경 : 너무 쉬운 경제 윤성종 님의 유튜브 영상을 참고하였습니다. 개인적으로 정리하는 글임을 알립니다.
금융용어정리 - 따상
따상
따상은 아래의 조건을 만족하는 경우를 칭하는 속어이다.
시가가 공모가(주식시장에 최초로 상장될 때의 주식 한 주당 가격)의 두 배가 된 경우
종가가 시가의 +30%인 경우
시가 장 시작전 동시호가매매시간이 끝남과 동시에 시가가 결정된다. 시가는 시초가라고 부르기도 한다.
주식 시장에서 주가는 최대 30% 상승 또는 하락할 수 있다. 이는 동시호가도 마찬가지이다.
하지만 한 가지 예외가 있는데, 처음 상장하는 날은 동시호가가 -10% ~ 100%까지 하락 또는 상승이 가능하다.
예를 들어 공모가 5,000원으로 상장하고 장 시작전 동시호가매매시간(08:30~09:00)이 끝나고 시가가 공모가의 두 배가 되어 시가가 1만 원으로 형성되고 또다시 15:20 ~ 15:30에 동시호가매매시간이 끝나고 종가가 시가의 30% 상승한 13,000원이 되면 따상에 성공한 것이다.
public class IntAryQueue {
private int max; //큐 용량
private int num; //현재 데이터 수
private int[] que;
IntAryQueue(int capacity) //생성자
{
this.max = capacity;
que = new int[max];
num = 0;
}
private boolean isFull() {return num >= max;} //큐의 공간이 모두 사용중인지 리턴
private boolean isEmpty() {return num <= 0;} //큐의 공간이 비어있는지 리턴
public int capacity() {return max;} //큐의 용량을 리턴
public int size() {return num;} //큐의 현재 데이터 수를 리턴
public void enque(int value)
{
if(!isFull()) que[num++] = value;
else System.out.println("큐의 공간을 모두 사용중입니다.");
}
public void deque()
{
if(!isEmpty())
{
for (int i = 1; i < num; ++i)
{
que[i-1] = que[i];
}
que[--num] = 0;
}
else System.out.println("이미 큐의 공간이 비어있습니다.");
}
public void peek() //큐의 front를 리턴
{
if(num > 0) System.out.println("front : " + que[0]);
else System.out.println("큐의 공간이 비어있습니다.");
}
public void back() //큐의 rear을 리턴
{
if(num > 0) System.out.println("rear : " + que[num- 1]);
else System.out.println("큐의 공간이 비어있습니다.");
}
public void indexOf(int value) //큐에서 찾는 데이터가 있는지 출력
{
for(int i = 0; i < num; ++i)
{
if(que[i] == value)
{
System.out.println("찾는 값이 있습니다. 인덱스 : " + i);
return;
}
}
System.out.println("찾는 값이 없습니다.");
}
public void clear() {num = 0;} //큐의 front를 초기화 시킴
public void dump() //모든 큐의 값을 출력
{
if(isEmpty())
{
System.out.println("큐가 비어있습니다.");
return;
}
for (int i = 0; i < num; ++i)
{
System.out.println("[" + i + "]" + "=" + que[i]);
}
}
}
import java.util.Scanner;
public class Main2{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("큐 용량 입력 : ");
int command = sc.nextInt();
IntQueue que = new IntQueue(command);
while(true)
{
System.out.println();
System.out.println("현재 데이터 수 : " + que.size() + "/" + que.capacity());
System.out.println("(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit");
System.out.print("cmd : ");
command = sc.nextInt();
if(command == 1)
{
System.out.print("value : ");
command = sc.nextInt();
que.enque(command);
}
else if(command == 2) que.deque();
else if(command == 3)
{
System.out.print("Data for Search: ");
command = sc.nextInt();
que.indexOf(command);
}
else if(command == 4) que.peek();
else if(command == 5) que.dump();
else if(command == 6) que.clear();
else if(command == 7) System.exit(0);
else continue;
}
}
}
/*
큐 용량 입력 : 5
현재 데이터 수 : 0/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 1
현재 데이터 수 : 1/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 2
현재 데이터 수 : 2/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 3
현재 데이터 수 : 3/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 4
현재 데이터 수 : 4/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 5
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 4/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 3/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 6
현재 데이터 수 : 4/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 7
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 5
1번째 데이터 : 3
2번째 데이터 : 4
3번째 데이터 : 5
4번째 데이터 : 6
5번째 데이터 : 7
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 3
Data for Search: 5
5는 큐의 3번째 데이터이고, 배열의 4인덱스에 있습니다.
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 4/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 3/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 2/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 8
현재 데이터 수 : 3/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 9
현재 데이터 수 : 4/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 1
value : 10
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 5
1번째 데이터 : 6
2번째 데이터 : 7
3번째 데이터 : 8
4번째 데이터 : 9
5번째 데이터 : 10
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 22
현재 데이터 수 : 5/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 4/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 3/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 2/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 1/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
현재 데이터 수 : 0/5
(1)inqueue (2)dequeue (3)search (4)peek (5)dump (6)clear (7)exit
cmd : 2
이미 큐가 비어있습니다.
*/
링 버퍼의 활용
링 버퍼는 오래된 데이터를 버리는 용도로 사용할 수 있다.
예를 들면 요소의 개수가 n개인 배열에서 계속해서 데이터가 입력될 때 가장 최근에 들어온 데이터 n개만 저장하고 오래된 데이터는 버리는 용도로 사용한다.
예제 아래의 예제는 배열 a의 길이는 10이다. 인큐는 무한히 할 수 있지만, 배열에 저장되는 데이터는 가장 최근에 입력한 10개의 데이터만 링 버퍼에 남아있다.
import java.util.Scanner;
// 원하는 개수만큼 값을 입력 받아 요솟수 N인 배열에 마지막 N개를 저장
class LastNElements {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
final int N = 10;
int[] a = new int[N]; // 입력 받은 값을 저장
int cnt = 0; // 입력 받은 개수
int retry; // 다시 한 번?
System.out.println("정수를 입력하세요.");
do {
System.out.printf("%d번째 정수:", cnt + 1);
a[cnt++ % N] = stdIn.nextInt();
System.out.print("계속 할까요? (예.1/아니오.0):");
retry = stdIn.nextInt();
} while (retry == 1);
int i = cnt - N;
if (i < 0) i = 0;
for ( ; i < cnt; i++)
System.out.printf("%2d번째의 정수 = %d\n", i + 1, a[i % N]);
}
}
데크(deque)
deque(Double Ended Queue)는 인큐와 디큐가 배열의 양쪽 끝에서 모두 발생할 수 있는 자료구조이다.
스택은 데이터를 일시적으로 저장하기 위한 자료구조로, 가장 나중에 넣은 데이터를 가장 먼저 꺼낸다.
데이터의 입력과 출력 순서는 후입선출(LIFO, Last In First Out)이다. 스택에 데이터를 넣는 작업을 푸시라 하고, 스택에서 데이터를 꺼내는 작업을 팝이라고 한다.
이렇게 푸시와 팝을 하는 위치를 꼭대기(top)라 하고, 스택의 가장 아랫부분을 바닥(bottom)이라고 한다.
int 배열을 이용한 IntStack 클래스
public class IntStack {
private int max;
private int ptr;
private int []stk;
public IntStack(int capacity) //생성자
{
max = capacity;
ptr = 0;
stk = new int[max];
}
private boolean isFull() {return ptr >= max;} //스택이 용량이 남아있는지 리턴
private boolean isEmpty() {return ptr <= 0;} //스택 비어있는지 리턴
public void push(int value)
{
if(!isFull()) stk[ptr++] = value;
else System.out.println("스택의 남은 용량이 없습니다.");
}
public void pop()
{
if(!isEmpty()) --ptr;
else System.out.println("이미 스택이 비어있습니다.");
}
public void peek() //스택의 꼭대기 값을 출력
{
if(!isEmpty()) System.out.println(stk[ptr-1]);
else System.out.println("스택이 비어있습니다.");
}
public void indexOf(int value) //스택에서 원하는 값을 검색
{
for(int i = ptr -1; i >= 0; --i)
{
if(stk[i] == value)
{
System.out.println("찾는 값이 있습니다. 인덱스 : " + i);
return;
}
}
System.out.println("찾는 값이 없습니다.");
}
public void clear() {ptr = 0;} //ptr을 0으로 바꿔줌으로서 스택에 쌓인 데이터가 0으로 인식
public int capacity() {return max;} //스택의 최대용량 리턴
public int size() {return ptr;} //데이터 수를 확인 하는 메소드
public void dump() //스택 안에 있는 모든 데이터를 표시하는 메소드
{
if(isEmpty())
{
System.out.println("스택이 비어있습니다.");
return;
}
for (int i = 0; i < ptr; ++i)
{
System.out.println("[" + i + "]" + "=" + stk[i]);
}
}
}