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

배운것 기록 + 유클리드 호제법 문제 (씹어먹는 C언어)

뜨거운 개발자 2023. 1. 7. 01:24
/* 2 차원 배열의 각 원소를 1 씩 증가시키는 함수 */
#include <stdio.h>
/* 열의 개수가 2 개인 이차원 배열과, 총 행의 수를 인자로 받는다. */
int add1_element(int(*parr)[2], int i); //열이 2인 이차원 배열과 행의 갯수를 입력받는다.
int main() {
	int arr[3][2];
	for (int i1 = 0; i1 < 3; i1++) {
		for (int i2 = 0; i2 < 2; i2++) {
			printf("숫자를 입력하세요:");
			scanf_s("%d", &arr[i1][i2]);
		}
	}
	add1_element(arr,3);

	for (int i1 = 0; i1 < 3; i1++) {
		for (int i2 = 0; i2 < 2; i2++) {
			printf("arr[%d][%d]:%d\n",i1,i2,arr[i1][i2]);
			
		}
	}
	return 0;
}

int add1_element(int(*parr)[2], int i) {
	
	for (int i1 = 0; i1 < 3; i1++) {

		for (int i2 = 0; i2 < 2; i2++) {
			parr[i1][i2]++;
		}

	}
	return 0;
}
/*문제 1번:
사용자로 부터 5 명의 학생의 수학, 국어, 영어 점수를 입력 받아서 평균이 가장 높은 사람 부터 평균이 가장 낮은 사람까지 정렬되어 출력하도록 하세요. 
특히, 평균을 기준으로 평균 이상인 사람 옆에는 '합격', 아닌 사람은 '불합격' 을 출력하게 해보세요 (난이도 : 中上).*/
/*학생들의 점수를 입력받기-arr[5][3]평균은 /3 구하기 평균값을 따로 저장할 필요 있다. ave[5], ave가 작은 순서대로 정렬 
평균의 평균을 구해서 평균보다 큰 사람은 합, 아니면 불합
*/
#include<stdio.h>
int test_result(int* ave);
int main() {
	int arr[5][3];
	int aver[6];
	for (int i1 = 0; i1 < 5; i1++) {//학생들의 성적을 입력한다.
		printf("Write number %d student's test result:\n",i1+1);
		printf("math:");
		scanf_s("%d", &arr[i1][0]);
		printf("korean:");
		scanf_s("%d", &arr[i1][1]);
		printf("english:");
		scanf_s("%d", &arr[i1][2]);
		aver[i1] = (arr[i1][0] + arr[i1][1] + arr[i1][2]) / 3;//각 학생들의 평균 성적 입니다.
	}
	test_result(aver);//시험 결과 값을 나타낸다.
	printf("공부 열심히 하세요!");
	return 0;

}
test_result(int* ave) {
	int student_num = 5;//학생 수를 정의
	int tmp;//임시 변수
	int all_ave=0;//전체의 평균
	while (student_num) {//큰 숫자를 뒤로 보낸다.
		for (int i2 = 0; i2 < student_num; i2++) {
			if (ave[i2] >=ave[i2 + 1]) {
				
				tmp = ave[i2 + 1];
				ave[i2 + 1] = ave[i2];
				ave[i2] = ave[i2 + 1];
			}

		}
		student_num--;
	}
	for (int i4 = 0; i4 < 5; i4++) {
		all_ave += ave[i4]/5;//전체 합 구하기
	}
	for (int i3 = 0; i3 < 5; i3++) {
		printf("%d등은 평균 %d점 ",i3+1,ave[i3]);
		if (ave[i3] > all_ave) {
			printf("합격\n");

		}
		else {
			printf("불합격\n");
		}
	}
	return 0;
}//문제가 알고리즘은 맞는 것 같은데 코드가 오류가 제법 있다...이거 고치느라 오늘 하루 다 썻다...

하나 발견

