본문 바로가기

대학교시절

대학교 C언어 과제 모음

1. 최대공약수와 최소공배수

 

 
/* 
문서이름 : Hw2-1
프로그램 작성자 : americano@korea.ac.kr
프로그램 작성일 : 2011년 10월 17일
프로그램 주제 : 두개의 정수를 입력받아 최대 공약수(GCD)와 최소 공배수(LCM)를 구하기
구현방법:

#최대공약수 구하는 방법
유클리드의 호제법 알고리즘을 이용하였습니다.
두 입력 값 중 큰 값과 작은 값을 구분하여 M과 N으로 지정하였습니다.
재귀 함수를 이용하여
M을 N으로 나눈 나머지가 0이 될 때 까지 N이 가진 값을 M에 지정하고 그 나머지 값을 N에 지정하여 다시 M을 N으로 나누었습니다. 
그리고 나머지가 0이 되면 최대공약수는 M이므로 재귀함수를 종료하였습니다.
유클리드 호제법:
1단계 : 두 입력 값 중 큰 값을 M, 작은 값을 N에 지정한다.
2단계 : M을 N으로 나누고 그 나머지를 R이라고 부른다.
3단계 : R이 0이 아닐 경우, N이 가진 값을 M에 지정하고 R의 값은 N에 지정한 다음 2단계로 돌아간다.
		R이 0일 경우, 현재 N에 지정된 값이 최대공약수이다.

#최소공배수 구하는 방법
입력받은 두 값을 곱한 후 최대공약수로 나누어 최소공배수를 구하였습니다.
*/

#include <stdio.h>
int GetGCD(int M, int N); //최대공약수 함수
int GetLCM(int M, int N, int GCD); // 최소 공배수 함수
int main()
{
	int a, b; // 값을 입력받은 변수
	int GCD, LCM;
	printf("2개의 정수 입력: ");
	scanf("%d %d", &a, &b);

	/*최대 공약수 구하기 */
	if(a>b) // 유클리드 호제법 1단계 실행
		GCD = GetGCD(a,b); // GetGCD 함수를 통해 유클리드 호제법 2,3 단계 실행
	else
		GCD = GetGCD(b,a);
	printf("G C D : %d\n", GCD); // 최대공약수 출력

	/*최소 공배수 구하기*/
	LCM = GetLCM(a,b, GCD);
	printf("L C M : %d\n", LCM); // 최소 공배수 출력
	return 0;
}

int GetGCD(int M, int N)
{
	if((M%N)==0) // 나머지가 0 일 경우 N이 최대공약수이다.
		return N;
	else
		return GetGCD(N, M%N); // 나머지가 0이 아닐 경우N이 가진 값을 M에 지정하고 R의 값은 N에 지정한 다음 2단계로 돌아간다.
}

int GetLCM(int M, int N, int GCD)
{
	return M*N/GCD; // 두 값을 곱한 후 최대공약수로 나눈다.
}


 

2. 시분초 변환

 

/*
프로그램 작성자 : americano@korea.ac.kr
프로그램 작성일 : 2011년 10월 18일
프로그램 주제 : 이용자로부터 초(second)를 입력받는다. 이를 [시,분,초]의 형태로 출력하는 프로그램을 작성해보자.
구현방법:
Hour(시)는 입력받은 초 값으로부터 3600을 나누어준 몫이고
Minte(분)은 입력받은 초 값으로부터 3600을 나눈 나머지에 다시 60으로 나누어준 몫이고
Second(초)는 입력받은 초 값으로부터 3600과 나눈 나머지에 다시 60을 나눈 나머지로 값으로 입력시켰습니다.
*/
#include<stdio.h>

int Hour (int sec);   // 시를 구하는 함수
int Minute(int sec);  // 분을 구하는 함수
int Second(int sec);  // 초를 구하는 함수

int main()
{
	int hour = 0, minute = 0, second = 0; // 기본은 0으로 초기화
	printf("초(second) 입력 : "); // 초 입력
	scanf("%d",&second);
	hour = Hour(second);      //시 - 함수실행
	minute = Minute(second);  //분 - 함수실행
	second = Second(second);  //초 - 함수실행
	printf("[h:%d, m:%d, s:%d]\n",hour, minute, second); // 결과값 출력
	return 0;
}

int Hour (int sec)
{
	return sec/3600; // Hour(시)는 입력받은 초 값으로부터 3600을 나누어준 몫
}
int Minute(int sec)
{	
	return (sec%3600)/60; //입력받은 초 값으로부터 3600을 나눈 나머지에 다시 60으로 나누어준 몫
}
int Second(int sec)
{
	return sec%3600%60; // 입력받은 초 값으로부터 3600과 나눈 나머지에 다시 60을 나눈 나머지
}

 

 

3. 경우의 수 조사

 

