• [ 장르 ] Heap 또는 Priority_queue
  • [ 문제 ]
 

11279번: 최대 힙

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이�

www.acmicpc.net

  • Code 1 ( 힙 을 구현한 ver. )
#include <iostream>
#include <vector>

using namespace std;
vector<int> arr;
int n = 0;

void downHeap(int idx)
{
	int greater, tmp;
	if (idx * 2 <= arr.size()-1)
	{
		greater = idx * 2;
		if (idx * 2 + 1 <= arr.size()-1)
			if (arr[greater] < arr[idx * 2 + 1])
				greater = idx * 2 + 1;
		if (arr[greater] > arr[idx])
		{
			tmp = arr[idx];
			arr[idx] = arr[greater];
			arr[greater] = tmp;
			downHeap(greater);
		}
	}
}
void upHeap(int idx)
{
	int max;
	if (idx / 2 >= 1)
	{
		if (arr[idx] > arr[idx / 2])
		{
			max = arr[idx];
			arr[idx] = arr[idx / 2];
			arr[idx / 2] = max;
			upHeap(idx / 2);
		}
	}
}
void InsertItem(int data)
{
	arr.push_back(data);
	upHeap(arr.size()-1);
	//n = n + 1;
}
int removeMax()
{
	if (arr.size() >= 2)
	{
		int rootValue = arr[1];

		arr[1] = arr.back();
		arr.pop_back();
		downHeap(1);
		//n = n - 1;

		return rootValue;
	}
}