tmp = ave[i2 + 1];
				ave[i2 + 1] = ave[i2];
				ave[i2] = ave[i2 + 1];//가 아니라 tmp이다

 

/*문제 1번:
사용자로 부터 5 명의 학생의 수학, 국어, 영어 점수를 입력 받아서 평균이 가장 높은 사람 부터 평균이 가장 낮은 사람까지 정렬되어 출력하도록 하세요. 
특히, 평균을 기준으로 평균 이상인 사람 옆에는 '합격', 아닌 사람은 '불합격' 을 출력하게 해보세요 (난이도 : 中上).*/
/*학생들의 점수를 입력받기-arr[5][3]평균은 /3 구하기 평균값을 따로 저장할 필요 있다. ave[5], ave가 작은 순서대로 정렬 
평균의 평균을 구해서 평균보다 큰 사람은 합, 아니면 불합
*/
#include<stdio.h>
int test_result(int* ave);
int main() {
	int arr[5][3];
	int aver[5];
	for (int i1 = 0; i1 < 5; i1++) {//학생들의 성적을 입력한다.
		printf("Write number %d student's test result:\n",i1+1);
		printf("math:");
		scanf_s("%d", &arr[i1][0]);
		printf("korean:");
		scanf_s("%d", &arr[i1][1]);
		printf("english:");
		scanf_s("%d", &arr[i1][2]);
		aver[i1] = ((arr[i1][0] + arr[i1][1] + arr[i1][2]) / 3);//각 학생들의 평균 성적 입니다.
	}
	test_result(aver);//시험 결과 값을 나타낸다.

	printf("공부 열심히 하세요!");
	return 0;

}
test_result(int* ave) {
	int student_num = 4;//학생 수-1로 정의
	int tmp;//임시 변수
	int all_ave=0;//전체의 평균
	while (student_num) {//큰 숫자를 뒤로 보낸다.
		for (int i2 = 0; i2 < student_num; i2++) {
			if (ave[i2] >=ave[i2 + 1]) {
				
				tmp = ave[i2 + 1];
				ave[i2 + 1] = ave[i2];
				ave[i2] = tmp;

			}

		}
		student_num--;
	}
	
	for (int i4 = 0; i4 < 5; i4++) {
		all_ave += ave[i4]/5;//전체 평균 구하기

		//중간점검 코드
		printf("all_ave:%d\n",all_ave);
		printf("ave[%d]:%d", i4, ave[i4]);
	}
	for (int i3 = 0; i3 < 5; i3++) {
		printf("%d번은 평균 %d점 ",i3+1,ave[i3]);
		if (ave[i3] > all_ave) {
			printf("합격\n");

		}
		else {
			printf("불합격\n");
		}
	}
	return 0;
}//결국 해결했다. 되게 단순한 문제였는데 기본적인 생각을 못해서 그랬다. 기초부터 천천히 차근차근 잊지말자.
/*유클리드 호제법을 이용해서 N 개의 수들의 최대공약수를 구하는 함수를 만들어보세요.
유클리드 호제법이 무엇인지 모르신다면, 인터넷 검색을 활용하는 것을 추천합니다. 
(댓글을 달아도 돼요) (난이도 : 中上)
유클리드 호제법: 2개의 자연수 a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다는 성질을 이용해서
b를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다.
*/
#include<stdio.h>
int uklid(int a, int b);//유클리드 호재법을 사용해서 두 수 사이 최대 공약수를 찾는 함수.
int main(){
	int N;//N개의 숫자
	int tmp;
	int arr[10] = {1,};//최대 10개까지
	printf("몇개의 숫자를 입력할 껀가요?(최대 10까지)");
	scanf_s("%d", &N);
	
	if (N > 10) {//10 이상일때 종료 해버림
		printf("10까지라고;");
		return 0;
	}
	
	
	for (int i1 = 0; i1 < N; i1++) {//숫자들을 배열에 넣는다.
		printf("%d번째 숫자 입력하세요:", i1 + 1);
		scanf_s("%d", &arr[i1]);
		
	}
	tmp = arr[0];

	for (int i2 = 0; i2 < N; i2++) {
		tmp= uklid(tmp, arr[i2 + 1]);//두수의 최대 공약수를 구하고 그 나오는 값을 다시 안 한 숫자와 공약수를 구하면 그 숫자들의 최대 공약수이다.

	}
	printf("%d가지의 숫자의 최대 공약수는: %d",N, tmp);

	return 0;
}

