—ฅ/ᐠ. ̫ .ᐟ\ฅ —

과목 일반

[프로그래밍 기초] 🎓 기말고사 오답노트

WIFI-Aircat 2024. 12. 2. 00:38
💾 Basic of Programming
Final Exam


🆀 문제 1.
이차원 배열 더하기

파일
- f11.txt

12 2 16 30
8 28 4 10
20 6 18 9

 

- f12.txt

1 2 3 4
5 6 7 8
9 10 11 12

 

🆂 풀이
나의 풀이
배열 A와 B를 함수 sumAB()에 넘기지 못 했다.
이차원 배열을 인수로 넘길 때 매개변수가 이중 포인터여서 문제가 됨.

void sumAB(int **A, int **B) { // wrong!
	int sum = 0;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 4; j++) {
			sum = A[i][j] + B[i][j];
			printf("%3d", sum);
		}
		puts("");
	}
}

int main() {
	FILE* f11 = fopen("f11.txt", "r");
	if (f11 == NULL) {
		printf("f11 Err\n");
		exit(1);
	}
	FILE* f12 = fopen("f12.txt", "r");
	if (f12 == NULL) {
		printf("f12 Err\n");
		exit(1);
	}

	int A[3][4] = {0}; //ary
	int B[3][4] = {0};

	for (int i = 0; i < 3; i++) { //elements
		for (int j = 0; j < 4; j++) {
			fscanf(f11,"%d", &A[i][j]);
		}
	}
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 4; j++) {
			fscanf(f12, "%d", &B[i][j]);
		}
	}

	sumAB(A, B);

	return 0;
}



정답
- 이차원 배열을 인수로 넘길 때는 매개변수가 이중 포인터이면 안 된다

