Skip to main content

Posts

Showing posts from August, 2007

BookCover plugin test page

This post is for testing BookCover plugin . (( The previous test page has some comments from users.)) The 'Books Reading' section in the sidebar is also using this plugin. [ bookcover:1932394613] [bookcover:1932394613] [ bookcover:1590598385(Smart and Gets Things Done)] [bookcover:1590598385(Smart and Gets Things Done)] [ bookcover:1591841380(Wikinomics : How Mass Collaboration Changes Everything)] [bookcover:1591841380(Wikinomics : How Mass Collaboration Changes Everything)] [ bookcover:8995856408] [bookcover:8995856408] [ bookcover:8831793721] [bookcover:8831793721] [ bookcover:9788831793728] [bookcover:9788831793728]

C++ of the Day #42 - Use of std::bad_exception

이번 글은 Use of std::bad_exception 을 보고 작성하였습니다. 아래 프로그램의 실행 결과는 무엇일까요? void my_unexpected() { if (!uncaught_exception()) cerr << "my_unexpected() called\n"; throw; } void my_terminate() { cerr << "my_terminate() called\n"; } void func() { cerr << "func() called\n"; } void g() throw (int) { throw 1.0; // throws double } int main() { set_unexpected (my_unexpected); set_terminate (my_terminate); atexit (func); try { g(); } catch (int) { cerr << "caught int\n"; } catch (bad_exception& e) { cerr << "caught bad_exception\n"; } return 0; } 한 단계씩 살펴보도록 하겠습니다. 먼저 main() 함수의 처음 세 라인은 각각 unexpected, terminate 함수와 프로그램 종료시 호출될 함수를 등록하고 있습니다. 그리고 C++03에서 unexpected() 함수와 관련된 내용은 다음과 같습니다. exception-specification을 가진 함수에서 exception-specification에 리스트되어 있지 않은 예외를 던지면 호출된다. unexpected 함수안에서 exception-specification에 있는 예외를 던지면 해당 handler를 찾아 처리한다. unexpected 함수안에서 rethrow 하거나

C++ of the Day #41 - Maintaining const in Impl classes

이번 내용은 c.l.c.m.에 올라온 Maintaining const in Impl classes 라는 글에서 가지고 왔습니다. Pimpl Idiom 과 const correctness에 관한 글입니다. struct Foo { struct Impl { void A() const { }; // unreachable code! void A() { }; }; Foo() : pimpl_(new Impl) { }; void A() const { pimpl_->A(); }; void A() { pimpl_->A(); }; Impl* pimpl_; }; // ... Foo const foo; foo.A(); // will always call non-const Foo::Impl::A() 위의 코드에서 문제라고 얘기되고 있는 것은 foo가 Foo 클래스의 const instance인데 Impl의 A() const가 호출되지 않고 A()가 호출된다는 점입니다. 원인은 간단합니다. foo가 const instance라서 const가 되는 것은 Impl*이지 Impl이 아니기 때문입니다. Impl* const냐 Impl const*냐의 차이죠. ((const 관련 내용이 얼마전 시즈하님의 C 포인터, 확실히 알자(6) - 상수와 포인터 에도 올라왔었습니다.)) 무엇의 const인지 쉽게 알기 위해서는 const 키워드의 바로 앞에 무엇이 있는지 보면 됩니다. 예를 들어보죠. T const* -> T가 const T* const -> T*가 const std::auto_ptr<T const> -> T가 const std::auto_ptr<T> const -> std::auto_ptr<T>가 const boost::shared_ptr<T const> -> T가 const boost::shared_ptr<T> const -> b

1의 개수 세기 - 해답

벌써 어제 말한 내일이 되었는데 답을 주신 분이 아무도 없어서 좀 뻘쭘하네요. :-P 그리고 어제 문제에 O(1)이라고 적었는데 엄밀히 얘기하자면 O(log 10 n)이라고 적었어야 했네요. 죄송합니다. ... 문제를 잠시 생각해보면 1~n까지의 수들 중 1의 개수를 얻기 위해서는 해당 숫자 n의 각 자리의 1의 개수가 모두 몇개나 될지를 구해서 더하면 된다는 사실을 알 수 있습니다. 예를 들어 13이라는 수를 생각해 보면 1~13까지의 수에서 1의 자리에는 1이 모두 몇개나 되는지와 10의 자리에는 모두 몇개나 되는지를 구해 이 값을 더하면 됩니다. 먼저 1의 자리를 생각해 보면 1, 11의 두 개가 있으며 10의 자리의 경우, 10, 11, 12, 13의 네 개가 있습니다. 따라서 2+4=6이라는 값을 구할 수 있습니다. 이번엔 234라는 수에서 10의 자리를 예로 들어 살펴 보겠습니다. 1~234라는 수들 중 10의 자리에 1이 들어가는 수는 10, 11, ..., 19, 110, 111, ... 119, 210, 211, ..., 219들로 모두 30개가 있음을 알 수 있습니다. 이 규칙들을 보면 해당 자리수의 1의 개수를 구하는 공식을 만들 수 있습니다. 234의 10의 자리에 해당하는 1의 개수는 ((234/100)+1)*10이 됩니다. 여기서 +1은 해당 자리수의 수가 0이 아닌 경우에만 더해집니다. 예를 들어 204라면 ((204/100)+0)*10으로 30개가 아닌 20개가 됩니다. 이런 방식으로 234의 각 자리수의 1의 개수를 구하면 1의 자리에 해당하는 1의 개수는 ((234/10)+1)*1=24개가 되고 100의 자리에 해당하는 개수는 ((234/1000)+1)*100=100이 됩니다. 이들 세 수를 모두 합하면 24+30+100=154개가 됩니다. 한가지 추가로 생각해야 할 점은 제일 큰 자리의 수가 1인 경우 위의 공식이 아닌 다른 공식이 필요하다는 점입니다. 예를 들어 123에서 100의 자리에 해당하는 1의 개수는 ((123/1

1의 개수 세기

저도 간단한 알고리즘 문제 하나... :-) 어떤 수 n이 주어졌을때 1~n까지의 수를 쭈욱 썼을때 나오는 1의 개수를 구하는 문제입니다. 예를 들어 13이라는 수가 주어지면 1~13까지의 수 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13에서 1은 1, 10, 11, 12, 13에 나오며 그 개수는 6이 됩니다. 즉, f(13)=6. 원래 문제 는 f(n)=n이 되는 1이 아닌 가장 작은 수를 구하는 문제인데 이 문제의 경우에는 처음부터 쭈욱 세어나가면 되기 때문에 간단히 다음과 같이 구현을 하면 됩니다. ((한가지 주의할 점은 이전에 찾았던 n-1값을 사용하지 않고 다시 처음부터 n까지 값을 계산하면 시간이 너무 많이 걸린다는 점입니다. 위의 코드에서는 static 변수를 사용하여 이전 값에 계속 더해나가는 방법을 사용했습니다.)) #include int count1(int n) { static int cnt = 1; // not 0 because n starts from 2. see main. while (n > 0) { if ((n % 10) == 1) ++cnt; n /= 10; } return cnt; } int main() { using namespace std; int n = 2; while (count1(n) != n) ++n; cout << n << endl; } 좀 재미가 없죠? 그래서 이번 문제는 어떤 수 n에 대해서 f(n)을 O(1)시간에 구하는 알고리즘을 만드는 것입니다. 관심있으신 분들은 한번 풀어보세요. 제가 만든 코드는 내일 올려보겠습니다.

어떤 두 정수의 합이 주어진 숫자가 되는 경우가 있는가?

art.oriented에 올라온 어떤 두 정수의 합이 주어진 숫자가 되는 경우가 있는가? 라는 글의 트랙백입니다. 코드가 비교적 단순해서 코드만 보시면 어떤 방법인지 아실 수 있습니다. 실행 파일을 만들 수 있는 전체 코드입니다. (에러 체크같은건 없습니다. ;-) ) #include using namespace std; int main(int argc, char *argv[]) { int V[] = { 1, 4, 7, 9, 10 }; int N = sizeof(V) / sizeof(*V); int K = atoi(argv[1]); int* l = V; int* r = V + N - 1; while (l < r) { int sum = *l + *r; if (sum < K) ++l; else if (sum > K) --r; else break; // sum == K } if (l < r) cout << "found(" << *l << ", " << *r << ")\n"; else cout << "not found\n"; } 간단히 설명하면, 제일 작은 수와 제일 큰 수를 각각 left, right로 놓고 이 두 수의 합을 원하는 값과 비교합니다. 만약 두 수의 합이 원하는 값보다 작다면 left를 다음 작은 수로 설정합니다. 이와 반대로 원하는 값보다 크다면 right를 다음 큰 값으로 놓습니다. 같으면 원하는 숫자의 합이 발견된 것이므로 바로 종료합니다. 적어 보니 그냥 단순 searching인것 같은데... 맞나요? :-)