/* 
문서이름 : Hw2-2
프로그램 작성자 : americano@korea.ac.kr
프로그램 작성일 : 2011년 10월 17일
프로그램 주제 : 금액 5000원 이상을 입력받아 비디오(1500원)을 한편 빌리고 남은 돈으로 남는 돈 없이 크림빵(500원), 새우깡(700원), 콜라(400원), 커피(100원)을 살수있는 경우의 수를 조사한다.
구현방법:
먼저 금액을 입력받고 그 금액에서 비디오를 빌린 금액 1500원을 빼 주었습니다.
물건을 구입한 후 남는 잔액을 통하여 크림빵, 새우깡, 콜라, 커피를 뒤에서부터 증가시키며 값을 늘려나갔습니다.
while문을 4번 중첩시켰고 뒤에서부터 증가시키기 위해 바깥쪽에서 안쪽으로 크림빵, 새우깡, 콜라, 커피 순으로 중첩시켰습니다.
첫번째 루프는 먼저 while문 실행 시 제일 안쪽에 있는 커피의 while문까지 들어와 커피로 최대한 살 수 있는 만큼의 개수를 구하였고
두번쨰 루프는 다시 커피를 초기화 시키고 그 한단계 바깥쪽에 있는 콜라를 한 개 씩 증가시키고 다시 안 쪽의 while문으로 돌아와 남는 잔액으로 커피를 최대한 살 수 있는 개수를 구하였습니다.
세번째 루프는 다시 커피를 초기화 시키고 콜라 한잔을 더 증가시키며 다시 개수를 구하였고
이런 방식으로 while문을 바깥으로 한층 한층 나가면서 그 층의 간식거리 개수를 하나씩 증가시키고
다시 안쪽으로 돌어오며 다시 while문을 실행시켰습니다. 

이런식으로 while문을 이용하였고 while문은 잔액이 0이상일 때만 루프를 돌게 하였습니다.
또한 출력은 모든 간식거리가 한가지 이상은 구입했을 때만 출력을 하도록 했습니다.
*/

#include<stdio.h>

void print(int a,int b, int c,int d); // 출력함수

int main()
{
	int bread = 0, snack = 0, coke = 0, coffee = 0; // 각 군것질거리의 개수를 나타낼 변수
	int money, balance; // 입력받을 금액과 잔액
	
	printf("비디오를 빌리기 전 금액을 입력하시오 : ");
	scanf("%d",&money);
	money -= 1500; // 비디오를 빌려보고 남은 금액
	printf("현재 당신이 소유하고 있는 금액 : %d\n",money);
	balance = money; // 아직은 비디오만 빌린 상태
	while(balance >=0) // while문은 남은 돈으로 크림빵을 최대한 많이 살 수 있을때까지 루프를 돌게 된다 
	{
		while(balance >0)  // while문은 남은 돈으로 새우깡을 최대한 많이 살 수 있을때까지 루프를 돌게 된다
		{
			while(balance >0)  // while문은 돈으로 콜라를 최대한 많이 살 수 있을때까지 루프를 돌게 된다 
			{
				while(balance >0)  // while문은 돈으로 커피를 최대한 많이 살 수 있을때까지 루프를 돌게 된다 
				{
					coffee++;
					balance = balance - 100; // 커피 한잔 더 구매
				}
				if(balance>=0&&bread>0&&snack>0&&coke>0&&coffee>0) // 출력은 모든 품목을 히니이상 구입했을 때만
					print(bread, snack, coke, coffee); // 프린트 함수 
				balance = money-snack*700-bread*500; // 잔액은 처음 돈에서 과자와 빵을 구매하고 남은 돈으로 입력
				coke++; // 콜라 한병 더 구매
				coffee=0;
				balance = balance - coke*400; 
			}
			if(balance>=0&&bread>0&&snack>0&&coke>0&&coffee>0) // 출력은 모든 품목을 하나이상 구입했을 때만
				print(bread, snack, coke, coffee);
			balance = money-bread*500; // 잔액은 처음돈에서 빵을 구매하고 남은 돈으로 입력
			snack++; // 새우깡 한봉 지 더 구매
			coffee = 0;
			coke = 0;
			balance = balance - snack*700; 
		}
		if(balance>=0&&bread>0&&snack>0&&coke>0&&coffee>0) // 출력은 모든 품목을 하나이상 구입했을 때만
			print(bread, snack, coke, coffee);
		balance = money; // 초기화
		bread++; // 크림빵 한 개 더 구매
		coffee = 0;
		coke = 0;
		snack = 0;
		balance = balance - bread*500; 
	}
	printf("어떻게 구입하시겠습니까?\n");

}
void print(int a,int b,int c,int d)
{
	printf("크림빵(%d개), 새우깡(%d봉지), 콜라(%d병), 커피(%d잔)\n",a,b,c,d);
}

 

 

4. 2^k <= n 을 만족하는 k구하기

 

/*프로그램 작성자 : americano@korea.ac.kr
프로그램 작성일 : 2011년 10월 18일
프로그램 주제 : 사용자로부터 숫자 n을 입력받는다. 그리고 나서 다음 공식이 성립하는 최대 k 값을 계산해서 출력하는 프로그램을 작성해 본다.
2^k <= n
구현방법:
상수 k의 최대값을 구해주는 함수를 선언하였습니다. 그 함수를 재귀호출하는 방식으로 해결했습니다.
그 함수는 입력한 값을 2로 나눈 몫이 1이 나올 때 까지 재귀호출하여 입력받은 값을 2로 계속 나누었고
나눌때마다 k값을 1씩 증가시켜서 k의 최대값을 구하였습니다.
*/

#include<stdio.h>

int GetNum(int Value, int Number); // 상수 k값을 구해주는 함수

int main()
{
	int Val=0, Num=0; // n과 k의 변수 0 으로 초기화
	printf("상수 n 입력 : ");
	scanf("%d", &Val);
	Num = GetNum(Val, Num); // 함수 호출
	printf("공식을 만족하는 k : %d\n",Num);
	return 0;
}