int *A[4]; int *B[4];
void sumAB(int A[][4], int B[][4]) {....
- exit()는 <stdlib.h>의 함수
- 파일 사용 후 fclose( ); 필요



🆀 문제 2.
Max, Min, Average 출력

파일

3
8 5 11
3 89 9 11 -99 80 0 37
18 -85 -1 1010 40
754 13 32 42 19 -5 22 14 57 69 7


결과
0: max = 89 min = -99 avg = 16.25
1: max = 1010 min = -85 avg = 196.40
2: max = 754 min = -5 avg = 93.09

🆂 풀이
나의 풀이

int pntmax(int** ary, int i, int c[]) {
	int max = ary[i][0];
	int temp = 0;
    
	for (int j = 0; j < c[i]; j++) {
		if (max < ary[i][j]) {
			temp = ary[i][j];
			ary[i][0] = max;
			max = temp;
		}
	}
	return max;
}

int pntmin(int** ary, int i, int c[]) {
	int min = ary[i][0];
	int temp = 0;

	for (int j = 0; j < c[i]; j++) {
		if (min > ary[i][j]) {
			temp = ary[i][j];
			ary[i][0] = min;
			min = temp;
		}
	}
	return min;
}

double pntavg(double sum, int i, int c[]) {
	double avg = sum / (double)c[i];
	return avg;
}

int main() {
	int r;
	int** ary;
	int c[10];

	FILE* file = fopen("f2.txt", "r");
	if (file == NULL) {
		printf("file Err\n");
		exit(1);
	}
	fscanf(file, "%d", &r);
	ary = (int**)malloc(sizeof(int*) * r);
	if (ary == NULL) {
		printf("ary Err");
		exit(1);
	}
	for (int i = 0; i < r; i++) { // 3만큼 돌아감
		fscanf(file, "%d", &c[i]); // [0]8 5 11
		ary[i] = (int*)malloc(sizeof(int) * c[i]); //8 5 11 할당
	}
    
    for (int i = 0; i < r; i++) {
        double sum = 0;
        for (int k = 0; k < c[i]; k++) {
            fscanf(file, "%d", &ary[i][k]);
            sum += ary[i][k];
        }
        int max = pntmax(ary, i, c);
        int min = pntmin(ary, i, c);
        double avg = pntavg(sum, i, c);
        printf("%d: max = %d min = %d avg = %.2f\n", i, max, min, avg);
    }
    for (int i = 0; i < r; i++) {
    	free(ary[i]);
    }
    free(ary);
    fclose(file);
    return 0;
}


다른 풀이

int pntmax(int** ary, int i, int c[]) {
    int max = ary[i][0]; // 첫번째 값으로 초기화
    int *ptr = ary[i]; // 포인터 선언

    for (int j = 0; j < c[i]; j++){
        if(max < *(ptr+j))
        max = *(ptr+j);
    }
	return max;
}

int pntmin(int** ary, int i, int c[]) {
    int min = ary[i][0];
    int *ptr = ary[i];

    for (int j = 0; j < c[i]; j++){
        if(min > *(ptr+j))
        min = *(ptr+j);
    }
	return min;
}

 

포인터로 풀 수 있다.



🆀 문제 3.
원본을 출력 후, 함수를 이용해 숫자를 오름차순, 이름을 가나다순으로 정렬해서 출력

파일

300 김자경 경기도
350 나한국 대구시
270 도현미 서울시
250 서칠서 서울시
265 이안나 부산시
400 허준이 광주시


🆂 풀이
나의 풀이

struct employee {
int num;
char name[30];
char adress[30];
};
typedef struct employee em; // data type name is 'em'

void pntnum(em*, int);
void pntname(em*, int);
void pntorigin(em*, int);

int main() {
    FILE* file = fopen("f3.txt", "r");
        if (file == NULL) {
        printf("file Err\n");
        exit(1);
    }

    struct employee emplos; // define struct as emplos
    em* ary;
    int n = 0, i = 0;
    int size = 5;

    ary = (em*)malloc(sizeof(em) * size); // allocation
    if (ary == NULL) {
        printf("alloc Err\n");
        exit(1);
    }
    while ((fscanf(file, "%d %s %s", &emplos.num, emplos.name, emplos.adress)) != EOF) {
        ary[n] = emplos; // 배열에 저장하기
        n++; // 개수
        if (n > size) { // 개수가 배열 크기를 넘으면 realloc을 통해 배열 크기를 2배로 늘린다
            size *= 2;
            ary = (em*)realloc(ary, sizeof(em) * size); // re allocation
        }
    }

    pntorigin(ary, n);
    pntnum(ary, n);
    pntname(ary, n);

	return 0;
}

void pntorigin(em* p, int n) {
    for (int i = 0; i < n; i++) {
            printf("origin: %d %s %s", p[i].num, p[i].name, p[i].adress);
            puts("");
        }
        puts("");
    }

int comp1(const void* a, const void* b) {
    return (((em*)a)->num - ((em*)b)->num);
}

void pntnum(em *p, int n) { // 숫자 오름차순 정렬
qsort(p, n, sizeof(em), comp1);
    for (int i = 0; i < n; i++){
        printf("%d %s %s", p[i].num, p[i].name, p[i].adress);
        puts("");
    }
    puts("");
}

int comp2(const void* a, const void* b) {
    return strcmp(((em*)a)->name, ((em*)b)->name);
}

void pntname(em *p, int n) { // 이름 가나다순 정렬
    qsort(p, n, sizeof(em), comp2);
    for (int i = 0; i < n; i++){
        printf("%d %s %s", p[i].num, p[i].name, p[i].adress);
        puts("");
    }
}


풀이
- 구조체에 받아서 배열에 저장하는 부분 잊지 말자
- 문자 비교할 때는 strcmp(a, b)

// 음수, 양수, 0을 반환하는 비교 포인터 함수
int comp2(const void* a, const void* b) {
    return strcmp(((em*)a)->name, ((em*)b)->name);
    // `(em*)a` : 선언한 `const void* a`를 구조체 포인터 타입으로 변환
// `a->num` : 구조체의 num을 비교하기 위해서 num 값을 가져옴
}

qsort(p, n, sizeof(em), comp2);
// Quick Sort의 재귀적 정렬을 사용
// 포인터 함수(comp)의 값에 따라서 배열 요소를 정렬
// 양수의 경우 두 요소의 자리를 바꾼다

 

반응형