2015년 8월 18일 화요일

Delete Coment(주석 제거 프로그램).

간단한 주석을 제거하는 프로그램을 구현해 보았다.

프로그램 하다보면 '//' 같은 한줄 주석  '/*' 같은 여러줄 주석을 많이 사용한다.

이런 주석이 달린 파일을 받아서 주석을 제거한 파일을 만들어 보았다.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stddef.h>
#define IN 0 // in 일때는 주석안에 들어갔을때
#define OUT 1 // out 일때는 주석밖으로 나왔을때
typedef unsigned int UINT;
char* AllocateInput(FILE*fp, UINT size); // 파일에 있는 문자전체를 메모리로 복사하는 함수
void DeleteComent(char*arr, UINT size, char* newArr);// 주석을 제거하는 함수
int main() {
UINT size;
char* arr;
char* newArr = NULL;
FILE* fp;
fp = fopen("test.c", "r");
if (fp != NULL) {
fseek(fp, 0l, SEEK_END); // 파일의 마지막 을 가르키게 한다
size = (UINT)ftell(fp); //마지막을 가르키고있는 파일포인터를 size 로 받는다
rewind(fp); // 다시 파일포인터를 파일의 처음주소로 가르킨다. 
arr = AllocateInput(fp, size);  
newArr = (char*)calloc(size + 1, sizeof(char));
DeleteComent(arr, size, newArr);
fclose(fp);
free(arr);
fp = fopen("main_rmc.txt", "w");
fprintf(fp, "%s", newArr);
fclose(fp);
free(newArr);
}
return 0;
}
char* AllocateInput(FILE* fp, UINT size) { 
char* arr = NULL;
int i = 0;
arr = (char*)calloc(size + 1, sizeof(char)); // 동적 메모리 할당( main에서 받아온 size+1 만큼)
while (!feof(fp)) { //파일의 끝까지의 문자들을 만들어진 메모리에 저장
arr[i] = fgetc(fp);
i++;
}
return arr; // 메모리 주소 반환
}
void DeleteComent(char* arr, UINT size, char* newArr) {
int state = OUT;  // 처음 상태 는 OUT
char* p = arr; // 캐릭터 포인터 p 가 문자열이 저장된 배열의 첫번째를 가르킴
int i = 0;
while ((*p) != '\0') { //p가 널문자를 만날때까지 반복
if (*p == '/'&& *(p + 1) == '/') { // 한줄 주석을 만나면 IN 으로 상태를 바꿈
state = IN;  
while ((*p) != '\n') { //개행문자를 만날때까지 포인터가 간다.
p++;
}
state = OUT; // 개행문자를 만나면 다시 OUT으로 상태를 바꿈
}
else if (*p == '/' && *(p + 1) == '*') {  // 여러줄 주석을 만나면 IN 으로바꿈
state = IN;
}
else if (*p == '*'&&*(p + 1) == '/') { // 여러줄 주석의 끝을 만나면 OUT
state = OUT;
p = p + 2;  // 마지막 '*/' 를 복사하지않기 위해 포인터를 2만큼이동
}
if (state == OUT) {
newArr[i] = *p; // 새로운 배열에 p가 참조하는 값을 복사.
i++;
}
p++; // p 는 1씩증가.
}
}



실행 해보면 다음과 같이 주석이 제거된 파일을 볼 수 있다.


2015년 8월 7일 금요일

Divide and Conquer(분할 정복)


분할 정복이란 컴퓨터가 큰 데이터를 한번에 처리할 수 없기 때문에,  작은 단위로 나누어

데이터나 문제를 해결(정복) 하는 알고리즘이다. 일단 이론은 다음그림을 보면  

    이해가 쉽다. 






자그럼 다음 과 같이 배열이 있다.  과연 연속된 수들중 가장 큰 연속을 찾고

싶을 때 어떻게 할것인가 ?  


정답은 4 -1 3 2 4 -7 10 2 로 연속된 배열이가장 큰배열이다. 이것을 분할 정복을 통해

찾아보자. 우선 그림처럼 가장 작은단위 까지 분할 하고 그수들 중 큰 값을 가져와 서로

비교한다. 재귀 함수를 이용해 왼쪽 오른쪽 가운데  값들의 연속을 작은단위부터 가져와

비교하는 것이다.  위그림과 설명이 이해가 안 간다면 코드를 보자. (파란색 펜으로 그린 배

열은 MidMax 함수로 찾은 최대값)



 

C language 2048_game

2048 게임을 작성해보았다.

2048게임이란 같은숫자를 계속 더해나가서 2048 이라는 블럭이 나오면 승리하는게임이다.

2048을 만들기전에 화면에 숫자들이 가득차서 더이상 움직일 수 없다면 게임에 패배한다.

간단한 함수 몇개 만 소개하자.


먼저 입력을 받는 함수를 짜기 전에 enum 으로 왼쪽 오른쪽 위쪽 아래쪽을 초기화 선언

해준다.


먼저 키보드 방향키(→,←,↑,↓)를  입력 받는 함수다. 방향키는 합성 코드로 찾아보면

두개의 수를 입력을 받는다.

왼쪽(224,75) 오른쪽(224,77)  위쪽(224,72) 아래쪽 (224,80) 이렇게 입력이 들어온다

그러므로 처음 224 가 들어올때까지 키보드 입력을 받고 다음 입력은 각각 방향키 고유의

숫자들을 받아준다.


각각 의 리턴값을 모와서 각 방향에따라 다른 함수를 호출해주는 함수.


위 함수는 왼쪽을 눌렀을때 호출되는 함수이다.  인접한 벽돌이 서로 같은숫자일 때와

테두리(벽쪽)에 숫자를 옮길수 있는 공간이 있을때 숫자를 합쳐주고 옮겨주는 코드이다.


