코딩/윤성우의 열혈 C프로그래밍

열혈C프로그래밍-도전 프로그래밍2

lee1201zxc 2021. 12. 19. 22:20
300x250
728x90

윤성우의 열혈 C 프로그래밍

328쪽에 위치한 '도전! 프로그래밍 2'의 해설입니다.

 

 

 

 

 

도전 1

 

 

길이가 10인 배열을 선언하고 총 10개의 정수를 입력받아서, 홀수와 짝수를 구분 지어 출력하는 프로그램을 작성해 보자. 일단 홀수부터 출력하고 나서 짝수를 출력하도록 하자. 단, 10개의 정수는 main 함수 내에서 입력받도록 하고, 배열 내에 존재하는 홀수만 출력하는 함수와 배열 내에 존재하는 짝수만 출력하는 함수를 각각 정의해서 이 두 함수를 호출하는 방식으로 프로그램을 완성하자.

 

 

내가 생각했을 때 이 문제의 핵심은 짝수, 홀수를 구분하는 것이 아닌 홀수, 짝수 출력 시 숫자들 사이에 ', '을 넣어 출력하는 것이다. 그냥 출력 시 "% d, "이렇게 해버리면 1,2,3, 이런 식으로 나오는데 이러면 가장 마지막 쉼표는 잘못된 것이기 때문이다. 그래서 1,2,3, 이아닌 1,2,3 이렇게 나오게 하려면 짝수, 홀수의 개수를 정확히 알고 있어야 한다. 그리고 문제에 나온 대로 홀수만, 짝수만 출력하는 함수를 각각 정의하면 된다. 물론 이때 매개변수를 잘 정하여야 한다. 

 

 

코드

#include<stdio.h>
void hol(int * a,int len)
{
	int count=0;
	for(int i=0; i<len; i++)
	{
		if(a[i]%2==1)
			count++;
	}
	printf("홀수출력: ");
	for(int i=0; i<len; i++)
	{
		if(a[i]%2==1)
		{
			count--;
			printf("%d", a[i]);
			if(count!=0)
				printf(", ");
		}
	}
	printf("\n");
}
void jjak(int * a,int len)
{
	int count=0;
	for(int i=0; i<len; i++)
	{
		if(a[i]%2==0)
			count++;
	}
	printf("짝수출력: ");
	for(int i=0; i<len; i++)
	{
		if(a[i]%2==0)
		{
			count--;
			printf("%d", a[i]);
			if(count!=0)
				printf(", ");
		}
	} 
}
int main(void)
{
	int a[10];
	printf("총 10개의 숫자 입력\n");
	for(int i=0; i<10; i++)
	{
		printf("입력:");
		scanf("%d", &a[i]);
	}
	hol(a, sizeof(a)/sizeof(int));
	jjak(a, sizeof(a)/sizeof(int));
	
}

 

main함수에서 10개의 숫자를 입력받아 배열에 저장하고 hol, jjak함수 각각에 배열의 주소와 배열의 크기를 인자로 전달해준다. 배열의 주소만 전달해주면 배열의 크기를 몰라 정확히 계산할 수 없기 때문이다.(물론 이 문제에서는 10개만 입력받으니 sizeof(a)/sizeof(int) 대신 10을 써도 상관없다. 그리고 hol, jjak함수에서 첫 번째 for문에서 홀수, 짝수가 몇 개인지 구해주고 두 번째 for문에서 홀수, 짝수를 출력하고 그 뒤에 쉼표를 출력해주는데 이때마다 count에 1을 빼주다가 count가 0이 되면 쉼표 출력만 멈추어 올바른 출력이 나올 수 있게 하는 것이다.

참고로 어떤 숫자를 2로 나눈 나머지가 0이면 짝수, 1이면 홀수이다. 

 

 

도전 2

 

 

프로그램 사용자로부터 10진수 형태로 정수를 하나 입력받은 다음, 이를 2진수로 변환해서 출력하는 프로그램을 작성해 보자.

 

프로그램을 만들기 전 10진수를 2진수로 만드는 방법을 알아보자 

출처: https://terms.naver.com/entry.naver?docId=2270333&cid=51173&categoryId=51173 (지식백과)

 

위 사진처럼 10진수를 1이 나올 때까지 계속 2로 나누고 이 과정에서 나온 나머지와 마지막에 나온 1을 아래서부터 모아 붙이면 2진수가 된다. 즉 37을 이진수로 변환하면 100101이 된다. 

이제 이것을 프로그램으로 만들어 보자. 

 

 

 

코드

#include<stdio.h>
int main(void)
{
	int n,a[31]={0},i=0; //배열굳이 초기화 안해도 됨
	scanf("%d", &n);
	while(n>0)
	{
		a[i]=n%2;
		n/=2;
		i++;
	}

	for(int z=i-1; z>=0; z--)
		printf("%d", a[z]);
}
//입력값이 제한이 안주어져서 0~2^31-1까지 정했음

 

 

10진수를 2로 나누어 나온 나머지를 바로바로 출력하면 유감스럽게도 답이 반대로 나온다.

37은 이진수로 100101인데 101001이 나온다는 것이다. 그렇기에 나머지들을 저장해놨다가 마지막에 반대로 출력해야 한다. 그래서 나머지들을 저장해주는 배열 a[31]을 선언한다. 문제에 입력 조건이 안 나와 있어서 그냥 int형 범위인 2^31-1까지 정해주었고 그렇기에 31개의 int형 변수를 선언해주었다. 

 

 

 

 

 

도전 3

 

 

 

길이가 10인 배열을 선언하고 총 10개의 정수를 입력받는다. 단, 입력받은 숫자가 홀수이면 배열의 앞에서부터 채워나가고, 짝수이면 뒤에서부터 채워나가는 형식을 취하기로 하자. 따라서 사용자가 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]을 입력했다면, 배열에는 [1, 3, 5, 7, 9, 10, 8, 6, 4, 2]의 순으로 저장이 되어야 한다.

 

 