int GetNum(int Value,int Number)
{
	if(Value==1) // 2로 나눈 몫이 1일 때 Number을 리턴한다.
		return Number;
	else	
		return GetNum(Value/2, ++Number); // 몫이 1일 때 까지 재귀함수를 호출한다.
		// 입력받은 값을 2로 나누고 구하려는 값을 1씩 증가시킨다.
}

 

 

5. 가우스 조던 소거법

 

/*
프로그램 작성자 : americano@korea.ac.kr

Gauss-Jordan elimination 구현

프로그램 설명: 
1) 가우스 조던 소거법을 이용하여 연립방정식의 근을 구하는 프로그램입니다.
2) n by n 행렬을 만들고 n의 범위는 (2<= n && 10>=n ) 의 조건을 가집니다.

구현 설명:
1) 이차배열 matrix[10][11]을 선언 후 값을 입력합니다.
2) 이 프로그램의 모든 함수의 아규먼트는 행렬의 범위 n과 이차배열의 포인터 (*matrix)[11] 입니다.
3) 이 프로그램의 함수는 총 4개로 이루어져 있습니다. 
 - JordanElimination : 조던 소거법을 실행합니다.
 - GaussElimination : 가우스 소거법을 실행합니다.
 - InputMatrix : 행렬의 값들을 입력합니다.
 - PrintMatrix : 행렬의 연산 결과를 출력합니다.
4) main 함수에서 n의 값을 범위 내에 입력하지 못할 시 무한 루프를 실행합니다.
5) 해가 무수히 많거나 해가 없을 경우 해가 없음을 보여주고 프로그램은 종료됩니다.
6) 가우싀 조던의 세가지 연산이 모두 포함됩니다.
 - 두 개 방정식(행) Ri와 Rj를 교환한다(Ri <-> Rj)
 - 방정식 Ri에 0이 아닌 수 a를 곱한다.(a * Ri)
 - 방정식 Ri에 0이 아닌 수 a를 곱하고, 그 결과를 다른 방정식 Rj에 더한다. (a*Ri+Rj)
7) 각 함수의 설명은 함수 위의 주석으로 설명하겠습니다.

구현날짜: 2011년 10월 31일(월요일)

제출일자: 2011년 11월  2일(수요일)
*/

#include <stdio.h>
#include <stdlib.h>

/* function prototype */
void JordanElimination(int n, double (*matrix)[11]);
void GaussElimination(int n, double (*matrix)[11]);
void InputMatrix(int n, double (*matrix)[11]);
void PrintMatrix(int n, double (*matrix)[11]);

/*main*/
int main()
{
	double matrix[10][11]; // double형 이차원 배열 선언
	int n;  
	int i=0;

	do //n 의 값을 2부터 10까지 구현받기 위해 while문을 선언함, 범위 밖 입력 시 무한 루프 실행
	{	
		printf("Matrix size : ");
		scanf("%d",&n);
		if(n>10||n<2)
			printf("2이상 10이하의 수를 입력하십시오\n");
	}while(n>10||n<2);
		
	

	InputMatrix(n, matrix); // 행렬의 값을 입력합니다
	GaussElimination(n, matrix); // 가우스 소거법을 실행합니다.
	JordanElimination(n, matrix); // 조던 소거법을 실행합니다.
	PrintMatrix(n, matrix); // 연산 결과를 출력합니다.

	return 0;
}


/* 가우스 소거법 함수
만약 matrix[a][a] (0<=a<n)행렬요소 중에 0 이 있거나 연산 중 0이 생겼을 경우
 - 두 개 방정식(행) Ri와 Rj를 교환한다(Ri <-> Rj)
의 연산을 통해 그 다음 행과 값을 교환합니다. 이는 요소가 0이 나타나지 않을 때 까지 반복됩니다.
모든 행과의 교환 후에도 모든 요소가 0일 시 프로그램은 종료됩니다.

*/
void GaussElimination(int n, double (*matrix)[11])
{
	int i, j, x;
	
	for(i=0; i<n; i++)
	{
		double temp = matrix[i][i]; // i행의 모든 원소를 i행i열 원소로 나누어 주기 위해 값을 입력 받습니다.
									// 또는 이 값이 0 일 경우 값을 교환하기 위한 용도로 사용합니다.
		double temp2; // 만약 i행 i열 원소가 0이 생길 시 i행을 그 다음 행과 바꾸기 위해 사용할 임시 변수입니다.
		int z = 1; // temp 값의 입력이 0을 방지하기 위해 사용할 check용 변수, 처음 초기 검사를 위해 1로 초기화합니다
		while(temp==0&&z!=0) // matrix[a][a] (0<=a<n) 행렬요소가 0일 경우 문제가 생겨 그 다음 행과 교환합니다.
		{
			if(matrix[n-1][n-1] == 0 || z+i==n) // 모든  matrix[a][a]이 계속 0 이거나 루프가 범위를 초과 경우
			{	
				printf("해가 없습니다\n");
				exit(0); // 프로그램 종료
			}
			for(j=0; j<n+1; j++) // 그 다음 행과 값들을 교환
			{
				double temp = matrix[i][j];
				matrix[i][j] = matrix[i+z][j];
				matrix[i+z][j] = temp;
			}
			temp = matrix[i][i]; // 다시 matrix[a][a]가 0이 아닌지 확인하기 위해 
			if(temp!=0) // 0이 아닐 경우 check 변수 z를 0으로 만들어서 while문 탈출
				z = 0;
			else if(temp==0) //0일 경우 그 다음 행과 다시 교환하기 위해 z값을 1 추가
				z++;
		}


		for(j=0; j<n+1; j++)
		{
			matrix[i][j] = matrix[i][j]/temp; //i행의 모든 원소들을 i행i열의 원소의 값으로 나누어서 i행i열을 1로 만들어 줍니다.	
		}
		if(i<n-1)	// 미리 그 다음 행을 지금 계산한 루프와 값과 계산합니다 아래 주석에 있는 연산을 합니다.
		{			// 방정식 Ri에 0이 아닌 수 a를 곱하고, 그 결과를 다른 방정식 Rj에 더한다. (a*Ri+Rj)
			for(x=1; x<n; x++)
			{	
				temp2 = matrix[i+x][i];
				for(j=0; j< n+1; j++)
				{
					matrix[i+x][j] -=(temp2*matrix[i][j]);
				}
			}
		}
	}
}

