대학교/프로그래밍랩

[프로그래밍 랩] 6주차 - 행렬, 구조체, 포인터

CodeJin 2021. 10. 7. 17:01

문제 1. 행렬연산

행렬의 합, 차를 return하는 함수를 작성하시오.

 

#include <stdio.h>
#define ROWS	3
#define COLS	3
void print_matrix(int m[ROWS][COLS])
{
    int i, j;
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++)
            printf("%2d ", m[i][j]);
        printf("\n");
    }
}
void add_matrix(int a[ROWS][COLS], int b[ROWS][COLS], int c[ROWS][COLS])
{
    int i, j;
    for (i = 0; i < ROWS; i++)
        for (j = 0; j < COLS; j++)
            c[i][j] = a[i][j] + b[i][j];
}
void sub_matrix(int a[ROWS][COLS], int b[ROWS][COLS], int c[ROWS][COLS])
{
    int i, j;
    for (i = 0; i < ROWS; i++)
        for (j = 0; j < COLS; j++)
            c[i][j] = a[i][j] - b[i][j];
}
void main()
{
    int A[ROWS][COLS] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
    int B[ROWS][COLS] = { {11, 12, 13}, {14, 15, 16}, {17, 18, 19} };
    int C[ROWS][COLS] = { 0 };

    printf("Matrix 배열 사용\n");
    printf("A = \n"); 	print_matrix(A);
    printf("B = \n"); 	print_matrix(B);
    add_matrix(A, B, C);
    printf("A + B = \n"); print_matrix(C);
    sub_matrix(B, A, C);
    printf("B - A = \n"); print_matrix(C);
}

 

문제 2. 행렬 ADT 사용

행렬 구조체를 만들어 문제 1의 함수를 다시 작성하시오.

#include <stdio.h>
#define MAXROWS	100
#define MAXCOLS	100

typedef struct matrix {
    int rows, cols;
    int data[MAXROWS][MAXCOLS];
} Matrix;
#define MAX(a, b) (a>=b ? (a) : (b))

void print_matrix(Matrix* m)
{
    int i, j;
    for (i = 0; i < m->rows; i++) {
        for (j = 0; j < m->cols; j++)
            printf("%2d ", (m->data)[i][j]);
        printf("\n");
    }
}
void add_matrix(Matrix* a, Matrix* b, Matrix* c)
{
    int i, j;
    for (i = 0; i < a->rows; i++)
        for (j = 0; j < a->cols; j++)
            (c->data)[i][j] = (a->data)[i][j] + (b->data)[i][j];
}
void sub_matrix(Matrix* a, Matrix* b, Matrix* c)
{
    int i, j;
    for (i = 0; i < a->rows; i++)
        for (j = 0; j < a->cols; j++)
            (c->data)[i][j] = (a->data)[i][j] - (b->data)[i][j];
}
void main()
{
    //int A[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    Matrix A = { 3, 3, {{1,2,3},{4,5,6},{7,8,9}} };
    //int B[ROWS][COLS] = {{11, 12, 13}, {14, 15, 16}, {17, 18, 19}};
    Matrix B = { 3, 3, {{11,12,13},{14,15,16},{17,18,19}} };
    //int C[ROWS][COLS] = {0};
    Matrix C = { A.rows, A.cols, {0,} };

    printf("Matrix ADT 사용\n");
    printf("A = \n"); 	print_matrix(&A);
    printf("B = \n"); 	print_matrix(&B);
    add_matrix(&A, &B, &C);
    printf("A + B = \n"); print_matrix(&C);
    sub_matrix(&B, &A, &C);
    printf("B - A = \n"); print_matrix(&C);
}

 

문제 3. 구조체 선언과 입출력

학생 정보를 저장하는 구조체를 만들고, 구조체를 입출력하는 함수와 학생을 찾아서 출력하는 main함수를 완성하시오.

본격적으로 문자열에 관한 함수가 등장한다. 문자열 처리하는 부분은 시험에 잘 나오니 알아두자.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // 이름 찾기 위해 필요
typedef struct student {
    char name[20];
    int year;
    char no[20];
    char phone[20];
} Student;

void PrintStudent(Student* s)
{
    printf("이름 : %s ", s->name);
    printf("학년 : %d ", s->year);
    printf("학번 : %s ", s->no);
    printf("전화 : %s ", s->phone);
    printf("\n");
}
void InputStudent(Student* s)
{
    printf("이름 : "); scanf("%s", s->name);
    printf("학년 : "); scanf("%d", &s->year);
    printf("학번 : "); scanf("%s", s->no);
    printf("전화 : "); scanf("%s", s->phone);
}

void main(void)
{
    int i, count, found;
    char name[20]; // 찾을 이름 입력 용
    Student* data;
    printf("몇명 : ");
    scanf("%d", &count);
    data = (Student*)malloc(sizeof(Student) * count); // 완성할것
    for (i = 0; i < count; i++) {
        // 입력 부분 완성
        printf("\n자료번호 %d 입력\n", i + 1);
        InputStudent(&data[i]); // 완성할것
    }
    for (i = 0; i < count; i++) // 출력
        PrintStudent(&data[i]);

    found = 1;
    while (found) {
        printf("찾을 이름: ");
        scanf("%s", name); // 이름 입력
        for (i = 0; i < count; i++) { // 자료 찾기
            // 같은 이름을 찾아서 맞으면  break
            if (strcmp(data[i].name, name) == 0) // 찾으면 break
                break;
        }
        if (i < count) // 찾았다.
            PrintStudent(&data[i]);
        else {
            printf("찾는 데이타가 없습니다.\n");
            found = 0;
        }
    }
    free(data);
}

 

