표준입력으로부터 문자열을 라인 단위로 입력 받기 위해서는,

C 표준 라이브러리 stdio.h 에 있는 함수 중,

fgets, gets 를 사용할 수 있는데,


fgets(buf, buf_size, stdin); 와 gets(buf); 의 차이는 무엇일까?

==> buf 에 new line character 를 붙이느냐 안 붙이느냐 차이다.

      fgets 로 받은 buf 에는 new line character 가 붙고,

      gets 로 받은 buf 에는 붙이지 않는다.


유사하게,

fputs(buf, stdout) 과 puts(buf) 의 차이는?

==> 둘 다 null character 를 만날 때가지 표준출력으로 출력하는데,

      fputs 는 마지막에 new line character 를 붙이지 않고,

      puts 는 마지막에 new line character 를 붙인다.



표준입/출력으로부터 라인 단위로 데이터를 처리해야 할 것이 있어서 잠시 찾아본 내용~

반응형

설정

트랙백

댓글

http://people.csail.mit.edu/bdean/6.046/dp/

위 링크의 Dynamic Programming 문제들 중,

남은 두 문제인 Edit Distance 와 Two-Person Traversal of a Sequence of Cities 에 대하여 정리해 본다.

( 12번 Bin Packing 은 굳이 할 필요가 없어 패스 )

이 두 문제는 도대체 해결방법이 떠오르지 않아, 인터넷의 풀이를 보고 말았다.

두 문제의 풀이를 보면서 일단 DP 문제라도,

문제를 Recursive 하는 푸는 방법을 떠 올리고,

거기서 DP 풀이를 찾는 것이 좋겠다는 생각이 들었다.



- Edit Distance

문제) String A, String B 가 있을 때, A -> B 로 바꾸는 최소한의 Operation 수를 구하는 문제이다.

        Operation 은 다음과 같은 3 가지가 있다.

        1. Insert a character, 2. Remove a character, 3. Change a character to another character.


이 문제는 아래 링크의 풀이를 참고하였다.

https://secweb.cs.odu.edu/~zeil/cs361/web/website/Lectures/styles/pages/editdistance.html

거기서 사용된  예를 가지고 문제를 쪼개는 방법을 설명해 본다.




- Two-Person Traversal of a Sequence of Cities

문제) 순서가 있는 N 개의 도시가 있다. (지리적으로 순서가 있다는 의미가 아니다. 방문할 수 있는 순서를 말한다. )

        그리고 각각의 도시는 모두 연결되어 있다.

        이 도시들을 두 집합으로 나누고 (연속된 도시일 필요는 없다.),

        두 사람 A, B 가 각각의 도시 집합을 방문한다고 할 때,

        A, B 의 이동거리의 합이 가장 짧은 경우는 얼마가 되는가?

        단, A, B 방문 시작점은 각 도시 집합의 첫 번째 도시이다.


처음엔 문제 자체를 이해를 못해서 한참 해멨다.

그 다음에는 문제를 어떻게 풀어야 하는지도 몰라서 한참 생각하다가,

결국 인터넷을 뒤졌는데, 이걸 깔끔하게 설명한 곳도 찾기가 힘들었다.

그리다가 아래 링크의 Grimbal 이란 사람의 리플을 보고 풀었다.

http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1311271494








반응형

설정

트랙백

댓글

- Counting Boolean Parenthesizations

문제) 5개의 심볼을 가지고 만든 Boolean Expression을 괄호로 묶어 Evaluation했을 때,

        결과가 true 가 되는 Case 의 갯수는 몇 개인가?

        심볼 = { true, false, and, or, xor }

        예를 들면, ' false and true xor true '가 true 가 되는 괄호 묶기 방법은 1가지 밖에 없다.




- Optimal Strategy for a Game

문제) N 개의 동전이 있다. (N은 항상 짝수)

        각 동전의 가치는 V(0)...V(N)이며, 이 동전들은 일렬로 놓여져 있다.

        두 사람이 일렬로 놓여져 있는 동전의 양쪽 끝 동전 중 하나를 가질 수 있다고 할 때,

        처음 시작하는 사람이 가능한 최대 금액은 얼마인가?


       상대방이 무엇을 선택하는지는 여기에서 문제가 아니다.

       모든 경우의 수에서 최대값을 찾는 문제인 것이다.

       처음엔 "상대방은?" 이라는 생각에 잠시 혼란스러웠었다.



두 문제 다, 나름 풀만한 문제였다.

근데, 이 두 문제 전에 있는 문제인 Edit Distance는 당췌 아이디어가 안 떠오르네...








반응형

설정

트랙백

댓글

1) Building Bridges

문제내용:

가운데로 강이 지나가는 2차원 지도가 있다. 강 북쪽과 남쪽으로 각각 N 개의 도시가 있다.

이 N 개의 도시를 A(1)...A(N), B(1)...B(N) 이라고 한다.

이 도시는 순서대로 위치해 있지는 않다. (즉 A(1) 옆에 A(2) 가 있는게 아니라는 말)