/*  조던 소거법 함수
n by n 행렬의 마지막을 행을 제외한 행렬의 가장 오른쪽 열부터 모든 행을 모두 0으로 만들어 줍니다.
이 0으로 만들어주는 작업을 왼쪽 열로 한칸 씩 와서 같은 작업을 반복합니다. 단 제거의 제외는 마지막 행의 그 위 행까지 늘어납니다.
이 작업에서 연립방정식의 해를 담고 있는 오른 쪽 열(n)을 위 작업의 0으로 만들어주면서 빼주는 값을 같이 빼줍니다. 
*/
void JordanElimination(int n, double (*matrix)[11])
{
	int i, j; // for루프를 위한 변수
	for(i=n-1; i>0; i--) // 마지막 열부터 왼쪽으로 옵니다.
	{
		double temp = matrix[i][n]; // 연립방정식의 해을 담고 있는 열을 임시 저장합니다.
		for(j=0; j<i; j++) // 행은 가장 위에 있는 행부터 시작합니다. 
		{
			double temp2;
			temp2 = matrix[j][i];
			matrix[j][i] = 0; // 지금 있는 열의 값을 0으로 만들어줍니다.
			matrix[j][n] = matrix[j][n]-temp*temp2; // 0으로 만들면서 빼준 값을 해를 담고 있는 열에 함께 빼줍니다.
		}
	}
}
/* 입력 함수
n by n 행렬을 만든 후
이 행렬의 원소 값을 입력해줍니다.
*/


void InputMatrix(int n, double (*matrix)[11])
{
	int i, j;
	printf("input elements : \n");
	for(i=0; i<n; i++)
	{
		for(j=0; j<n+1; j++)
		{
			int x;
			scanf("%d",&x);
			matrix[i][j] = x;
		}
	}
}

/* 출력함수
계산결과를 출력합니다.
계산결과를 double 형으로 계산 했기 때문에 미세한 오차가 생길 수 있어서
단위행렬의 출력은 int형으로 출력합니다.
그리고 연립방정식의 해를 담고 있는 열은 소수점 6자리 까지 출력합니다.
*/
void PrintMatrix(int n, double (*matrix)[11]) 
{
	int i, j; // for루프를 위한 원소
	printf("output result : \n");
	for(i=0; i<n; i++)
	{
		for(j=0; j<n; j++)
		{
			printf("%d ",(int)matrix[i][j]); // int형으로 출력합니다.
		}
		printf("%.6g ",matrix[i][n]); // 소수점 6자리 까지 출력합니다.
		printf("\n");
	}
}


 

 

6. 행렬 회전

 

/*
프로그램 작성자 : americano@korea.ac.kr

작성일자: 11년 11월 20일

프로그램 내용:
5 * 5 행렬에 순서대로 1부터 25까지 입력되어 있는 행렬이 있습니다.

 1  2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

이 행렬을 우회전 혹은 좌회전 시키는 프로그램입니다.

입력받는 방법을 양수, 0, 음수 이렇게 세가지로 정하여
양수일 경우 우회전, 0일 경우 종료, 음수일경우 좌회전을 실행합니다.
입력받은 값의 절대값만큼 회전합니다.

구현방법:
1. 위와같이 값이 입력된 2차원 배열을 만듭니다.
2. 현재 배열의 모습을 출력합니다.
3. 회전수를 입력받습니다.
4. 만약 입력받은 값이 양수일경우 회전을 우회전시킵니다. 
회전방법은 우선 원본배열의 사본을 하나 만든 후 이중으로 for 루프를 반복시켜
ary[i][j] = ary[4-j][i] 이런식으로 수정합니다.
5. 좌회전은 ary[i][j] = ary[4-j][i]으로 수정합니다.
6. 무한루프를 통하여 2번으로 돌아가 입력받는 값이 0 이 될 때까지 무한루프 시킵니다.
*/

#include<stdio.h>

void rightSpin(int (*ary)[5], int num); // 입력받은 수만큼 우측으로 회전시키는 함수
void leftSpin(int (*ary)[5], int num);	// 입력받은 수만큼 좌측으로 회전시키는 함수
void print(int (*ary)[5]);				// 2차원배열을 출력하는 함수