int uklid(int a, int b) {
	int rest=1;//나머지
	int task=1;//몫
	while (rest) {//나머지가 0이 될때까지 반복
		if (a == 0 || b == 0) {
			break;
		}
		if (a == 0 || b == 0) {
			break;
		}
		if (a > b) {
			rest = (a % b);
			a = b;
			b = rest;
			task = a;
			
			
		}
		else if (a < b) {
			rest = (b % a);
			b = a;
			a = rest;
			task = b;

		}
		else if (a == b) {
			task = a;
		}
	
	}
	return task;
	
}//이게 잘 안 풀린다.. 알고리즘까지는 잘 짰는데 역시 아직 디테일적 실력이 부족하다.
/*유클리드 호제법을 이용해서 N 개의 수들의 최대공약수를 구하는 함수를 만들어보세요.
유클리드 호제법이 무엇인지 모르신다면, 인터넷 검색을 활용하는 것을 추천합니다. 
(댓글을 달아도 돼요) (난이도 : 中上)
유클리드 호제법: 2개의 자연수 a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다는 성질을 이용해서
b를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다.
*/
#include<stdio.h>
int uklid(int *a,int student_num);//유클리드 호재법을 사용해서 배열의 최대 공약수를 찾는 것
int small_front(int* t,int student_num);//큰 순서대로 정렬하는 것.
int main(){
	int N;//N개의 숫자
	int tmp;
	int arr[10];//최대 10개까지
	int k = 1;
	printf("몇개의 숫자를 입력할 껀가요?(최대 10까지)");
	scanf_s("%d", &N);
	
	if (N > 10) {//10 이상일때 종료 해버림
		printf("10까지라고;");
		return 0;
	}
	for (int i1 = 0; i1 < N; i1++) {//숫자들을 배열에 넣는다.
		printf("%d번째 숫자 입력하세요:", i1 + 1);
		scanf_s("%d", &arr[i1]);
		
	}
	small_front(arr, N);//작은수부터 정돈
	for (int i2 = 0; i2 < N; i2++) {
		printf("arr[%d]:%d\n", i2, arr[i2]);
	}
	uklid(arr, N);
	

	return 0;
}
int small_front(int* t, int student_num) {
	printf("작은수부터 배열을 재정돈 합니다.");
	int tmp;//임시 변수
	while (student_num) {
		for (int i1 = 0; i1 < student_num-1; i1++) {
			if (t[i1] > t[i1 + 1]) {
				tmp = t[i1 + 1];
				t[i1 + 1] = t[i1];
				t[i1] = tmp;
			}
		}
		student_num--;
	}
	return t;
}

int uklid(int *a,int student_num) {
	int rest = 1;
	for (int i1 = 0; i1 < student_num-1; i1++) {
		for (;;) {

			
			if (a[i1 + 1] == a[i1]) {
				rest = a[i1+1];
				break;
				
			}
			else {
				rest = (a[i1 + 1] % a[i1]);
				if (rest == 0) {
					rest = a[i1];
					a[i1 + 1] = a[i1];
					break;
				}
				a[i1 + 1] = a[i1];
				a[i1] = rest;

			}
			
		}
		printf("%d번 실행시 rest값:%d\n", i1, rest);
	}
	printf("최대 공약수는: %d", rest);

}

/*유클리드 호제법으로 푼 문제 오래걸렸지만 뿌듯하다. 중간중간에
오류를 찾기 위해서 여러가지를 끼워넣었지만 기록용 이니까 */
#include <stdio.h>

