[CS 50トレーナー]第3週


第一題


単位計算プログラム:入力した成績に基づいて単位を出力する


[与えられた条件]

  • キーボード入力成績(0から100点)の有効性チェック
  • 単位配列により
  • を初期化する.
  • 「単位表」の内容を印刷し、それを使用して単位
  • を計算します.
    入力
  • '999'終了プログラム
  • [サンプル画面]



    [ソースコード]

    // 학점 계산 프로그램
    
    #include <cs50.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // 전역변수 선언 (학점 테이블)
    const int NUMBER_OF_GRADES = 9;
    const int SCORES[NUMBER_OF_GRADES] = {95, 90, 85, 80, 75, 70, 65, 60, 0};
    const char *GRADES[NUMBER_OF_GRADES] = {"A+", "A", "B+", "B", "C+", "C", "D+", "D", "F"};
    
    // 함수 프로토타입 선언
    void printGradeTable(void);
    char* calculateGrade(int score, const int scores[], const char *grades[], int length);
    
    int main(void)
    {
        // 학점 테이블 출력
    	printGradeTable();
    
        // 참인 경우 반복 수행
    	while(1)
        {
            int score = get_int("성적을 입력하세요 (0 ~ 100) : ");
    
            // 입력받은 점수에 따라 참인 조건 수행
            if (score == 999)
            {
                printf("학점 프로그램을 종료합니다.\n");
                return 0;
            } // 프로그램 종료
    
            else if (score >= 0 && score <= 100)
            {
                char *grade = calculateGrade(score, SCORES, GRADES, NUMBER_OF_GRADES);
                printf("학점은 %s 입니다.\n", grade);
                free(grade)
            } // 유효성 체크 : 0 <= 성적 <= 100
    
            else
            {
                printf("** %d 성적을 올바르게 입력하세요. 범위는 0 ~ 100 입니다.\n", score);
            } // 성적 < 0 이거나 성적 > 100 일 때, 수행
        }
    	return 0;
    }
    
    // 학점 테이블 내용 출력하는 함수
    void printGradeTable(void)
    {
    	printf("학점 프로그램\n");
    	printf("종료를 원한다면\"999\"를 입력\n");
        printf("\n");
    	printf("[ 학점 테이블 ]\n");
    
    	printf("점수 : ");
    	for (int i = 0; i < NUMBER_OF_GRADES; i++)
    	{
    		printf("%i\t", SCORES[i]);
    	}
    	printf("\n");
    
    	printf("학점 : ");
    	for (int i = 0; i < NUMBER_OF_GRADES; i++)
    	{
    		printf("%c\t", *GRADES[i]);
    	}
    	printf("\n");
        printf("\n");
    }
    
    // 성적을 입력 학점을 구하는 함수
    char* calculateGrade(int score, const int scores[], const char *grades[], int length)
    {
    	char *grade = malloc(2);
    
    	for (int i = 0; i < length; i++)
    	{
    		if (score >= scores[i])
    		{
    			grade = malloc(sizeof(char) * strlen(grades[i]));
    			strcpy(grade, grades[i]);
    			break;
    		}
    	}
    
    	return grade;
    }

    [結果画面]



    第二題


    データセットから除外された数字を出力するプログラム:1からNまでのデータセットから除外された数字Kを検索する


    [与えられた条件]

  • 2 <= N <= 500,000
  • 並べ替えられていないコレクションファイル
  • ファイル構造:第1の動作N値、次の動作空、K以外の(N-1)個の数字
  • をリストする

    [サンプル画面]



    [ソースコード(チームバージョンの発行)

    // 숫자 모음에서 제외된 숫자를 출력하는 프로그램
    
    #include <stdio.h>
    #define SIZE 500000
    
    int main(int arge, char*argv[])
    {
        int n;
        int partSum = 0;
    
        scanf("%d", &n);
    
        // 1부터 N의 숫자중 K가 빠진 배열
        int partArr[SIZE];
        int lengthOfPartArr = n - 1;
    
        for (int i = 0; i < lengthOfPartArr; i++)
        {
            scanf("%d", &partArr[i]);
            partSum += partArr[i];
        }
    
        // K 구하기
        int nSum = n * (n + 1) / 2;
        int answer = nSum - partSum;
    
        printf("K = %i\n", answer);
    
        return 0;
    }

    [フィードバック]


    2つ目のアルゴリズムの解決策は個人的にとても好きな方法です:)しかし、もう少しフィードバックをくれれば、Nの大きさは2から500000まで流れていて、SIZEを固定するのはメモリを浪費しすぎます.もし、n=2なら、14行目は499998*4バイトのメモリを無駄にしているのではないでしょうか.この場合はダイナミック割り当てを使用したほうがいいです!
    しかし、もう少し進むと、31行目と同じ方法でKを計算し、必ず保存する必要があると思います.変数に追加する方法もあります.

    [ソースコード(フィードバックver)]

    #include <stdio.h>
    
    int main(){
    	int n;
    	scanf("%d", &n); // get N
    
    	long totalSum = 0; // sum of N-1 values
    	for(int i = 0; i < n-1; i++){
    	int temp;
    	scanf("%d", &temp);
    	totalSum += temp; // add given value to the variable
    	}
    
    	long from1toN = n * (n+1) / 2; 
        // calculate sum of 1, 2, ..., n
    	printf("K = %ld\n", from1toN - totalSum);
    
    	return0;
    }

    第三題


    アレイによるキューデータ構造の実装


    [与えられた条件]


    入力オプション
  • (1、2、3、4)に従って、スイッチゲートを使用して各機能
  • を実現する.
  • add()関数、pop()関数、display()関数
  • [サンプル画面]



    [ソースコード]

    #include <stdio.h>
    #include <stdlib.h>
    #define MAX_QUEUE_SIZE 10
    
    // 큐 원소의 자료형 int로 정의
    typedef int element;
    
    // 큐 타입
    typedef struct
    {
        int front;
        int rear;
    
        // 1차원 배열 큐 선언
        element data[MAX_QUEUE_SIZE];
    } QueueType;
    
    // 함수 프로토타입 선언
    QueueType *createQueue();
    void enqueue(QueueType *q);
    int dequeue(QueueType *q);
    void display(QueueType *q);
    void print();
    
    int main()
    {
        // n : 항목 선택에 쓰이는 변수
        int n;
        int quit = 0;
    
        // 큐 생성
        QueueType *q = createQueue();
    
        // quit 값이 1이 아닌 경우 무한루프
        while (!quit)
        {
            printf("입력 : ");
            scanf("%d", &n);
    
            switch(n)
            {
                // 1. 삽입
                case 1 :
                    add(q);
                    print();
                    break;
    
                // 2. 삭제
                case 2:
                    pop(q);
                    print();
                    break;
    
                // 3. 조회
                case 3:
                    display(q);
                    print();
                    break;
    
                // 4. 종료
                case 4:
                    printf("프로그램 종료!\n");
                    quit = 1; // 무한루프 빠져나오기
                    break;            
            }
        }
        return 0;
    }
    
    
    // 큐 생성 함수
    QueueType *createQueue()
    {
        QueueType *q;
    
        // 큐 사이즈만큼 메모리 할당
        q = (QueueType *) malloc(sizeof(QueueType));
    
        // 초기값 설정
        q->rear = -1;
        q->front = -1;
    
        return q; 
    }
    
    
    // 옵션 프린트 함수
    void print()
    {
        printf("\n");
        printf("=================================\n");
        printf("1. 삽입\n");
        printf("2. 삭제\n");
        printf("3. 조회\n");
        printf("4. 종료\n");
        printf("=================================\n");
        printf("\n");
    }
    
    
    // 큐에 값 삽입하는 함수
    void enqueue(QueueType *q)
    {
        // 큐가 포화 상태인 경우 삽입 x
        if (q->rear == MAX_QUEUE_SIZE - 1)
        {
            printf("Queue가 꽉 찼습니다.\n");
        }
    
        // 큐에 빈 공간이 남은 경우 -> 값 입력받아 삽입
        else
        {
            q->rear++; // rear += 1
    
            int num;
            printf("값 입력 : ");
            scanf("%d", &num);
    
            // 큐 내에 삽입될 위치에 입력받은 값 대입
            q->data[q->rear] = num;
        }
    }
    
    
    // 큐 값을 삭제하는 함수
    int dequeue(QueueType *q)
    {
        // 큐 공백 상태일 경우
        if (q->front == q->rear)
        {
            printf("Queue가 비어있습니다.\n");
            return -1;
        }
    
        // 큐가 공백 상태가 아닐 경우
        else
        {
            // 원소 삭제 위치
            q->front ++;
    
            // 삭제 위치의 원소(데이터)를 num에 대입
            int num = q->data[q->front];
            printf("%d 삭제됨\n", num);
    
            return num;
        }
    }
    
    
    // 큐 원소를 출력하는 함수
    void display(QueueType *q)
    {
        int i;
        for (i = q->front +1; i <= q->rear; i++)
        {
            printf("%d\t", q->data[i]);
        }
        printf("\n");
    }

    [結果画面]