int main()
{
	int matrix[5][5]; 
	int spinNum = 1; // 배열의 회전수를 가리키는 변수
	int i, j;
	for(i=0; i<5; i++)
		for(j=0; j<5; j++)
			matrix[i][j] = spinNum++; //spinNum은 배열의 회전수를 가리키는 변수이나 공간 절약을 위해 spinNum을 배열 입력을 위해서도 씀 

	while(1) // 0을 입력하기 전까지 무한루프
	{
		print(matrix); // 2차원배열을 화면으로 출력
		printf("어느쪽으로 얼만큼 회전시키시겠습니까?\n");
		printf("음수 : 좌측방향 // 양수 : 우측방향 // 0 : 종료 : ");
		scanf("%d", &spinNum);
		if(spinNum==0) // 0을 입력시 종료
			break;
		else if(spinNum > 0) // 0보다 큰 값 입력시 우측회전 함수 실행
			rightSpin(matrix, spinNum);
		else				// 0보다 작은 값 입력시 좌측회전 함수 실행
			leftSpin(matrix, spinNum);
	}
}
//우측회전함수
void rightSpin(int (*ary)[5], int num)
{
	int i,j;
	int ary2[5][5]; //하나의 사본배열을 만듬
	while(num>0) // 값을 입력한 만큼 회전실행
	{
		for (i=0; i<5; i++) 
			for(j=0; j<5; j++)
				ary2[i][j] = ary[i][j]; // 원본배열을 사본배열에 복사
		for(i = 0; i < 5; i++)
			for(j=0; j < 5; j++)
				ary[i][j] = ary2[4-j][i]; //회전실행
		num--;
	}
}
//좌측회전함수
void leftSpin(int (*ary)[5], int num)
{
	int i,j;
	int ary2[5][5]; //하나의 사본배열을 만듬
	while(num<0) // 값을 입력한 만큼 회전실행
	{
		for (i=0; i<5; i++)
			for(j=0; j<5; j++)
				ary2[i][j] = ary[i][j]; // 원본배열을 사본배열에 복사
		for(i = 0; i < 5; i++)
			for(j=0; j < 5; j++)
				ary[i][j] = ary2[j][4-i]; //회전실행
		num++;
	}
}

void print(int (*ary)[5])
{
	int i, j;
	printf("\n"); // 보기좋게 한줄 표시
	for(i=0; i<5; i++)
	{
		for(j=0; j<5; j++)
			printf("%2d ", ary[i][j]); //2차원 배열 출력
		printf("\n");
	}
}

 

 

7. 야구게임

 

/*
프로그램 작성자 : americano@korea.ac.kr

작성일자: 11년 11월 20일

프로그램 내용 : 
컴퓨터가 임의의 숫자를 3개를 정합니다.
단, 그 수는 양수이고 10보다 작아야 하며 중복되서는 안됩니다.

사용자는 컴퓨터가 정한 숫자를 맞춰야합니다.
단, 위치까지 맞춰야 합니다. 

컴퓨터는 3개의 숫자 입력을 지시하고
사용자가 3개의 숫자를 입력하면 컴퓨터는 그 수가 말한 위치와 값이 맞는지를 확인합니다.
값과 위치가 같으면 스트라이크, 그 수는 있으나 위치가 틀릴경우 볼을 출력합니다.

이 행위를 반복하여 스트라이크가 3개가 되면 종료됩니다.

구현방법:
1. 현재 시간을 이용해서 씨드를 설정합니다.
2. 3개의 임의의 변수를 만듭니다. 단 중복을 방지합니다.
3. 스트라이크가 3개가 될 때 까지 무한루프로 값을 맞추도록 합니다.
4. 3개의 값을 입력받습니다.
5. 입력 받을 시에도 중복을 방지합니다.
6. 스트라이크와 볼 함수를 실행시켜 스트라이크와 볼의 개수를 return 받습니다.
7. 현재 스트라이크와 볼의 갯수가 몇개인지 출력합니다.
8. 스트라이크가 3개가 되면 종료됩니다.

*/

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int strike(int A[], int B[]); // 컴퓨터가 정한 배열과 사용자가 입력한 배열을 아규먼트로 받아 값과 위치가 같은 수의 갯수를 반환합니다.
int ball(int A[], int B[]); // 컴퓨터가 정한 배열과 사용자가 입력한 배열을 아규먼트로 받아 값은 있지만 위치가 다른 수의 갯수를 반환합니다.

int main()
{
	int str[3]; // 컴퓨터의 배열
	int input[3]; // 사용자가 입력할 배열
	int i;
	int n = 0;
	int s =0, b = 0 ;// 처음 스트라이크와 볼의 갯수는 0으로 초기화
	
	printf("Start Game!\n\n");
	do
	{
		srand((int)time(NULL)); // 현재 시간을 이용해서 씨드 설정
		for(i=0; i<3; i++)
			str[i] = rand()%10; // 임의의 값을 입력받음
	}while(str[0]==str[1] || str[1]==str[2] || str[0]==str[2]); // 중복된 숫자 입력 방지, 첫 숫자 0 방지
	while(s != 3) //스트라이크 3개가 되면 프로그램 종료
	{
		s = 0; // 다시 초기화 시킴
		b = 0;
		while(1) // 사용자로부터 값을 입력 받음
		{
			printf("3개의 숫자 선택: ");
			for(i=0; i<3; i++)
				scanf("%d", &input[i]);
			if(input[0]!=input[1] && input[1]!=input[2] && input[0]!=input[2]) // 정상적으로 입력받으면 루프 탈출
				break;
			else // 중복될 숫자가 있을 시 다시 입력
				printf("중복된 숫자가 있습니다. 다시 입력해주십시오 \n");
		}
		n++;
		s = strike(str, input); // 스트라이크함수를 불러서 스트라이크 갯수를 반환받음
		b = ball(str, input); // 볼 함수를 불러 볼 갯수를 반환받음
		printf("%d번째 도전 결과: %dstrike, %dball!!\n\n", n, s, b); // 결과 출력
	}
	printf("Game end!\n"); 
	return 0; // 프로그램 종료
}