랜드함수를 이용해, 숫자가 없는 빈 공간에 1/4의 확률로 '4' 3/4확률로 2를 생성하는 함수

다음은 게임 실행 화면이다. 


이렇게 원하는 게임 칸수를 정하면 칸수*칸수 만큼의 게임판이 나온다



게임을 진행하면 스코어도 나온다. 



숫자들이 보드를 가득채우고 더이상 움직이지 못하면 게임을 패배한다.

코드를 다운해서 컴파일 해보자.



2015년 8월 3일 월요일

Baseball Game(베이스볼, 야구 게임)

어렸을때 하던 베이스볼 게임을 간단히 코딩해 보았다.

베이스볼 게임이란, 4자리 숫자가 있으면, 그  숫자와 자릿수를 같이 맞추는 게임이다.

만약 숫자만 맞고 자리가 다르다면 ball,  숫자와 자릿수가 같으면 strike 이다.

간단히 한번의 진행에 strike 와 ball 의 갯수만 보여주는 코드를 작성해 보았다.

 1. 배경지식

숫자와 자리가 같으면 strike 를 카운트

같은 숫자만 있다면 ball 을 카운트

둘다 아니면 아무것도 아님;

2. 처리과정

  1) 정답인 숫자 4개를 배열에 입력 받는다. (배열 answer)

  2) 도전해볼 4개의 숫자를 입력할 배열을 만들어 입력받는다. (배열 in) 

  3) 반복문을 돌린다(i,j)
     
   -answer[j]와 in[i]가 같고 i와 j가 같으면 strike 를 카운트

   -answer[j] 와 in[i]가 같지만 i != j 이면 ball을 카운트 

  4) 카운트 한값을 출력

  5) 종료.


위는 스트라이크 와 볼을 판단해 각각의 갯수를 늘려주는 코드 이다.


실행 하면 먼저 정답(answer)을 입력한다.


그다음 자신이 도전해볼 수(in)를 입력한다


결과 : 5와 4 는 숫자는 있지만 자리가 달라 ball 이고 9는 둘다 같기 때문에 strike

따라서 1strike 2ball 이 된다.


Classify Number(숫자 구분하기)

이 코드 내용은

갯수를 입력하고, 입력받은 갯수만큼 숫자를 입력한다.

그리고 입력받은 숫자들 중에 홀수, 짝수, 양수, 음수의 갯수가 몇개있는지 보여주는

간단한 알고리즘이다.


위와 같이 갯수를 입력한다.


갯수 만큼 원하는 숫자를 입력한다.


입력한 숫자들중에서 혹수, 짝수, 양수, 음수의 갯수를 출력한다.

1. 배경지식

음수, 양수, 짝수, 홀수를 찾는다.

먼저, 짝수는 x%2==0, 즉 2로 나눴을때 나머지가 0이면 짝수다. 하지만 0은 2로 나눠지지만

짝수가 아니므로  (x%2==0&&x!=0)이어야 한다.

다음, 홀수는 반대로 짝수를 구분하고나서 (x%2!=0) 이면 홀수임을 알 수 있다.

양수는 x>0 

음수는 x<0

2. 처리과정
   
  1) 배열을 만든다. (크기가 100인 배열으로 만들어 보자)

  2) 원하는 갯수만큼 배열에 입력을 받는다

  3) 반복문을 원소의 갯수만큼 돌면서 음수, 양수, 짝수, 홀수의 갯수를 각각 세준다.



위의 코드는 차례로 짝수, 홀수, 양수, 음수의 갯수를 세주는 함수다.


2015년 8월 2일 일요일

원하는 숫자의 갯수 구하기(count number)

이번 알고리즘은 자신이 원하는 숫자가 총 몇개나 들어갔는지 찾는 알고리즘이다.

예를들어, 1~200 까지중에 7이라는 숫자가 몇번들어갈까?

뒤에 자리수가 7인것을 197 까지 새면 20개 가 되는가?

아니다. 77, 177, 71 등 7이 두 개이상 들어 가거나 7이 10의 자리, 100의 자리등 어디든지

올 수 있기 때문이다. 이모든 경우의 수를따져 숫자 7이 어디에 들어가던지 그 총 갯수를

찾는 코드를 구현해 보았다.

1. 선행 지식

각자리수 마다 7을 찾는 방법을 알아야한다.

그래서 생각한 방법이. 각자리수를 10의 배수로 나누고 그나머지를 일의 자리로 만들어

그 값이 7이면 그 수의 7이 들어가는 갯수를 알수있다.

예를들어 , 1777이라는 숫자가있으면 10000으로 나눴을때 몫이 0 이고 나머지가 1777이다.

이때, 이값을 10000보다 한 자리 작은 자릿수 1000 으로 나누면  1000의자리가 1임을 안다.

동일한 방법으로 자릿수를 낮춰 1000으로 나눴을때 몫이 1이 되고 나머지는 777 이된다.

나머지 777을 다시 100 으로 나누면 100의자리가 7이라는 것을 알 수 있다.

나머지 자릿수 도 동일한 방법으로 연산하면 각자릿수에 7이 몇번 들어가는지 알 수 있다.

2. 처리과정

1) 값을 입력받는다.

2) 입력받은 값을 '1.선행과정'의 내용대로 원하는 숫자(7)를 찾는다.

3) 원하는 숫자(7)을 찾을때 마다 count 를 늘려준다.

밑의 코드는 처리과정을 코딩 해본 것이다.

코드를 실행 해보자.
위 와 같이 숫자 를 입력받는다. 77을 넣어보자.

그렇다면 답은 7 , 17, 27, 37, 47, 57, 67, 70, 71, 72, 73, 74, 75, 76, 77 까지 총 16개가 나와야한다. 



값이 정확하게 나온다.