그냥 문제 그대로 홀수는 앞에서부터, 짝수는 뒤에서부터 채워 나가면 된다.

 

 

코드

#include<stdio.h>
int main(void)
{
	int a[10],n,h=0,j=9;
	for(int i=0; i<10; i++)
	{
		printf("입력: ");
		scanf("%d", &n);
		if(n%2==1)
		{
			a[h]=n;
			h++;
		}
		else
		{
			a[j]=n;
			j--;
		}
	}
	printf("배열 요소의 출력 : ");
	for(int i=0; i<10; i++)
		printf("%d ", a[i]);
}

 

 

 

h는 홀수를 채워 넣을 배열의 위치, j는 짝수를 채워 넣을 배열의 위치이다.

 

 

 

 

 

도전 4

 

 

 

회문(Palindrome)은 앞으로 읽으나 뒤로 읽으나 차이가 없는 단어들을 뜻한다. 예를 들어서 level, bob과 같은 단어들은 회문에 속한다. 이에 우리는 인자로 전달되는 영단어가 회문인지 아닌지를 판단해서 그 결과를 출력하는 기능의 함수를 정의하고, 이에 적절한 main 함수를 정의해 보고자 한다. 단 구현의 편의를 위해서 대소문자까지 일치해야 회문으로 인정하기로 하겠다(이는 어디까지나 구현의 편의를 고려한 제약사항일 뿐이다).

 

 

문자열을 입력받고 맨 앞과 맨뒤 문자를 비교하고 그다음에는 앞에서 두 번째 문자와 뒤에서 두 번째 문자를 비교하고

...... 이렇게 중앙에 이를 때까지 비교한 뒤 한 번이라도 두 문자가 다르면 회문이 아니게 된다.

 

 

코드

#include<stdio.h>
#include<string.h>
void pd(char a[],int b)
{
	int count=0;
	for(int i=0; i<b/2; i++)
	{
		if(a[i]!=a[b-i-1])
			count++;
	}
	if(count==0)
		printf("회문 입니다.");
	else
		printf("회문이 아닙니다.");	
}
int main(void)
{
	char a[101];
	printf("문자열 입력:");
	scanf("%s", a);
	pd(a,strlen(a));
}

 

 

b는 문자열의 길이이다. 

이 코드에서 생각해야 할 점은 문자열이 짝수이면 상관없는데 홀수일 때는 중앙에 있는 문자는 비교하지 않는다는 것이다. 하지만 이는 문제 될 게 없는 게 중앙에 있는 문자는 문자열이 뒤집혀도 그 자리에 그대로 위치하기 때문에 어떤 문자가 오든 회문의 조건을 만족한다.

 

 

 

도전 5

 

 

7개의 정수를 입력받아 버블 정렬을 통해 정렬하는 프로그램을 만들어라

 

 

 

버블 정렬은 두 원소를 비교하면서 큰 것을 뒤로 보내 결국 큰 것부터 뒤에 정렬하는 방식으로

O(n^2)의 시간 복잡도를 가지는 정렬 방식이다.

조금 더 자세히 설명하자면 처음에 1,2번째 원소 비교하여 1번째가 더 크면 1,2번째 원소 위치를 바꾸고

그다음에는 2,3번째 원소, 그다음에는 3,4번째원소.....n-1,n번째 원소까지 비교를 한다. 이러면 

가장 큰 원소가 n번째에 정렬되고 그 다음에는 다시 1,2번째 원소부터 시작해 n-1, n-2번째 원소까지 비교....

이렇게 하나씩 큰 원소부터 정렬하는 방식이다. 

 

아래 네이버 지식백과를 참고하면 이해가 잘될 것이다.

https://terms.naver.com/entry.naver?docId=2270437&cid=51173&categoryId=51173 

 

 

이제 코드로 구현해보자

 

 

 

코드

#include<stdio.h>
int main(void)
{
	int a[7];
	for(int i=0; i<7; i++)
	{
		printf("입력: ");
		scanf("%d",&a[i]);
	}
	for(int i=6; i>0; i--)
	{
		for(int z=0; z<i; z++)
		{
			if(a[z]>a[z+1])
			{
				int ss=a[z];
				a[z]=a[z+1];
				a[z+1]=ss;
			}
		}
	}
	for(int i=6; i>=0; i--)
		printf("%d ", a[i]);
}

 

 

참고로 위에서 설명한 방식은 오름차순 방식이다. 문제에서는 내림차순을 하라는데 그냥 

위의 방식대로 오름차순으로 정렬한 후 거꾸로 출력하면 된다. 

728x90