//컴퓨터가 정한 숫자배열과 사용자가 입력한 숫자배열을 입력받아 둘의 값과 위치가 같은 것의 갯수를 반환하는 함수
int strike(int A[], int B[])
{
	int i;
	int s = 0;
	for(i=0; i<3; i++)
		if(A[i]==B[i]) // 위치와 값이 같으면 스트라이크 갯수 1 증가
			s++;
	return s;
}

//컴퓨터가 정한 숫자배열과 사용자가 입력한 숫자배열을 입력받아 둘의 위치가 다르지만 그 값이 존재하는 것의 갯수를 반환하는 함수
int ball(int A[], int B[])
{
	int i;
	int b = 0;
	for(i=0; i<3; i++)
	{
		if(A[i]==B[(i+1)%3]) // 위치가 다른 것이 같을 경우 볼 1 증가
			b++;
		if(A[i]==B[(i+2)%3])
			b++;
	}
	return b;
}

 

 

8. 도서 관리

 

/* 
문서이름 : hw2.c
프로그램 작성자 : americano@korea.ac.kr
작성일 : 2011_12_15
프로그램 목표 :
1. 간단한 도서 관리용 프로그램
2. 도서에 대한 정보는 제목, 저자, 페이지수를 포함
3. 구조체 배열 10개 선언 후 입력이 끝나면 도서에 대한 정보 화면에 출력
4. 프로그램 종료와 함께 입력 내용을 "dadada.txt"에 저장
구현방법:
1. 구조체 배열을 10개 선언 합니다.
2. (입력 : 1), (전체내용보기 : 2), (종료 : 3) 에서 한가지를 선택합니다.
3. 입력(1) 시 Insert 함수를 call 하여 구조체 배열에 값들을 입력시킵니다.
4. 전체내용보기(2) 시 Print 함수를 call하여 입력한 값들을 모두 출력합니다.
5. 종료(3) 시 fprint 함수를 이용하여 "dadada.txt"에 입력한 내용을 모두 텍스트파일에 저장하고 동시에 프로그램은 종료됩니다..
6. 3번을 누르지 않는 한 메뉴가 무한루프 되고 입력은 10개까지만 가능합니다.
*/
#include <stdio.h>
typedef struct book
{
	char name[20]; // 저자
	char title[30];// 제목
	int page;	   // 페이지 수
}Book;


void insert(Book *BookAry, int num); //입력함수
void print(Book *BookAry, int num);  //출력함수

int main()
{
	Book bk[10]; // 구조체 배열 10개 선언
	int i;
	int index;
	int number=0; // 입력한 수는 최초 0개로 초기화
	FILE *fp = fopen("dadada.txt","wt");
	if(fp == NULL) // 파일오픈이 실패하였을 경우
	{
		puts("파일오픈실패!");
		return -1; // 비정상종료
	}
	while(1)
	{
		//메뉴 선택
		printf("어느 작업을 하시겠습니까?\n");
		printf("(입력 : 1), (전체내용보기 : 2), (종료 : 3) :  ");
		scanf("%d", &index); 
		if(index==1&&number<10) // 입력선택 (입력개수는 10개이하)
		{
			insert(bk, number); // 입력함수 call
			number++; // 입력개수 증가
		}
		else if(index==1&&number>=10) //초과입력 시
			printf("더이상 입력할 수 없습니다 \n");
		else if(index==2) // 전체내용출력
			print(bk, number);
		else if(index==3) // 프로그램종료 - 동시에 입력한 모든 내용 파일에 저장
		{
			for(i=0; i<number; i++)
			{
				fprintf(fp, "저자 : %s",bk[i].name);
				fprintf(fp, "제목 : %s",bk[i].title);
				fprintf(fp, "page : %d\n",bk[i].page);
			}
			fclose(fp);
			return 0;
		}
		else // 잘못된 index 선택 시
			printf("잘못 입력하셨습니다\n");
	} // 무한루프
}

void insert(Book* BookAry,int num)
{
	printf("도서 정보 입력\n");

	fflush(stdin); // 입력버퍼 소멸
	printf("저자: ");
	fgets(BookAry[num].name,19,stdin); // 저자입력
	fflush(stdin); // 입력버퍼 소멸
	printf("제목: ");
	fgets(BookAry[num].title,29,stdin); // 제목입력
	fflush(stdin); // 입력버퍼 소멸
	printf("페이지수: ");
	scanf("%d",&(BookAry[num].page)); // 페이지수 입력
	fflush(stdin); // 입력버퍼 소멸
	
}
		
void print(Book* BookAry, int num)
{
	int i;
	printf("도서 정보 출력\n");
	for(i=0; i<num; i++)
	{
		printf("저자: ");
		fputs(BookAry[i].name,stdout); // 저자를 화면에 출력
		printf("제목: ");
		fputs(BookAry[i].title,stdout); // 제목을 화면에 출력
		printf("페이지수: ");
		printf("%d\n",BookAry[i].page); // 페이지수를 화면에 출력
	}
}


 

 