int main()
{
  	cin.tie(NULL); cout.tie(NULL); ios_base::sync_with_stdio(false);	// ★ C++의 입출력속도개선의 매우중요
	int opcnt,X;
	arr.push_back(0);
	cin >> opcnt;
	for (int i = 0; i < opcnt; i++)
	{
		cin >> X;
		if (X == 0)
		{
			if (arr.size() == 1)
				cout << 0 << '\n';	// ★ 개행도 endl이 아닌 '\n'을 쓸 것
			else
				cout << removeMax() << '\n';
		}
		else
			InsertItem(X);
	}
	return 0;
}
  • Code 2 ( Priority_queue를 활용한 ver. ( 정확히는 힙은 아닌 것 같다. )
#include <iostream>
#include <queue>

using namespace std;
int main()
{
	cin.tie(NULL); cout.tie(NULL); ios_base::sync_with_stdio(false);
	priority_queue<int> q;		// 우선순위 큐 ( FIFO,First In First Out )
	int opcnt,X;

	cin >> opcnt;
	for (int i = 0; i < opcnt; i++)
	{
		cin >> X;
		if (X == 0)
		{
			if (q.empty())
				cout << 0 << '\n';
			else
			{
				cout << q.top() << '\n';	// 우선순위 큐의 front 요소출력
				q.pop();	// front요소 pop
			}
		}
		else
			q.push(X);	// 우선순위 큐는 push하면서 자동으로 front에서부터 내림차순정렬
	}
	return 0;
}

 " 알고리즘 문제를 풀 때는 딱 어떤 자료구조를 이용해야하는지 정해진 건 없다.
그 문제에서 요구하는 것이 아니어도 좀 더 효율적이라면 그걸 쓰자. "

[ CheckPoint ]

  • 문제는 간단하다고 생각했으나 풀면서, 생각보다 몰랐던 부분, 생각해야 할 부분이 많았던 문제였다.
  • 먼저, 최근에 나는 Heap에 대한 이론을 깨우쳐서 이 문제를 처음에는 힙을 만드는 과정의 삽입,삭제를 일일히 구현해서 메인에서 사용했다.
  • 근데 생각해보니, 이 문제만 봤을 떈, 결국 삽입시에는 상관없고, 삭제하면서 출력시에 최대 값만 출력하면 되는 문제였다보니, 꼭 힙을 써야할까 ?
    생각이 들었다. 결론은 그러지 않아도 된다 !
  • C++로 알고리즘 풀면서 이번에 queue container에 priority_queue를 쓰면
    매우 유용한 부분이 또 있다는 것을 알았다.
  • 이는, queue와 기본적으로 FIFO형태라 보면 되는데, 특이점은 요소를 삽입시, default옵션이 자동으로 내림차순으로 PQ안에 요소들이 정렬된다는 것!
    문제에선 삭제시, 배열 내에 최대값을 삭제하면서 출력하는 것이 었으니
    queue.top( )을 통해서 큐에 front에 요소를 top( )하고, 후에 pop( )을하면 간단했다.
  • 그리고, 무엇보다 이번에 가장 중요한 포인트는, 입출력과 관련된 시간이었다. 로직은 분명히 맞다. 맞는데. 이상하게 계속 시간초과가 뜬다. 이래저래 수를 써봤는데 변화가 없었다. 그러던 차에 구글링을 했더니 중요한 사항을 발견했다.
  1. 글의 내용에서, C++기준으로 정리를 하자면, 입출력을 할때, 조금이라도 더 빠른 실행시간이 필요하다면, C++의 입출력인 cin,cout에 대해서
    cin.tie(NULL) , cout.tie(NULL) , ios_base::sync_with_stdio(false) 를 메인 문두에 선언
  2. C++에서 개행 시에도 endl보다 '\n'을 사용하는 것이 속도적인 면에도 좋다.

그 외 백준알고리즘문제를 풀면서 참고해야 BOJ(Baekjoon) 참고사항 링크를 아래에 걸어둔다.
https://www.acmicpc.net/blog/view/55

728x90
반응형

'Algorithm Practice > [ Baekjoon ]' 카테고리의 다른 글

[Baekjoon][#10866] 덱(Deque)  (0) 2020.09.24
[Baekjoon][#11729] 하노이 탑 이동순서  (0) 2020.09.23
[Baekjoon][#18258] 큐 2  (0) 2020.09.22
[Baekjoon][#1991] 트리순회  (0) 2020.09.21
[Baekjoon][10828번] 스택  (0) 2020.09.18
  • [ 장르 ] 스택
 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 �

www.acmicpc.net

  • Code 1 ( 입력 문자열 기능비교시 string.compare(string) 사용한 경우 ) 
// string.compare(string) 사용한 경우
#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main()
{
	int cnt,data;
	stack<int> s;
	string str;
	//char str[5];
	cin >> cnt;
	
	for (int i = 0; i < cnt; i++)
	{
		cin >> str;
		//scanf("%s", str);
		if (str.compare("push") == 0)
		{
			cin >> data;
			s.push(data);
		}
		else if (str.compare("pop") == 0)
		{
			if (s.empty())
				cout << -1 << endl;
			else
			{
				cout << s.top() << endl;
				s.pop();
			}
		}
		else if (str.compare("top") == 0)
		{
			if (s.empty())
				cout << -1 << endl;
			else
				cout << s.top() << endl;
		}
		else if (str.compare("size") == 0)
			cout << s.size() << endl;
		else
		{
			if (s.empty())
				cout << 1 << endl;
			else
				cout << 0 << endl;
		}
	
	}
}
  • Code 2 ( 입력 문자열 기능비교시 strcmp(string1,string2) 사용한 경우 )
// strcmp(string,string) 사용한 경우
#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main()
{
	int cnt, data;
	stack<int> s;
	//string str;
	char str[5];
	cin >> cnt;

	for (int i = 0; i < cnt; i++)
	{
		//cin >> str;
		scanf("%s", str);
		if (strcmp(str,"push") == 0)
		{
			cin >> data;
			s.push(data);
		}
		else if (strcmp(str, "pop") == 0)
		{
			if (s.empty())
				cout << -1 << endl;
			else
			{
				cout << s.top() << endl;
				s.pop();
			}
		}
		else if (strcmp(str, "top") == 0)
		{
			if (s.empty())
				cout << -1 << endl;
			else
				cout << s.top() << endl;
		}
		else if (strcmp(str, "size") == 0)
			cout << s.size() << endl;
		else
		{
			if (s.empty())
				cout << 1 << endl;
			else
				cout << 0 << endl;
		}
	}
}

" C++에서 scanf,printf 와 cout,cin 의 차이가 있다. ! "

[ CheckPoint ]

  • 일단, 문제는 말 그대로 스택에 기본적인 기능에 대해 구현하는 것이라서 어렵지 않다. 다만 pop이나 top을 할 때 항상 스택이 비어있는데 참조할려고 하지 않는지 empty를 통해서 사전에 방지해야한다.
    그렇지 않으면 런타임 에러가 발생한다.
  • 그 외적으로, 문제를 풀면서 알게 된것은, 이 문제에서 스택에 기능을 영어 문자열로 입력을 받는데, 나는 최근까지 C언어를 많이 사용하다보니 문제가 쉬워보인다는 이유로 아무 생각없이 변수를 C++에있는 string변수로 선언하고 입력은 또 scanf( )로 받았다. 거기에 입력받은 문자는 각 "push","pop","top","size" 에 입력받은 문자열을 string container에 내장된 compare( ) 함수로 비교를 할려고 했다.
  • 그러다 보니 아무리 제대로 문자열을 입력한 것 같아보여도, 결과적으론 문자열이 입력 받는거까진 좋은데, compare( ) 연산을하는데 이론상은 두 문자열이 같으면 0 을 반환하는 걸 이용해야하는게 그것이 적용이 안되는 것이다. 반대로 strcmp를 이용해 봤는데 이 역시 받아 들이질 않았다.
  • 결론적으론, string변수를 쓴건 좋고, 그러면 입력과 출력을 C++의
    cout 와 cin만 이용을하거나, strcmp를 쓰면 char 형태의 배열을 선언해서 scanf printf를 만을 사용해서, scanf,printf 와 cin,cout 간의 두 입출력함수가 동시에 쓰이는 경우를 없애야한다.
  • 이유는 혼동 되서 쓰이게 되면 싱크가 맞지 않아서 프로그램안에서 입력 순서가 바뀌는 참사가 발생한다고 한다.
    [ 참고자료 ]

  • 추가적으로 프로그램 성능(실행시간)면에서 봤을 때, scanf,printf보다 cin,cout가 무거운 함수이다. 간단한 이유를 생각해보면, scanf,printf는 안에 형식들이 일일히 정해져서 들어가지만, cin,cout는 그냥 변수명만 넣기 때문에 컴파일러 내부적으로 이게 무슨 자료형이지 ? 등을 생각해야하기 때문에 당연히 속도적으로 느릴 수 밖에 없다.

 

저의 설명에 잘못됬거나 하는 것이 있다면 의견을 부탁드립니다.


 

728x90
반응형

'Algorithm Practice > [ Baekjoon ]' 카테고리의 다른 글

[Baekjoon][#10866] 덱(Deque)  (0) 2020.09.24
[Baekjoon][#11729] 하노이 탑 이동순서  (0) 2020.09.23
[Baekjoon][#18258] 큐 2  (0) 2020.09.22
[Baekjoon][#1991] 트리순회  (0) 2020.09.21
[Baekjoon][#11279] 최대 힙  (0) 2020.09.20
  • [ 장르 ] Sort
 

코딩테스트 연습 - H-Index

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다. 어떤 과학자가 발표

programmers.co.kr


  • Code
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int solution(vector<int> citations) {
    sort(citations.begin(), citations.end(), greater<int>());

    for (int i = 0; i < citations.size(); ++i) {
        if (citations[i] < i + 1) {
            return i;
        }
    }

    return citations.size();
}

" H-Index 란 무엇인가 ? "

[ CheckPoint ]

  • 문제에대한 이해가 왠만한사람은 잘못된 길로 갈 가능성이 큰 문제다.
  • [ 3,0,6,1,5 ] 일때 내림차순을 통해 [ 6,5,3,1,0 ] 에서 '3'일때 자기보다 크거나같은 요소는 3개, '3'보다 작은 수는 자기를 제외하고 2개니깐 답이 '3'이 ! 아니라, 이는 표를 통해 확인하자.

 총 인용 수 ( 내림차순 )

 순위

일때, 총 인용 수 < 순위이기 바로 직전 순위가 바로 "H-Index"이다. 애초에 Index하니깐 Index가 답이지 어떤 값이 정답이 되는게 아닌 듯하다.

다른 예로, [ 1,7,0,1,6,4 ] 가 있다 치자.

총 인용 수 ( 내림차순 ) 

순위 

 7

일때, 여기서 H-Index는 '3' 이다.

H-index 정의를 가져오자면, "피 인용수( Citation ) 가 논문의수( Index,No. ) 와 같아지거나 작아지기 시작하는 No.( = Index ) 가 H-Index이다.

이를 의미적으로 접근하면,예로들어 전체 논문의 수가 5편이고, H-Index가 3 이라함은 그 중, "3편의 논문은 3회이상 인용되었습니다. 그리고 나머지 2편의 논문은 3회 이하 인용되었기 떄문에 H-Index는 3입니다." 이다.


728x90
반응형
  • [ 장르 ] STACK
  • [ 문제 ]

[#42584] 주식가격

초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.

programmers.co.kr
  • My Code
#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> prices) {
    vector<int> answer;
    int NoDownDuring;		// 해당시점 이후, 주식가격 낮아지기까지 시간체크
    
    answer.assign(prices.size(), 0);		// 주식 수 만큼 정답 벡터 0으로 초기화
    for(int i = 0 ; i < prices.size(); i++)
    {
        NoDownDuring = 0;		// 시간측정은 현 시점부터 0부터 시작
        for(int j = i + 1; j < prices.size(); j++)	
        {
            NoDownDuring++;
            if(prices[i] > prices[j])	// 현 시점 주식에서 뒤에 주식중에 현 시점 주식보다 낮은 시점
                break;
        }
        answer[i] = NoDownDuring;		// 현 시점에서 주식이 낮아지기까지 시간 벡터에 삽입
    }
    return answer;
}
  • Another Code
#include <string>
#include <vector>
#include <stack>

using namespace std;

vector<int> solution(vector<int> prices)
{
    vector<int> answer(prices.size());
    stack<int> s;
    int size = prices.size();

    for (int i = 0; i<size; i++)
    {
        // 스텍이 차있으면서 가격이 떨어지기 시작하면
        while (!s.empty() && prices[s.top()] > prices[i])
        {
            answer[s.top()] = i - s.top();
            s.pop();
        }

        // 가격이 올라갈때동안 스텍에 넣음
        s.push(i);
    }

    // 스텍에 남은것들을 계산해줌
    while (!s.empty())
    {
        answer[s.top()] = size - s.top() - 1;
        s.pop();
    }

    return answer;
}

" 알고리즘 풀 때는 성능(주로, 실행시간) 에 대해서 생각을 해보자. "


[ CheckPoint ]

  • 문제 의도만 파악하면, 문제는 어렵지 않은 문제다.
  • 주된 장르는 스택인데, 나는 풀고나니 스택을 안았다. 스택을 써야하는 발상이 나지 않았다.
  • 풀고나서보니, 최악의 상황 prices 벡터크기가 10000개이고, 모든 주식 가격이 같다면, 총 실행시간은 O(n^2)시간이 될 수 있다. 이는 굉장히 비효율적일 수 있는데, 이 문제는 이 사항은 수용하기로 했나보다.
  • 다른 사람의 코드를 보면, 반복문이 2개가지만, 스택을 잘 활용해서 적어도 O(n^2)의 시간은 걸리지 않다는 것을 알 수있다.

 

728x90
반응형
  • 변수 ( Variable ) = 값을 저장할 수 있는 공간. 변할 수 있는 값
  • 예약어 = 정해진 기능을 수행하도록 이미 용도가 정해져 있는 단어. 변수로 사용 X
  • 기억클래스 = 변수 선언 시 변수의 값을 저장하기 위한 기억영역을 결정하는 작업
  1. 자동 변수( Automatic Variable ) 
    : 함수나 코드의 범위를 한정하는 블록 내에서 선언되는 변수
    초기화하지 않으면 쓰레기값(Garbage Value) 저장, 함수나 블록 벗어나면 자동으로 소멸
  2. 외부 변수( External Variable )
    : 현재 파일이나 다른 파일에서 선언된 변수나 함수를 참조하기위한 변수
    함수 밖에서 선언, 함수가 종료된 뒤에도 값이 소멸 X, 초기화하지 않으면 자동으로 0으로 초기화 된다. 다른 파일에서 선언된 변수를 참조할 경우 초기화 할 수 없다.
  3. 정적 변수( Static Variable )
    : 함수나 블록 내에서 선언하는 내부 정적변수,함수 외부에서 선언하는 외부 정적변수.
    선언한 함수나 블록 내에서만 사용, 외부 정적변수는 모든 함수 사용가능 
    함수나 블록이 종료되도 값이 소멸하지 X, 초기화는 선언 시 한번만.
    초기화 생략시 자동으로 초기화.
  4. 레지스터 변수 ( Register Variable )
    : 메모리가 아닌 CPU 내부의 레지스터에 기억영역을 할당받는 변수.
    자주 사용되는 변수를 레지스터에 저장. 처리속도 높임.
    함수나 블록에서 벗어나면 자동으로 소멸. 레지스터 사용 개수 한정.
    변수의 주소를 구하는 주소연산자(&)를 사용할 수 없다.   


연산자 우선순위

단항연산자 ( !, ~, ++, --, sizeof )
>> 산술연산자 ( *, /, %, +, - )
>> 시프트 연산자 ( << , >> )
>> 관계연산자 ( <, <=, => , > )
>> 비트연산자 ( &, ^, | )
>> 논리연산자 ( &&, || )
>> 조건연산자(  조건 ? 실행문1 : 실행문2 )
>> 대입연산자 ( =, +=, -=, *=, /=, %=, <<=, >>= 등 )
>> 순서연산자 (,(콤마)) 순


포인터

  • 포인터 변수는 필요에 의해 동적으로 할당되는 메모리 영역인 "힙 영역"에 접근하는 동적 변수이다.
  • 메모리 영역
    • 코드 영역 : 실행할 프로그램의 코드가 저장됨
    • 힙 영역 : 필요에 의해 동적으로 할당되는 영역
    • 스택 영역 : 함수의 매개 변수와 지역변수가 저장됨
    • 데이터 영역: 전역 변수와 정적 변수가 저장됨


함수 포인터

  • C언어에서 함수 이름은 해당 함수가 시작되는 주소를 의미
    변수의 주소를 포인터 변수에 저장하는 것처럼 함수의 주소도 함수 포인터에 저장할 수 있을 뿐만 아니라 함수 포인터를 이용해서 함수를 호출할 수 있다.
  • ex) int (*pf)(int,int);  << 함수 포인터 선언
    pf = 함수이름;  << 함수포인터 함수이름에 연결
    pf( int형변수,int형변수 ); 함수형포인터로 함수호출


절차적 프로그래밍 언어

  • 장점
    1. 실행속도가 빠르다.
    2. 구조적 프로그래밍이 가능하다.
  • 단점
    1. 프로그램 분석이 어렵다.
    2. 유지보수나 코드수정이 어렵다.
  • 종류
    • C
      = 포인터를 제공하며, 고급프로그래밍 언어이면서 저급프로그램
      언어이다. 컴파일러 방식의 언어
    • ALGOL
      = 수치계산이나 논리 연산을 위한 과학 기술 계산용 언어이다.
    • COBAL
      = 사무 처리용 언어이다.
    • FORTRAN
      = 과학 기술 계산용 언어이다.


객체지향 프로그래밍 언어

  • 객체지향 프로그래밍 언어
    = 현실 세계의 개체(Entity)를 기계의 부품처럼 하나의 객체로 만들어 기계적인 부품들을 조립하여 제품을 만들 듯, 프로그램을 작성할 수 있도록 한 프로그래밍 기법
  • 장점
    1. 상속을 통한 재사용과 시스템 확장이 용이
    2. 코드의 재활용성이 높다.
    3. 모델링에 의해 분석과 설계를 쉽 효율적으로 할 수 있다.
    4. 대형 프로그램의 작성의 용이하다.
    5. 소프트웨어 개발 및 유지보수가 용이하다.
  • 단점
    1. 구현 시 처리 시간이 지연된다.
  • 종류
    • Java,C++,Python 정도


객체지향 프로그래밍 언어의 특징

  • 캡슐화 ( Encapsulation )
    1. 데이터와 데이터를 처리하는 함수를 하나로 묶는 것
    2. 세부내용이 외부에 은폐(정보 은닉)되어, 변경이 발생 할 때 오류의
      파급효과가 적다.
    3. 캡슐화된 객체들은 재사용이 용이하다.
  • 정보은닉 ( Information Hiding )
    1. 캡슐화에서 가장 중요한 개념으로, 다른 객체에게 자신의 정보를 숨기고 자신의 연산만을 통하여 접근을 허용
  • 추상화 ( Abstraction )
    1. 불필요한 부분을 생략하고 객체의 속성 중 가장 중요한 것에만 중점을 두어 개략화 한 것, 즉 "모델화" 하는 것이다.
    2. 데이터의 공통된 성질을 추출해서 슈퍼 클래스를 선정하는 개념이다.
  • 상속성 ( Inheritance )
    1. 이미 정의된 상위 클래스(부모 클래스)의 모든 속성과 연산을 하위 클래스가 물려 받는 것이다.
    2. 상속성을 이용하면 하위 클래스는 상위 클래스의 모든 속성과 연산을 자신의 클래스 내에서 다시 정의하지 않고서도 즉시 사용할 수 있다.
  • 다형성 ( Polymorphism )
    1. 메시지에 의해 객체(클래스)가 연산을 수행할 때 하나의 메세지에 대해 각 객체가 가지고 있는 고유한 방법으로 응답할 수 있는 능력
    2. 객체들은 동일한 메소드명을 사용하며 같은 의미의 응답을 한다.


스크립트 언어 ( Script Language )

  • 스크립트언어
    = HTML문서 안에 직접 프로그래밍 언어를 삽입하여 사용. 기계어로
    컴파일 되지 않고 별도의 번역기가 소스를 분석하여 동작하는 언어
    - 서버용 스크립트 언어 : ASP, JSP, PHP, 파이썬
    - 클라이언트용 스크립트 언어 : 자바 스크립트
  • 장점
    1. 컴파일 없이 바로 실행가능. 결과를 바로 확인
    2. 배우고 코딩하기 쉽다.
    3. 개발 시간이 짧다.
    4. 소스코드를 쉽고 빠르게 수정할 수 있다.
  • 단점
    1. 코드를 읽고 해석해야 하므로 실행 속도가 느리다.
    2. 런타임 오류가 많이 발생한다.
  • 종류
    • 자바 스크립트 ( Java Script )
      = 클라이언트용 스크립트 언어. 웹 페이지 동작을 제어.
      변수 선언이 필요없음. 서버에서 데이터를 전송할 때 입력 사항을 확인하기 위한 용도로 많이 사용
    • ASP ( Active Server Page )
      = 서버 측에서 동적으로 수행되는 페이지를 만들기 위한 언어
      MS사에서 제작. Windows 계열에서만 수행 가능한 프로그래밍 언어
    • JSP ( Java Server Page )
      = Java로 만들어진 서버용 스크립트 언어로, 다양한 OS에서 사용 가능
    • PHP ( Professional Hypertext Preprocessor )
      = 서버용 스크립트 언어. Linux, Unix, Windows OS에서 사용이 가능
      C,Java 등과 문버이 유사하므로 배우기 쉬어 웹 페이지 제작에 사용
    • 파이썬
      = 객체지향 기능을 지원하는 대화영 인터프리터 언어.
      플랫폼에 독립적이고 문법이 간단하여 배우기 쉽다.


선언형 언어 vs 명령형 언어

  • 선언형 언어
    = 프로그램이 수행해야 할 문제를 기술한 언어.
    1. 목표를 명시하고 알고리즘은 명시하지 않는다.
    2. 함수형 언어와 논리형 언어 등이 있다.
  • 명령형 언어
    = 문제를 해결하기 위한 방법을 기술한 언어.
    1. 알고리즘을 명시하고 목표는 명시하지 않는다.
    2. 절차적 언어와 객체지향 언어가 있다.
  • 선언형 프로그래밍 언어 종류
    • HTML
      = 인터넷 표준 문서인 하이어텍스트 문서를 만들기 위해 사용한 언어
      특별한 데이터 타입이 없는 단순한 텍스트이므로, 호환성이 좋고 사용이 편리하다.
    • XML
      = 기존 HTML의 단점을 보완하여 웹에서 구조화된 폭넓고 다양한 문서들을 상호 교환할 수 있도록 설계된 언어.
      HTML에 사용자가 새로운 태크(Tag)를 정의할 수 있으며, 문서의 내용과 이를 표현하는 방식이 독립적이다.
    • PROLOG
      = 논리학을 기초로 한 고급언어. 인공지능분야에서 사용
    • LISP
      = 인공지능 분야에서 사용되는 언어

 " Ch.1 프로그래밍 언어 예상문제 정리 "

( 지극히, 내가 기억하고 싶은 내용 중심을 참고하길 바란다. )

  • 객체지향 프로그래밍 언어 구성요소 객체, 클래스, 메시지가 무엇인지 간단하게 서술하시오.

    [ 정답 ]
    A. 객체 : 속성과 이를 처리하기 위한 메소드를 결합한 소프트웨어 모듈
    B. 클래스 : 객체의 집합
    C. 메시지 : 객체들 간에 상호작용을 위한 수단. 객체의 메소드를 일으키는 외부의 요구사항.

  • HTML 문서 안에 직접 프로그래밍 언어를 삽입하여 사용하는 것으로, 기계어로 컴파일 되지 않고 별도의 번역기가 소스를 분석하여 동작하게 하는 언어는 ?

    [ 정답 ]
    스크립트 언어 ( script Language )

  • 서버용 스크립트 언어의 하나로, Linux, Unix, Windows 운영체제에서 사용된다. C,Java와 언어의 문법과 유사해서 배우기가 쉽고, 웹페이지 제작에 많이 사용하는 이 프로그래밍 언어는 ?

    [ 정답 ]
    PHP ( Professional HyperText Preprocessor 

  • 순차적인 명령 수행을 기본으로 하는 언어로, 문제를 처리하기 위한 방법에 초점을 두고 코드를 작성하는 것은 ? 대표적으로 C,Java가 속해있다.

    [ 정답 ]
    명령형 언어

  • 선언형 언어는 알고리즘은 명시하지않고 목표만 명시한다. 이러한 선언형 언어의 종류를 3가지만 쓰시오.

    [ 정답 ]
    HTML , XML , LISP, PROLOG


728x90
반응형

이 정보처리기사 실기 정리는 지극히 시험에 합격하기 위해
나의 초점에서 생소하거나 기억해야 할 것 같은 내용 위주로 정리를 하였음을 지극히 강조한다
.

 

합격하자 !!


728x90
반응형
  • [ 장르 ] Queue
    [ Question ]

[#42583] 다리를 지나가는 트럭

모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.
programmers.co.kr
  • My Code
#include <string>
#include <vector>
#include <queue>

using namespace std;

int solution(int bridge_length, int weight, vector<int> truck_weights) {
    int answer = 0,cur_Weight = 0,truck_Count;
    queue<int> Crossed;		// 지나간 트럭
    queue<int> Passing;		// 다리위에 트럭
    vector<int> waitBridge;	// 다리위 대기중인 각 트럭당 대기시간

    truck_Count = truck_weights.size();	// 초기 트럭수 변수에 저장
    while(true)
    {
        answer++;		// 단계 카운트
        if(!waitBridge.empty())	// 다리위에 트럭이 있으면
            for(auto iter = waitBridge.begin(); iter != waitBridge.end(); iter++)
                *iter -= 1;		// 다리위에 트럭큐에 끝까지 대기시간 -1감소

        while((!waitBridge.empty()) && waitBridge.front() == 0)	// 다리위에 트럭이있고, 다리끝까지 왔다면 ( == 대기시간 다 됬다면 )
        {
            Crossed.push(Passing.front());		// 현재 다리위에 맨 앞에 트럭, 다리를 건넜음큐에 push 
            cur_Weight -= Passing.front();		// 현재 다리위에 중량무게 이제 나갈 트럭무게만큼 차감 업데이트
            Passing.pop();						// 이제서야 다리위에 맨 앞 트럭 pop
            waitBridge.erase(waitBridge.begin());	// 대기시간 벡터도 맨앞에요소 하나삭제
        }
        if(Crossed.size() == truck_Count)	// 초기의 다리건너기전 트럭수랑, 건넌 트럭수 큐의원소의 수가 같으면 탈출
            break;
        if((!truck_weights.empty()) && weight >= cur_Weight + truck_weights.front())	// 매 단계마다, 다리를 건너기 전 트럭이 존재하고, 현재 다리위에 있는 트럭의 무게의 합과 지금 들어갈
        {																				// 트럭의 무게를 합한 것이, 다리의 하중보다 작거나 같다면 
            Passing.push(truck_weights.front());	// 다리위에 트럭추가
            cur_Weight += truck_weights.front();	// 추가된 트럭 무게만큼 총 무게 증가
            truck_weights.erase(truck_weights.begin());	// 다리건너기전 트럭원소는 삭제
            waitBridge.push_back(bridge_length);	// 새로 대기시간 (다리길이만큼) 벡터에 맨뒤에 삽입
        }
    }
    return answer;
}

 

" 지금까지 푼 것중엔 처음 알고리즘 답게 푼 것 같다. "
" queue 와 vector containner를 잘 사용하고, 로직도 나름 괜찮다. "
" ( 물론 더 최고의 방법이 있을 수 있겠지만....... ) " 


[ CheckPoint ]

  • 문제를 풀다 마주친 첫번째 고민은, 다리위에 적재된 트럭마다 다리길이만큼 대기시간을 가지게되고, 각각 들어온 시점이 다를 수 있는데 이걸 어떻게 컨트롤 해야할까 ?
  • 두번째 고민은, 오류에서 발견 됬는데, 다리위에 있던 트럭을 다리를 끝까지 다와서 건너간트럭큐에 push하거나, 다리에 적재되기전에 기존의 트럭 vector에 트럭을 다리위에 적재할때  vector에 트럭이 존재하는지를 먼저 체크를하고 뭔가를 해서 잘못된
    IndexError를 피할 수 있다.


728x90
반응형
  • [ 장르 ] Stack / Queue
  • [ Question ]

[#42586] 기능개발

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.
programmers.co.kr
  • My Code
#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) {
    vector<int> answer;
    int CurFrontIndex = 0;	// 현재 제일 앞 우선순위 인덱스
    int releaseCount = 0;	// 현 시점 배포할 작업 수

    while(true)
    {
        while(progresses[CurFrontIndex] < 100)	// 현재 우선순위 인덱스 작업이 100% 될때까지
        {
            for(int i = CurFrontIndex ; i < progresses.size(); i++)	// 모든 작업, 스피드만큼 증가
                progresses[i] += speeds[i];
        }
        
        while(progresses[CurFrontIndex] >= 100 )	// 현재 우선순위 인덱스의 작업이 일단 100%끝난 시점에서 다음 작업으로 넘어가면서 다른 100%끝난 작업이 있는지 전진
        {
            releaseCount++;
            CurFrontIndex++;
            if(CurFrontIndex >= progresses.size())
                break;
        }
        if(releaseCount != 0)	// 한번 순회하면서 100% 완성된 작업 수 카운트를 정답 벡터에 push !
        {
            answer.push_back(releaseCount);
            releaseCount = 0;
        }
        if(CurFrontIndex >= progresses.size())	// 마지막 작업까지 끝나면 탈출
            break;
    }
    return answer;
}
  • Better Code
#include <string>
#include <vector>
#include <iostream>
using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) {
    vector<int> answer;

    int day;
    int max_day = 0;
    for (int i = 0; i < progresses.size(); ++i)		// 반복문 하나로 끝 
    {
        day = (99 - progresses[i]) / speeds[i] + 1;	// 매 작업마다 한 작업당 스피드로 나누면 몇일이 소요할 지 바로 나오겠지

        if (answer.empty() || max_day < day)
            answer.push_back(1);
        else
            ++answer.back();		// 이 부분이 포인트라 했다. ++answer.back() ..

        if (max_day < day)
            max_day = day;
    }

    return answer;
}

" 나는 정작 STACK을 잘 구현할려고 한 것인가 ? "


  • [ CheckPoint ]
  1.  이 문제의 작은 포인트는 작업이 100프로가 되면 작업을 중단하고 배포를 해야 한다는 것. 혹시 본인의 테스트 케이스가 대부분 맞는데 1,2개가 틀린다면 이 부분을 체크 해볼 것.
  2. 나의 로직은 맨 앞 작업부터 끝나기까지 맨 끝 작업까지 한번 씩 speed만큼 작업의 진도를 증가 시키는 것인데, 만약 기존 작업량이 모두 낮고
    (10% 미만 ) speed는 각각 전부 1일 경우, 나의 알고리즘은 작업시간이 오래걸릴 것이다.
  3. 좀 더 좋은 방법은 Better Code의  한 작업의 단계에서
    (99-현재작업의 량) / 작업의 speed + 1 = 남은 작업 일 수가 측정 됨을 생각하면 연산 한번의 이런 과정이 끝난다.
  4. 아직 ++answer.push_back(1)의 의미를 정확히 모르겠는데 이해를 해봐야 겠다. 혹시 먼저 의견을 줄 수 있다면 조언을 주길 바란다.


728x90
반응형
  • [ Question ]

[ Problem ] #42746 가장큰수

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
programmers.co.kr
  • Version 1 ( 정렬기준을 정확히 설계해놓지 않았을 경우, 볼 필요 X )
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

string solution(vector<int> numbers) {
    string answer = "";
    vector<int> Highest_digit;
    vector<int> priority;
    int tmpDigit,tmpNum;
    string str;
    for(int i = 0 ; i < numbers.size(); i++)
    {
        if(numbers[i] / 1000 != 0)
            Highest_digit.push_back(numbers[i] / 1000);
        else if(numbers[i] / 100 != 0)
            Highest_digit.push_back(numbers[i] / 100);
        else if(numbers[i] / 10 != 0)
            Highest_digit.push_back(numbers[i] / 10);
        else
            Highest_digit.push_back(numbers[i]);  
    }
    for(int i = 0 ; i < Highest_digit.size()-1; i++)
    {
        for(int j = 0 ; j < Highest_digit.size()-1 ; j++)
        {
            if(Highest_digit[j] < Highest_digit[j+1])
            {
                tmpDigit = Highest_digit[j];
                Highest_digit[j] = Highest_digit[j+1];
                Highest_digit[j+1] = tmpDigit;
                tmpNum = numbers[j];
                numbers[j] = numbers[j+1];
                numbers[j+1] = tmpNum;
            }
            else if( Highest_digit[j] == Highest_digit[j+1])
            {
                if(numbers[j] < numbers[j+1] && (numbers[j] / 1000 + numbers[j] / 100 % 10 + numbers[j] / 10 % 10 + numbers[j] % 10)  != (numbers[j+1] / 1000 + numbers[j+1] / 100 % 10 + numbers[j+1] / 10 % 10 + numbers[j+1] % 10) )
                {
                    tmpNum = numbers[j];
                    numbers[j] = numbers[j+1];
                    numbers[j+1] = tmpNum;
                }
            }
        }
    }
    for(int i = 0 ; i < numbers.size(); i++)
    {
        str = to_string(numbers[i]);
        answer += str;
    }
    return answer;
}
  • 반성하고 다시 짠 코드 ( 정렬 기준을 무엇으로 !! ) 
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

bool compare(string a,string b)
{
    return a + b > b + a;
}
string solution(vector<int> numbers) {
    string answer = "";
    vector<string> tmp;		// 숫자 벡터 요소들을 문자열로 바꾼 벡터

    for(int i = 0 ; i < numbers.size(); i++)
        tmp.push_back(to_string(numbers[i]));	// to_string()으로 숫자->문자열로
    sort(tmp.begin(),tmp.end(),compare);	// 정렬한다 ( 따로 정의한 compare()함수 기준으로 )
    for(auto i : tmp)	
        answer += i;	// 정답 문자열 변수에 정렬된 문자열벡터요소하나씩 붙이기
    if(answer[0] == '0')	// 모든 수가 "0" 일 경우
        return "0";
    return answer;
}

" 문제를 보고 !!정렬의 기준!! 을 어떻게 설정할지 고민하라. "


  • [ CheckPoint ]
  1.  to.string( 정수 ) 를 기억하자.
    = 정수를 문자열로 반환해주는 함수 ( #include <string> 필요 )
  2. C++반복문은 ( 일반적 반복문, iterator이용, auto방식 3가지 정도는 기억 )
  3. 나는 정렬의 기준을 깔끔하게 잡지 못하고, 숫자벡터의 요소들의 최고자리수를 먼저 구해서 정렬시키고, 최고자리수가 같은 경우 원래 숫자벡터끼리 모든 자리수를 구한 값이 같으면 그대로 두는 식....( 내가 설명하고도 뭔소린지 이해 못한다..) (생략)
  4.  결론적으로, 숫자벡터를->문자열벡터로 변환한 벡터가지고서 각 원소들끼리 반복하면서 앞뒤 숫자끼리만 바꿔보면서 더 큰 숫자가 만들어지면 Swap하는 식으로 정렬한 다음, 정답 벡터에 넣어주면 끝나는 문제였다.

[ 참고자료 ]


728x90
반응형
  • [ LEVEL 2 ] [ 스택 / 큐 ]
  • [ Qusetion ]

[ LEVEL 2 ] [ 스택/큐 ] 프린터

내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.
programmers.co.kr
  • My Code
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int solution(vector<int> priorities, int location) {
    int answer = 0,tmp,i,j;
    while(true)
    {
        for(i = 1; i < priorities.size(); i++)	// 첫번째 우선순위기준으로 그 다음인덱스부터 우선순위벡터 끝까지 조사
        {
            if(priorities[0] < priorities[i])	// 첫번째 우선수위보다 더 큰 우선순위있으면
            {
                tmp = priorities[0];	// 첫번째 우선순위 담아두고
                for(j = 0 ; j < priorities.size()-1 ; j++)	// 뒤에 원소를 하나씩 앞으로 댕김
                    priorities[j] = priorities[j+1];
                priorities[j] = tmp;	// 첫번째 우선순위는 벡터 맨 뒤에 위치
                break;
            }
        }
        if(priorities.size() == i)	// 첫 번째 우선순위가 가장 큰 우선순위일 때
        {
            answer++;	// 우선순위벡터에서 pop()개념으로 정답 우선순위 순번 1증가
            for(j = 0 ; j < priorities.size()-1 ; j++)	// q.pop()개념으로 뒤에 원소들 하나씩 댕김
                priorities[j] = priorities[j+1];
            priorities[j] = 0;	// pop()된 우선순위를 0 (의미없는 수)으로 지정
            if(location == 0)	// 중복된 수들이 있었을 때를 고려. 같은 수중에 내가 원한 우선순위를 체크
                break;
        }
        location--;	// 내가 원하는 우선순위 차례 조작
        if(location < 0)	// 맨뒤로 내가 원하는 우선순위가 벡터에 갔을때 
                location = priorities.size() - 1;	// 맨뒤 인덱스로 변경
    }
    return answer;
}
  • Best Code
#include <string>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

int solution(vector<int> priorities, int location) {
    queue<int> printer;                         //queue에 index 삽입.
    vector<int> sorted;                         //정렬된 결과 저장용
    for(int i=0; i<priorities.size(); i++) {
        printer.push(i);
    }
    while(!printer.empty()) {
        int now_index = printer.front();
        printer.pop();
        if(priorities[now_index] != *max_element(priorities.begin(),priorities.end())) {
            //아닌경우 push
            printer.push(now_index);
        } else {
            //맞는경우
            sorted.push_back(now_index);
            priorities[now_index] = 0;
        }
    }
    for(int i=0; i<sorted.size(); i++) {
        if(sorted[i] == location) return i+1;
    }
}

" C++의 큐(Queue) STL 사용에 익숙해지자 "


  • [ CheckPoint ]
  1.  우선 <queue> STL은 <algorithm> 헤더가 필요하다.
  2.  queue는 정렬이 따로 없다.
  3.  사용가능한 주 함수로는 다음이 있다.
  1.  문제에서 큐에서 최대값을 순회하면서 구하는 방법을 몰랐다.
  2.  *max_element OR *min_element ( 객체.begin() , 객체.endl() )
    를 기억하자.
  3. 함수는, 배열이나 벡터 큐 등등 (문자열도 됨) 에서 시작과 끝 사이에서 각각 최대값, 최소값을 반환한다.
    다만 값이 아닌 주소를 반환하기 때문에 함수앞에 참조연산자를 붙인다.


728x90
반응형

+ Recent posts