강 북쪽과 남쪽은 연결하는 다리를 건설하고자 하는데,

다리의 건설은 A(k) 와 B(k) 만 연결할 수 있다.

이 때, 가장 다리를 많이 놓을 수 있는 갯수는 몇 개 인가?


설명이 은근히 길다.

그림으로 그리고 싶지만, 잘 찾지도 못하겠고 그리기도 귀찮아서 패스.





- Balanced Partition

문제:

N 개의 정수를 가진 집합을 2개의 Subset S1, S2 로 나누었을 때, |Sum(S1) - Sum(S2)| 의 최소값을 구하라.


사실 이 문제는 내가 못 풀었다.

Subset 을 나누는 데, 단순히 한 Element 를 기준으로 좌/우로 나누는 건줄 알았다.

그래서 문제를 이해해서 제대로 못 풀었다.

그리고 해답을 얼핏 보고 아하.. 하고 다시 푼 문제.





반응형

설정

트랙백

댓글

- Longest Increasing Subsequence

임의의 순서로 나열된 집합 A 가 있을 때,

값이 증가하는 최장 길이 수열을 찾는 문제이다.

단, 수열은 인접해 있을 필요는 없고,

이러한 수열은 여러가지 종류가 있을 수 있다.


예를들어 아래와 같은 수열이 있을 경우

{ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }

LIS 는 0, 2, 6, 9, 13, 15 혹은 0, 4, 6, 9, 11, 15 이 되겠다.


처음에는 2차원 배열로 계산을 했었는데,

그다지 좋은 방법은 아니었다. 

메모리도 많이 쓰고 최장 길이는 찾을 수 있었으나, 실제 수열을 찾지는 못했기에...




- Box Stacking

임의의 N 개 타입의 박스가 있을 때, 박스를 가장 높이 쌓을 수 있는 경우와 그 높이를 구하는 문제이다.

박스의 갯수는 제한이 없다. 

단, 박스를 쌓기 위해서는 strictly larger 야 한다.

( 즉, 박스의 Width > Depth 라고 했을 때,

 아래박스.Width > 위박스.Width && 아래박스.Depth > 위박스.Depth 를 만족해야 한다. )



* Box Stacking 문제부터 STL을 사용 해 보았는데,

  Box Class 의 Sorting 이 조금 문제가 있었다.

  STL 의 sort() 를 이용하기 위해 operator < 오버로딩 하였는데,

  단순히 return (w > b.w && d > d.w); 를 하게 되면,

  원하는대로 정렬이 되지 않아, !((w < b.w) || (d < b.d)); 를 사용하였다.

  Box 처럼 크다, 작다, 크지도 작지도 않다, 같다..  이런식으로 구분되는 것에는 좀 주의해야 하겠다.





반응형

설정

트랙백

댓글

N 개 타입의 동전으로 어떠한 금액을 만드는 것과 관련된 문제이다.


여기서 몇 가지 문제를 생각할 수 있는데,


1. Frobenius coin problem

이 문제는 NP-hard 문제로, GCD(최대공약수)가 1인 N 개 타입의 동전으로 만들 수 없는,

가장 큰 수를 찾는 문제이다. 이 수를 Frobenius(프로베니우스) number 라 한다.

하지만 N이 1,2,3 일 때는 다항시간에 찾을 수 있는 공식이 나와있다.

더 자세

한 내용은 위키피디아 http://en.wikipedia.org/wiki/Coin_problem 참고.



2. N 개 타입의 동전으로 어떠한 금액을 만들 때, 가장 적은 수의 동전을 사용했을 때의 동전의 수.

(단 N >= 1 이고 N[1] = 1 )

요 문제는 Greedy 한 방법으로 풀어도 되지만, DP 방법으로 풀 수도 있다.




3. N 개 타입의 동전으로 어떠한 금액을 만들 때, 가능한 동전 조합의 경우의 수를 구하는 경우.

(단 N >= 1 이고 N[1] = 1 )

이 문제는 약간 어려웠던거 같다. 그냥 생각만으로는 잘 안되서,

아주 간단한 케이스를 가지고 종이에 적어가면서 확인했다.




조합의 수를 구하는 문제는 좀 헷갈리긴 했지만,

생각을 좀 해보고, 간단한 케이스를 확인해 보면서 찾을 수 있었다.

반응형

설정

트랙백

댓글

문제) N 개의 실수 A(1) ~ A(N)이 있을 때, 연속된 수 A(i) ... A(j)의 합이 최대가 되는 값을 구하라.


솔직히 Brute Force 방식으로 풀어도 O(N^3)의 복잡도를 가지므로,

NP-Complete 한 문제는 아니다.

하지만 D.P 연습으로 공부를 하는 거니깐.



D.P 문제 중에는 난이도가 낮은 문제가 아닐까?

반응형

설정

트랙백

댓글

- Knapsack Problem

Dynamic Programming을 공부하면서,

(정말 정말 너무나 쉬운) Fibonacci 수열의 값을 구하는 예를 제외하고,

가장 많이 이용되는 예가 아닐까?