9. 벡터 내적

 

/*
문서이름 : hw3.c
프로그램 작성자 : americano@korea.ac.kr
작성일 : 2011_12_15
프로그램 목표 :
복소수의 실수부분과 허수부분으로 만든 벡터를 이용하여 한 계산식의 수렴값을 구합니다. 
A = a+bi , B = c+di로 할경우
계산식 = (||A||^2+||B||^2) - (||A*B||^2 + ||A/B||^2)
위 계산식의 결과를 구하고 다시
A = A*B 
B = A/B 로 설정하여 위의 계산식을 10회 반복하여 그동안 수렴을 축정합니다.

구현방법:
1. 랜덤넘버 제너레이터로 복소수 2개 생성합니다. (A+Bi, C+Di) 단, A,B,C,D의 크기는 -10이상 10이하로 설정
2. 복소수를 A+Bi 라고 할 시 이 값을 이용하여 벡터 <A,B>를 설정합니다.
3. 두개의 복소수의 곱한 값과 나눈 값을 구하고 이 값으로 2개의 벡터를 설정합니다.
4. 두 벡터의 크기의 합을 구하고 
5. 곱한 값과 나눈 값을 다시 2개의 복소수 (A+Bi, C+Di) 로 설정하여 3번으로 되돌아갑니다.
6. 만약 두 벡터의 크기의 합의 차이가 내가 설정한 값 이하로 세번이상 나올 경우 반복을 정지합니다.
7. 1번부터 6번과정을 총 10번 반복합니다.
*/

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct ComplexNumber
{
	double a; //실수 부분
	double b; //허수 부분
}CoNum;

CoNum multiplex(CoNum A, CoNum B); // 두 복소수의 곱한 결과를 반환
CoNum divide(CoNum A, CoNum B); // 두 복소수의 나눈 결과를 반환
double sum(CoNum A, CoNum B);// 두 복소수로 만들어진 벡터 크기의 합을 반환

int main()
{
	CoNum A, B;
	CoNum C, D;
	int i = 0;
	int j = 0;
	double dif = 0; // (두 벡터 크기의 합) - (다른 두 벡터 크기의 합)
	double mydif = 100; // 내가 설정한 차이 값
	double inner = 0; //내가 설정한 값 이하에 수렴한 횟수
	srand((int)time(NULL)); // 현재 시간을 이용해서 씨드 설정
	while(i<10)
	{	
		printf("%d 번째 루프\n", i+1);
		A.a = rand()%10; // 10이하의 임의의 값을 입력받음
		A.b = rand()%10; // 10이하의 임의의 값을 입력받음
		B.a = rand()%10; // 10이하의 임의의 값을 입력받음
		B.b = rand()%10; // 10이하의 임의의 값을 입력받음
		
		if(rand()%2==1)
			A.a *= -1; // 임의로 음수설정
		if(rand()%2==1)
			A.b *= -1; // 임의로 음수설정
		if(rand()%2==1)
			B.a *= -1; // 임의로 음수설정
		if(rand()%2==1)
			B.b *= -1; // 임의로 음수설정

		for(j=0; j<10; j++)
		{
			C = multiplex(A,B); // C = A*B
			D = divide(A,B);	// D = A/B
			dif = sum(A,B) - sum(C,D);

			if(dif<0)
				dif *= -1; // 절대값으로 변경

			printf("%d번째 차이 값 : %g \n" , j+1, dif);
			if(dif<=mydif) // 내가 설정한 이하로 값이 수렴하면
				inner++; // 반복횟수 1 증가
			else
				inner = 0; //그렇지 않을 경우 다시 0으로 초기화
			if(inner==3) // 3번이상 수렴시 루프 탈출
				break;
			A = C;
			B = D;
		}
		i++;
	}
	return 0;
}

CoNum multiplex(CoNum A, CoNum B) // 두 복소수의 곱한 결과를 반환
{	
	CoNum mul1; // 곱한 결과 값
	mul1.a = A.a*B.a - A.b*B.b;
	mul1.b = A.a*B.b + A.b*B.a;
	return mul1;
}
CoNum divide(CoNum A, CoNum B) // 두 복소수의 나눈 결과를 반환
{
	CoNum div1;	// 나눈 결과 값
	CoNum PairB; // 켤레복소수
	PairB.a = B.a;
	PairB.b = -B.b;
	div1 = multiplex(A,PairB); // (a+bi)*(c-di)
	div1.a /= B.a*B.a+B.b*B.b; // 실수부분 / (c+di)*(c-di)
	div1.b /= B.a*B.a+B.b*B.b; // 허수부분 / (c+di)*(c-di)
	return div1;
}

double sum(CoNum A, CoNum B)// 두 복소수로 만들어진 벡터 크기의 합을 반환
{
	double a, b;
	a = A.a*A.a+A.b*A.b; // a^2+b^2
	b = B.a*B.a+B.b*B.b; // c^2+d^2
	return a+b; 
}





 

 

10. 링크드리스트를 이용한 전화번호 관리

 