int factorial(int *N, int* temp);
int main() {
	int N = 0;
	int temp = 1;

	printf("N!을 구할 N을 입력하세요. \n");
	scanf_s("%d", &N);
	printf("%d! = ", N);

	factorial(&N, &temp);
	printf("%d \n", temp);

	return 0;
}

int factorial(int *N, int* temp) {
	*temp *= *N;
	*N= *N-1;

	while (*N)
		factorial(N, temp);

	return 0;
}//이 코드는 함수안에서 함수를 호출한다는 의미를 참고하기 위해서 다른분의 코드를 참고했다.

과제는 여기서 가져왔다. 너무 오래 걸려서 다른 공부를 못하겠어서 일단은 계산기까지만 만들고 다음거는 좀 여유가 있을때 다시 해야겠다.

 
/*계산기를 만들어보세요. 사용자가 1 을 누르면 +, 2 를 누르면 - 와 같은 방식으로 해서 만들면 됩니다. 
물론 이전의 계산 결과는 계속 누적되어야 하고, 
지우기 기능도 있어야 합니다. 
(물론 하나의 함수에 구현하는 것이 아니라 여러개의 함수로 분할해서 만들어야겠죠?) 
(난이도 : 中)*/
/*숫자 입력 함수, 곱셈 나눗셈함수, 덧셈 뺄셈 함수 필요, 이전의 결과값들을 저장하는 수result 를 main에서 만들기 아직 엔터를 눌렀을때 결과가 나오는 걸 모르니까 
계산할 숫자를 입력하세요!-->선택하세요1:* ,2:+ ,3:-, 4:/, 5:=, 나머지 숫자: 입력을 다시 합니다-->1,2,3,4=>함수로 처리->다시 입력 받기 결과값 저장하기.
, 5-->결과값 나오게하기 ,나머지 숫자-->숫자 입력 칸으로 돌아감.-->이전의 계산결과 되돌리고, 다시 입력하기. 

*/
#include<stdio.h>
int calculation(int* A,int*B,int*result);//계산기 함수를 정의 두개의 인자는 숫자를 의미
int main() {
	int result;//계산 결과를 저장하는 변수
	int A;//A는 숫자
	int B = 5;
	printf("숫자를 입력하세요:");
	scanf_s("%d", &A);//A에 숫자를 넣는다.
	result = A;
	while (B ==! 5) {
		printf("계산결과:%d", result);
		printf("어떤 연산을 할껀가요?\n 1:+\n 2:-\n3:*\n4:/\n5:=\n");
		scanf_s("%d", &B);
		result = calculation(&A, &B, &result);
	}
	printf("계산 완료 ...계산 결과는%d ", result);
	return 0;
}
/*입력값은 A에 연산을 하는 B가 있고 그 다음 숫자는 함수내부에서 받도록 하자.
함수 내부에서 받은 다음에 미리 받은 연산자와 계산을 하고 계산 결과를 내보내도록 하고 거기에 뭘 더할지 다른 숫자를 넣을경우 어디로 돌아가야할까? 
돌아갈 곳은 계산결과 수정으로 들어가서 result값을 변경시켜주자. 
*/
int calculation(int* A, int* B, int* result) {
	int tmp=0;
	*A = *result;
	printf("추가 숫자를 입력하세요:");
	scanf_s("%d", &tmp);
	for (;;) {
		switch (*B) {
		case 1:
			*result = *A + tmp;
			break;

		case 2:
			*result = *A - tmp;
			break;
		case 3:
			*result = *A * tmp;
			break;
		case 4:
			*result = *A / tmp;
			break;
		default:
			printf("당신은 이상한 숫자를 입력하셨기 때문에 다시 A를 입력하십시오:");
			scanf_s("%d", &tmp);
			continue;

		}
	}
}
/*계산기 겁나 오래걸린다...

다음에 계산기부터 다시 해야겠다,,, ㅜㅜㅜ
*/

 

728x90