열 마디 설명보다 그림이 이해하기 쉬우므로, 부담없이 인용할 수 있는 위키피디아 그림을 가져왔다.

File:Knapsack.svg
(저자: Dake, 출처: http://en.wikipedia.org/wiki/File:Knapsack.svg )


위 그림과 같이 15kg까지 담을 수 있는 배낭에

각각 Value와 Weight를 가진 N 종류 타입의 상자들을 담았을 때,

Max Value가 되는 값이 얼마인가? 를 구하는 문제이다.


Knapsack Problem에는 3가지 종류가 있다.

이 구분은 사용가능한 N 종류 타입의 아이템의 갯수에 따라 나뉜다.

(위 그림으로 치자면 상자의 각 타입의 상자가 몇 개씩 있느냐?)


1. 0-1 Knapsack Problem : N 개의 타입의 아이템이 1개씩 있음.

2. Bounded Knapsack Problem : N 개의 타입의 아이템이 x(임의의 갯수)개씩 있음.

3. Unbounded Knapsack Problem : N 개의 타입의 아이템의 갯수 제한이 없음.


기본적인 해결 아이디어는 동일하다.

하지만 종류에 따라 아이디어를 조금 간소화 시킬 수 있다.


3가지 방법에 대해 일반적으로 사용할 수 있는 Knapsack 소스는 다음과 같다.



결론

다시 한번봐도 어렵긴 마찬가지다.

여러가지 D.P 문제들을 보고 익숙해지길 바라는 수 밖에.



(추가사항)

Knapsack Problem 중에 아이템을 쪼갤수 있는 Case의 경우는,

Value/Weight 가 높은 순으로 Greedy 한 방법을 통해 해결할 수 있다.

반응형

설정

트랙백

댓글

Windows 에서 C/C++ 개발환경 설정을 위해 Eclipse CDT 를 선택하기로 하고 설치해서 사용하는데,

그냥은 잘 안된다. 그래서 이것저것 삽질한 내용을 남겨본다.

( Visual Express C++ 2010 은 회사에서 쓸 수 없고,

  Dev-C++ 은 개발중단된지 오래되어서 Eclipse + Cygwin 조합을 사용했다)


1. 필요한 프로그램 설치

Eclipse CDT - http://www.eclipse.org/downloads/ 에서 Eclipse IDE for C/C++ Developers 설치

                     eclipse 는 단순히 압축풀면 끝.

Cygwin - http://www.cygwin.com 에서 setup.exe 를 받아서 설치.

              필요한 패키지는 gcc-core, gcc-g++, make, gdb, binutils 정도?

              이것만 선택하면 추가로 필요한 패키지는 알아서 설치된다.


2. 전역 환경 설정

메뉴의 Window > Preferences 에서 설정가능하다.

반드시 필요한 설정은

- C/C++ > Build > Build Variables 에서 Show system variables 를 선택하여

PATH 에서 c:\cygwin\bin 을 제일 위로 바꿀것.

(이걸 안하면 빌드시 에러가 나는 경우가 있는 듯 하다)

- C/C++ > Debug > Source Lookup Path 에서 'Add' 하여 'Path Mapping' 선택

왼쪽엔 \cygdrive\d 오른쪽엔 D:\ 라고 적고 추가한다.

(소스가 저장되는 드라이브에 따라 d 를 c 나 다른 문자로 바꾸면 된다.

 이걸 하지 않으면 Debug 시에 소스가 보이지 않는다. 또한 gcc 실행시에도 문제가 생기는 듯.. )

- tab 대신 space 를 사용하려면 tab, formatter 검색해서 설정 필요.

- 파일 인코딩 관련해서 설정하려면 encoding 검색해서 설정하면 된다.


3. 프로젝트 생성

여러가지 프로젝트 타입이 있던데, 보통은 C or C++ Project  > Makefile project 로 선택하면 무난 할 듯.

Toolchins 는 Cygwin GCC 를 선택해야 겠지.


4. 프로젝트 설정

실제 사용을 위해서는 몇 가지 셋팅이 더 필요했는데...

먼저 메뉴의 Project > Properties 로 들어간다.

- Makefile 을 자동 생성하게 하려면 C/C++ Build 에서 'Generate Makefiles automatically' 를 체크하자.

  (이걸 체크 하지 않고 직접 makefile 을 작성해도 될 거 같은데... 실제로 아직 해보질 않아서 패스..)

- C/C++ > Environment 에서 PATH 를 보면 c:\cygwin\usr\bin 이 제일 앞에 있다면 삭제해 버리거나

   c:\cygwin\bin 으로 바꾸어 주자.

  (이걸 안하면 make 에서 에러가 발생하는데... 역시 이유는 잘 모르겠다)



p.s

음.. 일단 이렇게 하면 문제는 없지만,

Segmentation fault 에러 났을 때, GDB 가 출력하는 메시지를 제대로 파싱을 못하는 지,

제대로 디버깅이 안된다. 후우... 아직 해결방법을 못 찾았다..



반응형

설정

트랙백

댓글