문제 4. 문자열 처리(배열)

string.h와 배열을 이용하여 문자열에 관한 여러가지 함수를 익힌다. 또한 문자열을 뒤집는 reverse함수를 구현하라. 이때, 한글도 고려해야 한다.

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

void reverse(char to[], char from[]) {
    // 완성할것
    int len = strlen(from);
    int i;
    for (i = 0; i < len; i++)
        to[i] = from[len - i - 1];

    to[len] = '\0';
}
// 한글을 고려한 reverse
// 한글 조건 ((unsigned char)from[i]>=0x80 && (unsigned char)from[i+1]>=0x80)
// 한글은 영문기준 2문자가 한글 1글자임
void reverseK(unsigned char to[], unsigned char from[]) {
    // 한글 2bytes를 고려한 reverse
    // 완성할것
    int len = strlen(from);
    int i;
    for (i = 0; i < len; i++)
        if (from[len - i - 1] >= 0x80 && from[len - i - 2] >= 0x80) {
            to[i] = from[len - i - 2];
            to[i + 1] = from[len - i - 1];
            i++;
        }
        else {
            to[i] = from[len - i - 1];
        }
    to[len] = '\0';

}
int main() {
    char str1[100] = "Hansung"; // "한성대학교"
    char str2[100] = "University";
    char str3[100] = "Computer";
    char str4[100] = "Engineering";
    char str5[100];
    char str6[100];
    int ret;

    ret = strlen(str1);
    printf("strlen(%s)=%d\n", str1, ret);
    ret = strcmp(str1, str1);
    printf("strcmp(%s, %s) = %d\n", str1, str1, ret);
    ret = strcmp(str1, str2);
    printf("strcmp(%s, %s) = %d\n", str1, str2, ret);
    ret = strcmp(str1, str3);
    printf("strcmp(%s, %s) = %d\n", str1, str3, ret);

    strcpy(str5, str1);
    printf("strcpy str5 = %s\n", str5);
    strcat(str5, " ");
    strcat(str5, str2);
    printf("strcat str5, str2 = %s\n", str5);

    reverseK(str6, str5);
    printf("reverse str5 = %s\n", str6);
}

 

문제 5. 문자열 처리(포인터)

string.h에 구현된 여러 문자열 함수들과 배열의 사용 없이 오로지 포인터를 통해 mystrlen, mystrcpy, mystrcat, mystrcmp, reverse함수를 구현하라. 이때 reverse함수는 한글을 고려해야 한다.

#include <stdio.h>

char* mystrcpy(char* to, char* from)
{
    char* tmp = to;
    while (*tmp++ = *from++);
    return to;
}
int mystrlen(char* str)
{
    int len = 0;
    while (*str++) len++;
    return len;
}
int mystrcmp(char* s1, char* s2)
{
    int result = 0;
    while (1) {
        if (*s1 == '\0' || *s2 == '\0') break;
        if (*s1 > *s2) {
            result = 1;
            break;
        }
        else if (*s1 < *s2) {
            result = -1;
            break;
        }
        *s1++; *s2++;
    }
    return result;
}
char* mystrcat(char* to, char* from)
{
    char* tmp = to;
    while (*tmp) tmp++;
    while (*tmp++ = *from++);
    return to;
}
// 한글을 고려한 reverse 작성
void reverse(char* to, char* from)
{
    int len = 0;
    int kor = 0;
    char* tmp = to;
    while (*from++) len++;
    *from--; *from--;
    while (len--) {
        if ((unsigned char)*from >= 0x80 && (unsigned char)*from - 1 >= 0x80) {
            *(tmp+1) = *from--;
            *tmp++ = *from--;
            *tmp++;
            kor++;
        }
        else
            *tmp++ = *from--;
    }
    *(tmp-kor) = '\0';
}
int main()
{
    char str1[100] = "한성대학교";
    char str2[100] = "University";
    char str3[100] = "Computer";
    char str4[100] = "Engineering";
    char str5[100];
    char str6[100];
    int ret;

    ret = mystrlen(str1);
    printf("mystrlen(%s)=%d\n", str1, ret);
    ret = mystrcmp(str1, str1);
    printf("mystrcmp(%s, %s) = %d\n", str1, str1, ret);
    ret = mystrcmp(str1, str2);
    printf("mystrcmp(%s, %s) = %d\n", str1, str2, ret);
    ret = mystrcmp(str1, str3);
    printf("mystrcmp(%s, %s) = %d\n", str1, str3, ret);
    //mystrcpy(str5, str1);
    printf("mystrcpy str5 = %s\n", mystrcpy(str5, str1));
    mystrcat(str5, " ");
    //mystrcat(str5, str2);
    printf("mystrcat str5 = %s\n", mystrcat(str5, str2));
    reverse(str6, str5);
    printf("reverse str5 = %s\n", str6);
}

 

문제 7. 백준 9037번

https://codejin.tistory.com/85

 

백준 9037번 C언어 풀이

https://www.acmicpc.net/problem/9037 9037번: The candy war 입력은 표준입력(standard input)을 통해 받아들인다. 입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 각각의 테스트 케이스의 첫 줄에는 아..

codejin.tistory.com