2013년 11월 23일 토요일

[C/C++] Reading. "Effective C++ by Scott Meyers, 2006"

This book is introduced by all the developers for C++,  as a required reading.

now I'm reading on half of this, and I say

"You Must have read before you want to build something real"

and I feel regretful to spending last time without reading this.

Still half, but I learned a lot. and this teaches me the concept of OOP with examples of codes. 

And now I'm REALLY recommend this book if you having a job or interesting to C++ programming.

what if you have skills, read first. and Keep on reading and reading.


2013년 10월 7일 월요일

[VI/VIM] 찾기 & 바꾸기 정리

vi에서 찾기 및 바꾸기를 정리합니다.
워낙 사용방법이 무궁무진하여, 개략적으로 정리했습니다.
KLDP의 스레드를 참조하였습니다. (https://kldp.org/node/74138)

1. 사용법
vi 화면에서 command mode ( ':' 입력 ) 으로 전환 후, 입력합니다.

2. 일반적인 형식
:[범위]s/[찾을문자열]/[바꿀문자열]/[옵션]
- 간단예시
 :%s/abc/efg/g : 문서 전체에서 abc를 efg로 치환



- 범위
  • 일반 형식 : "[시작라인],[끝라인]" , "[특수문자]"
  • 예제 
    • 1,25 : 1행부터 25행까지
      • :1,25s/a/b/g : 1행부터 25행까지 a를 b로 모두 치환
    • % : 문서 처음부터 마지막까지
      • :%s/a/c/g : 문서 전체에서 a를 c로 모두 치환
    • .,200 : 현재 커서 행부터 200행까지
      • :.,200s/a/d/g : 현재 커서 행부터 200행까지 a를 d로 모두 치환
    • .,$ : 현재 커서 행부터 문서 마지막 까지
      • :.,$s/a/e/g : 현재 커서 행부터 문서 마지막까지 a를 e로 모두 치환
    •  : [무입력] 현재 행만
      • :s/a/g/g : 현재 행만 a를 g로 모두 치환

- 찾을문자열, 바꿀문자열
  • 일반 형식 : [문자열], [특수문자][문자열]....
  • 예제
    • & : 특수문자. 찾을문자열을 대입한다.
      • char/_&_ : 'char'를 '_char_'로 치환
    • a/b : 일반문자열. a를 b로 치환한다.
    • [정규표현식] : 문자열에는 정규표현식이 가능하며, 이를 통해 다양한 응용이 가능하다.
    • \(ab\)\(cd\)\(ef\)/\3\1\2 : 각 문자열의 순서를 정렬한다. 예시의 경우 결과는 'efabcd'가 된다.
- 옵션
  • g : grep. 해당 조건에 만족하는 모든 행에 수행한다. g! 인 경우, 해당 조건에 만족하는 행을 제외한 모든 행에 수행한다.
  • c : choose(?). 바꿀 문자열마다 확인 및 취소를 선택할 수 있다.
  • ":help s_flags" 로 옵션 조회 가능.


정규표현식을 사용하면, 정말 무궁무진한 수식이 다 나오지만, 쓰이는 빈도는 그리 많지 않을 것 같습니다. 포스트 앞부분의 링크를 따라가 보시면, 정말 많은 표현이 가능하다는 것을 보실 수 있습니다.

2013년 9월 24일 화요일

[Eclipse] 단축키 모음

Ctrl + K : 다음 찾기(Find next)
Ctrl + Shift + K : 이전 찾기(Find previous)

Ctrl + L : 줄번호로 이동(Go to Line)

2013년 8월 14일 수요일

[Network Programming] 수신가능, 송신불가 상태

네트워크 단에서 규칙설정을 하지 않고서야,

서버프로그램이 수신데이터만 받고, 송신데이터는 전송하지 못하는 현상이 발생할 것이라 생각하지 못했다.

현상을 정리하면 다음과 같다.

- 메모리 점유율 95%의 Windows 서버 ( svchost.exe에 의한 버그인 것으로 추정 )
- 1개의 서버 프로그램
- 수백개의 외부클라이언트
- 클라이언트의 접속 및 송신데이터는 서버에서 정상처리
- 서버의 응답데이터는 로그 상 정상전송으로 기록
- 반면, 클라이언트는 응답데이터를 받지 못함. ( wireshark에서도 감지하지 못함 )


서버프로그램의 수정은 2주 전에 이루어졌고,

현상은  0시 기준으로 발생하여, 네트워크 야간작업에 실수가 있었을 것이라 예상하였으나

실제로는 서버프로그램의 문제로 밝혀졌다.

몇 개월 전 코드로부터 수정사항을 하나씩 적용하면서 현상 재발생을 기다렸으나,

신기하게도 최신 코드를 적용할 때 까지 현상이 재발생하지 않았다.

잠재적인 리스크가 남아있어 기분이 매우 불편하지만, 다른방법으로 데이터를 보완할 수 있으므로 좀 더 시간을 두고 지켜보아야겠다.
전체적인 검토가 제일 바람직하겠지만, 시간이 여의치 않다.


결론은, 
AP를 절대적으로 신뢰해서는 안된다는 것.
수신가능, 송신불가 상태를 네트워크만의 문제로 속단하여서는 안된다는 것.

2013년 8월 12일 월요일

Project Euler : Problem.1

Q.
10보다 작은 자연수 중에서 3 또는 5의 배수는 3, 5, 6, 9 이고, 이것을 모두 더하면 23입니다.
1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면 얼마일까요?

A.
3의 배수의 합과 5의 배수의 합에서 최소공배수의 합을 뺀다.
#include 

int main()
{
 int a = 3, b = 5, max = 1000;
 int sum3=0, sum5=0, cross=0;
 int i, j, k;
 for( i = 1; a * i < 1000; i ++ ) {
  sum3+=a*i;
 }
 for( j = 1; b * j < 1000; j ++ ) {
  sum5+=b*j;
 }
 for( k = 1; a * b * k < 1000; k ++ ) {
  cross+= a*b*k;
 }
 printf("%d\n", sum3+sum5-cross);
 return 0;
}
그냥 단순하게 하면 이처럼 해도 되지만, 1~n까지의 합을 다음과 같이 구하는 것이 조금 더 효율적이다.
단, 최소공배수인 15는 이미 알고있다고 가정한다.

 1~n까지 연속된 수의 합은 n * ( n+1 ) / 2 이므로, 각 배수의 합은 여기에 해당 값을 곱하면 된다.
#include 

int main()
{
  int Cnt3 = 0, Cnt5 = 0, Cnt15 = 0;
  int sum3 = 0, sum5 = 0, sum15 = 0;
  int max = 1000;

  Cnt3 = max / 3;
  Cnt5 = max / 5;
  Cnt15= max / 15;

  sum3 = ( Cnt3 * ( Cnt3 + 1 ) / 2 ) * 3;
  sum5 = ( Cnt5 * ( Cnt5 + 1 ) / 2 ) * 5;
  sum15 = ( Cnt15 * ( Cnt15 + 1 ) / 2 ) * 15;

  printf("%d\n", sum3 + sum5 - sum15);
  return 0;
}

위를 일반화 시키면 다음과 같다.
프로그램 실행 시, 해당하는 인자값을 받도록 수정하였다.
사용 : 실행파일 [인자1] [인자2] [제한값]

#include <stdio.h>

int getLCM(int left, int right);     // 최대공약수를 반환하는 함수
int getGCD(int left, int right);     // 최소공배수를 반환하는 함수
int getCntInRange(int num, int range); // 범위내 인자의 배수 갯수를 반환하는 함수
int getSumInRange(int num, int range); // 범위내 인자의 배수 합을 반환하는 함수

int main(int argc, char* argv[] )
{
  int paramCnt = argc;
  if( argc != 4 ) 
  { 
    printf("사용법 : [실행파일명] [첫번째수] [두번째수] [제한값]\n");
    return -1;
  }

  int lcm = 0;
  int left = atoi(argv[1]);          // 문자열 인수를 숫자로 변환
  int right = atoi(argv[2]);
  int max = atoi(argv[3]);

  lcm = getLCM( left, right );
  
  printf("%d\n", getSumInRange( left, max )
                  - getSumInRange( right, max )
                  - getSumInRange( lcm , max ) );
  return 0;
}

int getLCM(int left, int right)
{
  return left*right/getGCD(left,right);  // 두 인자의 곱에서 최대공약수로 나누면, 최소공배수가 나온다.
}

int getGCD(int left, int right)
{
  int temp = 0;                 // 유클리드 호제법에 의해 최대공약수를 구한다.
  while(right)
  {
    temp = left % right;
    left = right;
    right = temp;
  }
  return left;
}

int getSumInRange(int num, int range)
{
  int cnt = getCntInRange(num, range);
  return cnt * ( cnt + 1 ) / 2 * num;    // n까지의 자연수 합에 인자값을 곱하여, 범위 내 인자값의 배수 합을 구한다.
}

int getCntInRange(int num, int range)
{
  return range / num;
}