Cmain.c · 98 行#include <stdio.h>#include <stdlib.h>#include <string.h> typedef struct { int *data; /* 이 줄의 값들을 담으려고 빌린 블록 */ int len; /* 들어 있는 값의 수 */ int cap; /* 빌린 칸의 수 */} Row; typedef struct { Row *rows; int n, cap;} Table; /* 빌리기에 실패하면 멈춘다(받은 포인터를 확인한 다음에 담는다) */static void *grow(void *p, size_t count, size_t size) { void *q = realloc(p, count * size); if (q == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } return q;} /* 표 끝에 빈 줄 자리를 하나 만들어 그 주소를 돌려준다. 표의 블록이 옮겨질 수 있으니, 이 함수를 부르기 전에 쥔 Row 포인터는 부른 뒤에 쓰지 않는다 */static Row *append_row(Table *t, int cap) { if (t->n == t->cap) { t->cap = t->cap ? t->cap * 2 : 4; t->rows = grow(t->rows, (size_t)t->cap, sizeof *t->rows); } Row *r = &t->rows[t->n++]; r->len = 0; r->cap = cap > 0 ? cap : 1; r->data = malloc((size_t)r->cap * sizeof *r->data); if (r->data == NULL) exit(1); return r;} static void push(Row *r, int v) { if (r->len == r->cap) { r->cap *= 2; r->data = grow(r->data, (size_t)r->cap, sizeof *r->data); } r->data[r->len++] = v;} int main(void) { Table t = {NULL, 0, 0}; int q, i, j, k, v; char cmd[8]; if (scanf("%d", &q) != 1) return 0; while (q--) { scanf("%7s", cmd); if (strcmp(cmd, "new") == 0) { scanf("%d", &k); Row *r = append_row(&t, k); for (j = 0; j < k; j++) { scanf("%d", &v); push(r, v); } } else if (strcmp(cmd, "copy") == 0) { scanf("%d", &i); int len = t.rows[i - 1].len; Row *dst = append_row(&t, len); /* 먼저 자리를 만들고 */ const Row *src = &t.rows[i - 1]; /* 그다음 원본 주소를 쥔다 */ memcpy(dst->data, src->data, (size_t)len * sizeof *src->data); /* 바이트 수 = 칸 수 × 칸 크기 */ dst->len = len; } else if (strcmp(cmd, "add") == 0) { scanf("%d %d", &i, &v); push(&t.rows[i - 1], v); } else if (strcmp(cmd, "set") == 0) { scanf("%d %d %d", &i, &j, &v); t.rows[i - 1].data[j - 1] = v; } else if (strcmp(cmd, "del") == 0) { scanf("%d", &i); free(t.rows[i - 1].data); /* 뒤의 줄들을 한 칸씩 당긴다: 겹치는 자리라 memcpy가 아니라 memmove */ memmove(&t.rows[i - 1], &t.rows[i], (size_t)(t.n - i) * sizeof *t.rows); t.n--; } else { scanf("%d", &i); const Row *r = &t.rows[i - 1]; printf("%d", r->len); for (j = 0; j < r->len; j++) printf(" %d", r->data[j]); printf("\n"); } } long long cells = 0; for (i = 0; i < t.n; i++) { cells += t.rows[i].len; free(t.rows[i].data); /* 줄마다 빌린 블록을 돌려주고 */ } free(t.rows); /* 마지막으로 표의 블록을 돌려준다 */ printf("%d %lld\n", t.n, cells); return 0;}