초기 네이버 기록/과거 공부 기록

다시 천천히 -씹어먹는 C언어 에라토스테네스의 체 예제 + 계산기 예제

뜨거운 개발자 2023. 1. 7. 01:27
/*자기 자신을 호출하는 함수를 이용해서 1 부터 특정한 수까지의 곱을 구하는 프로그램을 만들어보세요.*/
#include<stdio.h>
int multi(int* N, int* result);
int main() {
	int N;
	int result=1;
	printf("N?:");
	scanf_s("%d", &N); 
	printf("%d!=:", N);
	multi(&N, &result);
	printf("%d", result);
	return 0;
}
int multi(int* N, int* result) {
	*result *= *N;
	*N=*N-1;
	if (*N == 0) {
		return 0;
	}
	multi(N, result);
	return 0;
}//멘탈을 잡고 하기 싫은 코딩을 다시 하기 시작했다
/*계산기를 만들어보세요. 사용자가 1 을 누르면 +, 2 를 누르면 - 와 같은 방식으로 해서 만들면 됩니다. 
물론 이전의 계산 결과는 계속 누적되어야 하고, 
지우기 기능도 있어야 합니다. (물론 하나의 함수에 구현하는 것이 아니라 여러개의 함수로 분할해서 만들어야겠죠?) (난이도 : 中).*/
#include<stdio.h>
int plus(int* a, int* b, int* result);
int minus(int* a, int* b, int* result);
int multi(int* a, int* b, int* result);
int divion(int* a, int* b, int* result);
int reset(int* result);
int main() {
	int a, b;
	int tmp;
	int result;
	printf("number1:");
	scanf_s("%d", &a);
	printf("1:+\n2:-\n3:*\n4:/\nother:reset result\n");//5는 결과가 출력되게 하는 걸로 할까 하다가 일단 만들고 return 0;
	scanf_s("%d",&tmp);
	printf("number2:");
	scanf_s("%d", &b);
	switch (tmp) {
	case 1:
		plus(&a, &b, &result);
		break;
	case 2:
		minus(&a, &b, &result);
		break;

	case 3:
		multi(&a, &b, &result);
		break;

	case 4:
		divion(&a, &b, &result);
		break;
	
	default:
		reset(&result);
		break;
	}
	printf("계산결과는 %d", result);
	
	return 0;
}
int plus(int* a, int* b, int* result) {
	*result = *a + *b;
	return 0;
}
int minus(int* a, int* b, int* result) {
	*result = *a - *b;
	return 0;
}
int multi(int* a, int* b, int* result) {
	*result = *a * *b;
	return 0;
}
int divion(int* a, int* b, int* result) {
	*result = *a / *b;
	return 0;
}
int reset(int* result) {
	*result = 0;
	return 0;
//계산기 구현 완료!
/*에라토스테네스의 체를 이용해서 1 부터 N 까지의 소수를 구하는 프로그램을 만들어보세요. (난이도 : 中)
에라토스테네스의 체란 2의 배수를 지우고 가까운 소수 찾아서 3의 배수 지우고 가까운 소수 찾아서 5의 배수 지우고 계속 지워서 더이상 지워지지 않으면 소수로 가득찬다.
*/
#include<stdio.h>
int ELA(int* N, int* arr ,int *num);//N까지 숫자, 배열, 소수의 갯수
int main() {
	int N,num;//N까지의 숫자중 소수 출력 ,소수의 총 갯수
	int arr[1000];
	printf("N은 몇?(N는 정수이고 1000까지 가능하다.");
	scanf_s("%d", &N);
	if (N > 1000 || N < 1) { return 0; }
	for (int i = 0; i < N; i++) {
		arr[i] = i + 1;//arr에 숫자 넣기 완료
	}

	ELA(&N, arr, &num);//함수 실행
	
	printf("소수의 총 갯수는 %d", num);//소수 갯수 표현
	for (int i3 = 0; i3 < num; i3++) {//함수 실행후 소수 표현
		printf("%d\n", arr[i3]);
	}
	return 0;
}
int ELA(int* N, int* arr, int* num){//N까지 숫자, 배열, 소수의 갯수
	*num = *N;//총 소수의 갯수는 일단N과 같다. 
	int count = 0;//줄어들고 남은 소수의 갯수이다.
	for (int i1 = 2; i1 < *num; i1++) {//i1이 2부터인건 1을 제외하고 시작하기 위해서이다.
		count = 0;//배열의 갯수는 한번 위쪽 문을 완료하면 다시 0부터 시작해야해서 0을 넣어준다.
		for (int i2 = 1; i2 < *num; i2++) {
			if (arr[i2] % arr[i1] == !0) {
				
				count++;
				arr[count] = arr[i2];
			}
			else if (arr[i2] == 0) {//배열안에 0이 있다면 그건 끝난거기 때문에 지금까지 카운트 해준 값은 num에 저장해주고 나온다.
				*num = count;
				break;
			}

		}
		if (arr[i1] == 0) {
			//만약 i1마저 0이 나온다면 이 함수는 끝이다.
			break;
		}
	}

	return 0;

}//이건 안 풀리네,,
/*에라토스테네스의 체를 이용해서 1 부터 N 까지의 소수를 구하는 프로그램을 만들어보세요. (난이도 : 中)
에라토스테네스의 체란 2의 배수를 지우고 가까운 소수 찾아서 3의 배수 지우고 가까운 소수 찾아서 5의 배수 지우고 계속 지워서 더이상 지워지지 않으면 소수로 가득찬다.
*/
#include<stdio.h>
int ELA(int* N, int* arr ,int *num);//N까지 숫자, 배열, 소수의 갯수
int main() {
	int N,num;//N까지의 숫자중 소수 출력 ,소수의 총 갯수
	int arr[1000] = {0};
	printf("N은 몇?(N는 정수이고 1000까지 가능하다.");
	scanf_s("%d", &N);
	if (N > 1000 || N < 1) { return 0; }//N의 조건식
	for (int i = 0; i < N; i++) {
		arr[i] = i + 2;//arr에 숫자 넣기 완료 (2부터 넣었다.)
	}

	ELA(&N, arr, &num);//함수 실행
	
	printf("소수의 총 갯수는 %d", num);//소수 갯수 표현
	for (int i3 = 0; i3 < num; i3++) {//함수 실행후 소수 표현
		printf("%d\n", arr[i3]);
	}
	return 0;
}
int ELA(int* N, int* arr, int* num){//N까지 숫자, 배열, 소수의 갯수
	*num = *N;//총 소수의 갯수는 일단N과 같다. 
	int count = 0;// 남은 소수의 갯수이다.
	int tmp;//임시변수다.
	for (int i1 = 0; i1 < *num; i1++) {
		count = 0;//배열의 갯수는 한번 위쪽 문을 완료하면 다시 0부터 시작해야해서 0을 넣어준다.
		tmp = arr[i1];
		int i2 = 0;
		while (arr[i2]) {
			if (arr[i2] % tmp == !0)
			{
				arr[count] = arr[i2];
				count++;
			}
			i2++;
		}


	}

	return 0;

}
/*아무리 해도 이 함수 내부에서 배열을 가져와서 다시 사용하는 
방법을 모르겠어서 포기하고 다른 코드를 참조한다. */
#include <stdio.h>

int prime(int num, int *p_num[1]);
int main()
{
int num;
int i;
int p_num[1000] = {0};

printf("1~N까지의 소수를 구하는 프로그램\n");
printf("N의 값을 입력하세요.(2~999) : ");
scanf("%d",&num);

prime(num, p_num);

return 0;
}

int prime(int num, int *p_num)
{
int i, j;

for(i = 2 ; i <= num ; i++)
{
for(j = i ;j<=num ; j+=i)
{
if(j%i==0)
{
p_num[j] += 1;
}
}
}

for(i = 2 ; i <= num ; i++)
{
if(p_num[i] == 1)
{
printf("%5d",i);
}
}

printf("\n");

return 0;
}//이 코드가 이해가 안 갔는데 다시 보니까 천재였다.
/*에라토스테네스의 체를 이용해서 1 부터 N 까지의 소수를 구하는 프로그램을 만들어보세요. (난이도 : 中)
에라토스테네스의 체란 2의 배수를 지우고 가까운 소수 찾아서 3의 배수 지우고 가까운 소수 찾아서 5의 배수 지우고 계속 지워서 더이상 지워지지 않으면 소수로 가득찬다.
*/
#include <stdio.h>

int prime(int num, int* p_num[1]);
int main()
{
	int num;
	int i;
	int p_num[1000] = { 0 };

	printf("1~N까지의 소수를 구하는 프로그램\n");
	printf("N의 값을 입력하세요.(2~999) : ");
	scanf_s("%d", &num);

	prime(num, p_num);

	return 0;
}

int prime(int num, int* p_num)
{
	int i, j;
	//num은 몇까지 입력
	for (i = 2; i <= num; i++)
	{
		for (j = i; j <= num; j += i)
		{
			if (j % i == 0)/*j와 i의 나머지가 0인경우에 배열에 j번째 배열에 그 값에 1을 더한 값을 넣는다.즉 4라면 5 6이라면7 10이라면 11 15라면 16이런식으로 하지만 이러면 지워졌던게
			또나올텐데 이걸 계속 반복하면 어차피 해결된다는 걸까? 어차피 j는 num까지 가니까 상관없나 
			배열2번에는 j는 전부 짝수 배열은 원래 다 0이 었으니까 1이 들어간거다. 음,, 2번에도 1이 들어간거고 아 이건 배열에서 몇번찾는게 아니라 1이들어간 배열은 소수라는걸 나
			타내는거구나!!! 2의 배수에는 전부다 1이 더해진다. 3의 배수에는 전부다 1이 더해진다 4의 배수에도 전부다 1이 더해진다. 와 개 지린다. 이거 코드 짠사람 엄청 똑똑하구나
			이런식으로 쓰다니,,,*/
			{
				p_num[j] += 1;
			}
		}
	}

	for (i = 2; i <= num; i++)
	{
		if (p_num[i] == 1)/*만약 코드에 1이 들어가 있다는건 그 코드는 1이 더해진 후에 단 한번도 어떤수로 나눠지지 않았다는 의미이기 때문에 와,, 이거 나눠서 0이 안 나오는걸 찾는 것
		보다 나눠서 1이 나오는 걸 찾는게 더 쉽다는걸 이용해서 이런식으로 발상을 전환했구나 
		진짜 똑똑하다. */
		{
			printf("%5d", i);
		}
	}

	printf("\n");

	return 0;
}//지린다.

생각해볼 문제 7번은 숫자의 자리수가 너무 클 경우에는 char[1000]식으로 배열을 정의하고 각 배열마다 숫자를 하나씩 넣어서 그 값을 저장하고

아스키코드 48을 빼거나 48인 문자 '0' 을 빼면 문자에서 정수로 변환됨 이런식으로 전환시켜서 각 배열마다 문자로 저장되어있는 숫자들을 숫자로 변환시켜준다. 하지만 계산 결과 역시 문자로 저장되어야 하기 때문에 각 자리별로 계산해주고 두자리가 되면 옆으로 넘기는 걸 해주고 다시 그 자리에 저장을 해주어야한다. 이건 10보다 큰경우 를 덧셈으로 해주면 되고 곱셈의 경우에는 각 자리별로 곱해주는게 1의자리 곱하기 1의자리 1의자리 곱하기 10의 자리 이런식으로 계속 해줘야 하니까 for문을 이용해서 계산해주면 되고 10이상인 경우 앞자리를 옆으로 1의자리 곱하기 1의자리 최대는 81이니까 옆으로 계속 넘겨주면 된다. 코드 구현에 너무 많은 시간을 소비할 것 같아서 다음 걸로 넘어간다.

 

이 글은 코딩 꼬꼬마 시절에 푼 문제를 보관한 글로 네이버에 저장해둔 글을 옮긴 글입니다.
혹시나 참고하시는 부분에 이상한 부분이나 질문이 생긴다면 남겨주시면 친절히 답변 드리겠습니다.

728x90