일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 카카오 코테
- 시스템호출
- python
- Nodejs
- AWS
- 알고리즘
- 스프링
- 코테
- C++
- thymeleaf
- git
- 프로그래머스
- 카카오
- Spring
- @Component
- spring boot
- 가상면접사례로배우는대규모시스템설계기초
- 카카오 알고리즘
- 해시
- nestjs auth
- TypeORM
- OpenCV
- 파이썬
- 코딩테스트
- 컴포넌트스캔
- 구조체배열
- nestjs typeorm
- C언어
- nestJS
- @Autowired
Archives
- Today
- Total
공부 기록장 💻
[자료구조] 배열 실습 문제들 본문
2021/04/02 자료구조 실습 5주차 예제들
1. 1차원 배열: ISBN 문제
내가 작성한 코드:
#include <stdio.h>
#define SIZE 13
int is_ISBN(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
if (i % 2) // 홀수번째인 경우
sum += arr[i];
else sum += 3 * arr[i]; // 짝수번째인 경우 3을 곱한 값을 저장
}
if (sum % 10) // ISBN 코드가 올바르지 않음
return 0;
else return 1; // 코드가 올바른 경우
}
int main(void) {
FILE* fp = fopen("data.txt", "rt");
int arr[SIZE];
for (int i = 0; i < SIZE; i++)
fscanf(fp, "%d", &arr[i]);
for (int i = 0; i < SIZE; i++) printf("%d", arr[i]);
if (is_ISBN(arr, SIZE)) printf("는 유효한 ISBN입니다\n");
else printf("는 유효하지 않은 ISBN입니다\n");
return 0;
}
정답 코드:
+ 파일에 저장되어 있는 정수 개수가 13개인지 확인 (while문 돌리며 저장하는 동시에 cnt 로 세기)
#include <stdio.h>
int is_ISBN(int arr[]) {
// ISBN 규칙: a + 3^b + c + 3^d + ...
// 홀수는 값 그대로, 짝수는 3을 곱한 값을 저장
int nSum = 0; // 나머지를 계산하기 위한 합계
for (int i = 0; i < 13; i++) {
if (i % 2==1) // 홀수인덱스(1,3,5,7,9,11)
nSum += 3*arr[i];
else // 짝수
nSum += arr[i];
}
// 10으로 나누어 0이면 ISBN
if (nSum % 10 == 0) // valid ISBN
return 1;
else return -1; // invalid ISBN
}
int main(void) {
// 변수 선언
int nISBN[13];
int nCount = 0; // 13자리 숫자인지?
int nResult = 0; // ISBN
FILE* fp;
// file open
fp=fopen("data.txt", "rt");
// fp 빙아 코드
if (fp == NULL) {
printf("file not found\n");
return 0;
}
// data.txt에 있는 ISBN이 13자리인지 체크
while (!feof(fp)) {
if (nCount > 13) {
printf("ISBN은 13자리입니다.\n");
return 0;
}
fscanf(fp, "%d", &nISBN[nCount]); // &nISBN[nCount++]
nCount++;
}
// ISBN 규칙에 부합하는지 체크
nResult = is_ISBN(nISBN);
// 결과 값 출력
for (int i = 0; i < 13; i++)
printf("%d", nISBN[i]);
if (nResult== -1)
printf("는 유효하지 않은 ISBN입니다\n");
else if(nResult==1)
printf("는 유효한 ISBN입니다\n");
return 0;
}
2. 2차원 배열: 전치 행렬 문제
여기서 막힌 부분은.. 행과 열을 어떻게 구분하여 fscanf()로 받을건지였다.
한 행이 끝나면 rCount를 증가시켜야 할 텐데, 어떻게 할 수 있는가?
내가 작성한 코드:
// 파일로부터 데이터 읽어 행렬 초기화 시키고 이 행렬의 전치 행렬 구하기
#include <stdio.h>
#include <stdlib.h>
#define MAX_ROWS 30
#define MAX_COLS 30
int main(void) {
FILE* fp;
int m[MAX_ROWS][MAX_COLS];
int sparseM[MAX_ROWS][MAX_COLS];
int data;
char cdata=0;
int cCount = 0; // 열의 개수 구하기
int rCount = 0; // 행의 개수 구하기
// 파일 열기
fp = fopen("data2.txt", "rt");
if (fp == NULL) {
printf("File not found\n");
return 0;
}
// 파일로부터 데이터 읽어 행과 열의 값 구하기
// 열의 개수 읽어오기.
while (!feof(fp)) {
if (cdata == '\n') break; // 만약 개행문자가 온 것이라면 열의 값 그만 읽는다.
fscanf(fp, "%d%c", &data, &cdata); // 정수와 char형문자를 한꺼번에 같이 읽는다.
printf("%d ", data);
cCount++; // 하나 읽을 때마다 열의 값 증가
}
printf("\n열의 개수 = %d\n\n", cCount);
// 파일 읽어 행렬 초기화
rewind(fp); // 파일 포인터의 위치를 파일의 처음으로 이동
while (!feof(fp)) {
for (int i = 0;i < cCount;i++) {
fscanf(fp, "%d", &m[rCount][i]);
printf("rcount = %d, %d\n", rCount, m[rCount][i]);
}
rCount++;
}
// 전치 행렬 i와 j의 값 바꾸기
for (int i = 0;i < rCount;i++) {
for (int j = 0;j < cCount;j++)
sparseM[j][i] = m[i][j];
}
// original matrix, translate matrix print
printf("\n\n\nOriginal Matrix\n");
for (int i = 0;i < rCount;i++) {
for (int j = 0;j < cCount;j++)
printf("%d\t", m[i][j]);
printf("\n");
}
printf("\nTranslate Matrix\n"); // 전치 행렬은 행렬의 열값만큼 행 출력
for (int i = 0;i < cCount;i++) {
for (int j = 0;j < rCount;j++)
printf("%d\t", sparseM[i][j]);
printf("\n");
}
fclose(fp);
}
파일을 여러 번 읽는경우, rewind(fp) 함수 이용하여 파일포인터의 위치 이동시키는 것!
결과:
정답 코드:
+ 행렬의 값 초기화 할 때, 각 요소에 -1 대입
#include <stdio.h>
#define SIZE 100
int main() {
FILE* fp;
int nAr[SIZE][SIZE]; // 원본 행렬
int TransAr[SIZE][SIZE]; // 전치 행렬
int rCnt = 0, cCnt = 0; // 행과 열의 크기
char chTemp = '\0'; // 공백 문자
int nTemp;
// 파일 열기
fp = fopen("data.txt", "rt");
if (fp == NULL) {
printf("file nout found\n");
return 0;
}
// 2차원 배열 초기화 하기
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
nAr[i][j] = -1;
TransAr[i][j] = -1;
}
}
// 행의 개수를 읽어 오기
while (!feof(fp)) {
if (chTemp == '\n') // newLine 개행문자가 나오면
break; // '4\n'인 경우
fscanf(fp, "%d%c", &nTemp, &chTemp); // '1\0', '2\0 ' ... 각각 (int + space)한 쌍으로 읽음
rCnt++;
}
rewind(fp);
// data.txt 파일을 2차원 배열로 읽기
while (!feof(fp)) {
for (int i = 0; i < rCnt; i++) {
fscanf(fp, "%d", &nAr[nRow][i]);
nRow++;
}
}
// 원본 행렬 출력
printf("Original Matrix\n");
for (int i = 0; i < nRow; i++) {
for (int j = 0; j < nCount; j++)
printf("%d\t", nAr[i][j]);
printf("\n");
}
// 전치 행렬 계산
printf("Translate Matrix\n");
for (int i = 0; i < nCount; i++) {
for (int j = 0; j < nRow; j++)
printf("%d\t", TransAr[i][j]);
printf("\n");
}
return 0;
}
3. 동적 할당을 이용한 프로그래밍
내가 작성한 코드:
// 파일로부터 읽은 데이터 개수만큼 동적 할당 받아 데이터 중 최대 최소 구하기
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp;
int dataCnt = 0, cnt = 0; // 전체 데이터 개수
int* data;
// 파일 열어 데이터 읽어 데이터 개수 구하기
fp = fopen("data.txt", "rt");
if (!fp) {
printf("File not found\n");
return 0;
}
while (!feof(fp)) {
fscanf(fp, "%d", &data);
dataCnt++;
}
printf("데이터 개수: %d\n\n", dataCnt);
// 데이터 개수만큼 동적 할당, 파일 다시 읽어 배열에 저장
data = (int*)malloc(sizeof(int) * dataCnt);
rewind(fp);
printf("Input Array : \n");
while (!feof(fp)) {
fscanf(fp, "%d", &data[cnt]);
printf("%d\t", data[cnt]);
cnt++;
}
// 최대와 최소 구하기
int max = data[0], min = data[0];
for (int i = 1;i < dataCnt;i++) {
if (data[i] > max)max = data[i];
if (data[i] < min)min = data[i] ;
}
// 전체 데이터, 최대 최소 출력
printf("\n\nMax : %d\nMin : %d\n", max, min);
fclose(fp);
}
결과:
free() 메모리 반납
중대한 실수를 했다.
동적할당을 하며 사용 완료한 메모리는 꼭 운영 체제에게 반납하자...
나는 파일을 읽으면서 동시에 입력된 배열 요소들을 출력한 반면,
정답 코드에서는
데이터를 출력함과 동시에 최대 최소값에 해당하는 인덱스 값을 저장하였다.
정답 코드:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp;
int nCount = 0; // 전체 데이터 개수
int nTemp;
int* pAr;
int MaxIndex = 0, MinIndex = 0; // 최대 최소에 해당하는 인덱스 값 저장
// 파일 열어 데이터 읽어 데이터 개수 구하기
fp = fopen("data.txt", "rt");
if (!fp) {
printf("File not found\n");
return 0;
}
while (!feof(fp)) {
fscanf(fp, "%d", &nTemp);
nCount++;
}
pAr = (int*)malloc(sizeof(int) * nCount);
rewind(fp);
nCount = 0;
printf("Input Array : \n");
while (!feof(fp)) {
fscanf(fp, "%d", &pAr[nCount]);
nCount++;
}
// 화면에 루프를 돌며 배열을 출력하면서 동시에 최대 최소에 해당하는 인덱스값 구하기
printf("입력 배열 : \n");
for (int i = 0;i < nCount;i++) {
printf("%d\t", pAr[i]);
if (pAr[i] > pAr[MaxIndex])
MaxIndex = i;
if (pAr[i] < pAr[MinIndex])
MinIndex = i;
}
// 전체 데이터, 최대 최소 출력
printf("\n\nMax : %d\nMin : %d\n", pAr[MaxIndex], pAr[MinIndex]);
free(pAr);
close(fp);
}
4. 구조체 포인터 실습
scores.txt
정우람 100.0 45.9 78.5
양현종 64.8 78.9 100
박해진 82.4 93.5 88.4
추신수 99.5 43.9 88.3
박찬호 100.0 99.9 78.5
이대호 88.9 99.9 78.9
강백호 85.4 78.6 31.5
이재학 82.4 93.5 78.4
작성한 소스 코드 :
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[10];
double language;
double math;
double computer;
double total;
}STU;
int main() {
FILE* fp = NULL;
int nCount = 0;
STU* p, temp; // 구조체 포인터와 정렬할 때 필요한 임시 구조체 변수
int i, j, max; // 구조체의 total의 값대로 정렬할 때, 반복문에서 인덱스 번호를 임시로 저장할 정수 변수
char name[10];
double temLan, temMath, temCom; // 파일의 값을 임시로 읽어들일 변수
fp = fopen("scores.txt", "rt");
if (!fp) {
printf("File not found\n");
return 0;
}
// 파일의 레코드 개수 읽기 (nCount값 얻기)
while (!feof(fp)) {
fscanf(fp, "%s %lf %lf %lf",name, &temLan, &temMath, &temCom);
nCount++;
}
// 동적 메모리 할당 후, 파일로부터 입력 받고, 총점 구하기
p = (STU*)malloc(sizeof(STU) * nCount);
// 파일을 한번 읽고난 파일포인터 fp를 다시 파일의 첫부분으로 이동시킴
fseek(fp, 0, SEEK_SET);
while (!feof(fp)) {
fscanf(fp, "%s %lf %lf %lf", p->name, &(p->language), &(p->math), &(p->computer));
p->total = p->language + p->math + p->computer;
p++;
}
p -= nCount;
printf(" -----------------【 성적표 순위별 】------------------- \n\n");
printf("| 이 름\t언어\t수리\t컴퓨터\t 총점\t 등수 |\n");
printf(" ========================================================\n");
// 등수를 매겨 레코드를 정렬한 뒤 출력
for (i = 0;i < nCount;i++) {
max = i;
for (j = i + 1;j < nCount;j++) {
if (p[j].total > p[max].total)
max = j;
}
temp = p[i];
p[i] = p[max];
p[max] = temp;
printf("|%9s\t%5.1f\t%5.1f\t%5.1f\t%5.1f\t%5d |\n", p[i].name, p[i].language,
p[i].math, p[i].computer, p[i].total, i+1);
printf(" --------------------------------------------------------\n");
}
fclose(fp);
return 0;
}
728x90
반응형
'# CS Study > DS Algorithm' 카테고리의 다른 글
[자료구조] 단순 연결 리스트(Linked List) ADT + 예제들 (1) | 2021.04.14 |
---|---|
[자료구조] 단순 연결 리스트 Singly Linked List 실습 문제 - 동적 메모리 할당, 노드 생성(create), 삽입(insert), 역순 연산(reverse), 버블 정렬(bubble sort), 출력, 메모리 해제 (0) | 2021.04.13 |
[자료구조] 다항식 배열의 연산 (구조체 배열, 포인터, 다항식의 표현) (0) | 2021.04.04 |
[자료구조] 연도별 통계 프로그램 (2차원 배열, 반복문) (0) | 2021.03.15 |
[자료구조] 성적 관리 프로그램 (2차원 배열, 파일 입출력, 반복문 활용) (0) | 2021.03.14 |
Comments