/* 
문서이름 : hw1.c
작성자 : americano@korea.ac.kr
작성일 : 2011_12_15
프로그램 목표 :
링크드리스트를 이용하여 전화번호 관리 프로그램을 작성합니다.
한 노드에는 이름과, 전화번호가 포함됩니다.
총 입력, 삭제, 검색, 출력, 종료가 메뉴에 구현됩니다.

구현방법:
구조체 링크드리스트로 만듭니다.
입력한 노드는 기존 노드의 노드의 뒤쪽으로 연결됩니다.
삭제는 맨 앞의 노드를 삭제합니다.
검색은 이름으로 검색하여 결과를 출력합니다.
출력은 지금 링크드리스트에 있는 내용을 출력합니다.
종료는 동적할당을 헤제하며 프로그램이 종료됩니다.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct TelNode
{
	char name[20]; // 이름
	char phone[20];// 전화번호
	struct Node *next;
}TelNode;

void Insert(TelNode *start); // 입력함수
void Delete(TelNode *start); // 출력함수
void Search(TelNode *start); // 검색함수
void PrintAll (TelNode *start); // 출력함수

int index(); // 메뉴

int main()
{  
	TelNode *head = NULL;
	head = malloc(sizeof(TelNode)); //처음 노드 동적할당
	head->next = NULL; // 노드는 아무것도 연결되어 있지 않습니다.

	while(1)
	{
		int choice = index(); // 메뉴에서 선택한 후
		TelNode *current = head; // 현재 가리키는 노드는 헤드를 가리킵니다.
		
		switch(choice)
			{
                  case 1:
						Insert(head);
                        break;
                  case 2:
						Delete(head);
                        break;
                  case 3:
						Search(head);
						break;
                  case 4:
                        PrintAll(head);
                        break;
                  case 5:
						while(head->next!=NULL) //모든 링크드리스트의 동적할당을 헤제합니다.
						{
							current = head->next;
							head->next = current->next;
							free(current);
						}
						free(head); // 헤드노드의 동적할당을 헤제합니다.
                        return 0;
                  default:
                        break;
            }
      }
}


// Insert 함수 
void Insert(TelNode *start)
{
	TelNode *current=NULL;
	TelNode *end=NULL;
	current = malloc(sizeof(TelNode)); // 한 메모리를 동적할당합니다.
	current->next=NULL;
	printf("Input Name: ");
	scanf("%s",current->name); //이름을 입력합니다.
	printf("input Tel Number: ");
	scanf("%s",current->phone);// 전화번호를 입력합니다.

	if (start->next==NULL) //1번째 삽입
	{
		start->next = current; // 생성한 노드를 첫번째 노드 이후로 연결합니다.
		printf("---------> Data Insert\n\n");
		return;
	}
	else //2번째 삽입 이후
	{   
		end = start;
		while(1)
		{   
			if(end->next == NULL)  // 노드의 맨 끝에 입력합니다.
			{
				end->next = current;
				printf("---------> Data Insert\n\n");
				return;
			}
			else
				end = end->next; // 노드의 맨 끝으로 이동합니다.
		}
	}
}




// Delete 함수
void Delete(TelNode *start)
{
	TelNode *delNode; 
	if(start->next == NULL) // 지울 노드가 없을 경우
	{
		printf("list is empty\n"); //아무것도 삭제하지 않습니다.
		printf("---------> Data Delete\n\n");
		return;
	}

	else
	{
		delNode = start->next; //삭제할 노드
		start->next = delNode->next; // 처음은 삭제할 노드의 다음 노드를 가리킵니다.
		free(delNode);
		printf("---------> Data Delete\n\n");
		return;
	}
}

// Search 함수
void Search(TelNode *start)
{
	char name[20];
	TelNode *current = start->next;
	printf("Input Name: ");
	scanf("%s",name);

	if(current ==NULL) //입력한 것이 하나도 없는 경우
	{
		printf("list is empty\n");
		printf("---------> Data Search\n\n");
		return;
	}
	while(1)
	{
		if(!strcmp(current->name, name)) // 검색시 입력한 이름을 검색합니다.
		{
			printf("name : %s      /    Tel : %s\n", current->name, current->phone);
			printf("---------> Data Search\n\n");
			return;
		}
				
		else if (current->next == NULL)
		{
			printf("not exist\n"); // 검색한 이름은 리스트에 존재하지 않습니다.
			printf("---------> Data Search\n\n");
			return;
		}

		else
		{
			current = current->next; // 다음노드를 검색하기 위해 위치를 바꿔줍니다.
		}
	}
	
}

// Print 함수
// 주어진 링크드 리스트를 전부 출력합니다. 
void PrintAll (TelNode *start)
{
	TelNode *current;

	if(start->next == NULL) //리스트가 비워져있는 경우
	{
		printf("list is empty\n");
		printf("---------> Print All\n\n");
		return;
	}

	current = start->next; 

	while(current!=NULL) //노드가 끝에 도달할때까지 출력합니다.
	{
		printf("name : %s      /    Tel : %s\n", current->name, current->phone);
		current = current->next; // 다음노드로 이동
	}
	printf("---------> Print All\n\n");
	return;
}

// 메뉴
int index()
{
      int choice;

      while(1)
      {
            printf("---------Menu--------\n");
            printf("             1. Insert\n");
			printf("             2. Delete\n");
			printf("             3. Search\n");
			printf("             4. Print All\n");
			printf("             5. Exit\n");
			printf("             Choose the item: ");
            scanf("%d", &choice);

            if(choice < 1 || choice > 5) // 입력값을 벗어나면 다시 입력합니다.
                  printf("choose again\n");
            else
                  return choice;
      }
}