
#include <stdio.h>
#include <stdlib.h>
void set(int** arr, int* data, int rows, int cols) {
for (int i = 0; i < rows * cols; ++i) {
arr[((i + 1) / rows) % rows][(i + 1) % cols] = data[i];
}
}
int main() {
int rows = 3, cols = 3, sum = 0, i;
int data[] = {5, 2, 7, 4, 1, 8, 3, 6, 9};
int** arr;
arr = (int**) malloc(sizeof(int*) * rows);
for (i = 0; i < rows; i++) {
arr[i] = (int*) malloc(sizeof(int) * cols);
}
set(arr, data, rows, cols);
for (i = 0; i < rows * cols; i++) {
sum += arr[i / cols][i % cols] * (i % 2 == 0 ? 1 : -1);
}
for(i=0; i<rows; i++) {
free(arr[i]);
}
free(arr);
printf("%d", sum);
return 0;
}
🖍️ 13
data배열에 있는 값을 2차원 배열arr에 특정 방식으로 저장 (set 함수)- 저장된 배열 값을 홀수 인덱스에서는 음수, 짝수 인덱스에서는 양수로 합산
- 최종적으로
sum을 출력🧩 2차원 배열을 동적으로 할당:
arr = (int**) malloc(sizeof(int*) * rows);
arr은int포인터의 포인터, 즉int**
arr을int*배열로 만들고 싶음sizeof(int*) * rows:int*타입을rows개 만큼 메모리 할당
즉, 행(row) 개수만큼 포인터 공간을 확보arr │ ├───► arr[0] → ? ├───► arr[1] → ? └───► arr[2] → ?for (i = 0; i < rows; i++) { arr[i] = (int*) malloc(sizeof(int) * cols); }
arr[i]는 각 행에 해당하는 포인터sizeof(int) * cols: 열(col) 수만큼 정수 배열을 만듦
즉, 각 행에 실제 데이터를 저장할 공간을 할당arr │ ├───► arr[0] → [ int ][ int ][ int ] ├───► arr[1] → [ int ][ int ][ int ] └───► arr[2] → [ int ][ int ][ int ]🧩 set() 함수
void set(int** arr, int* data, int rows, int cols) { for (int i = 0; i < rows * cols; ++i) { arr[((i + 1) / rows) % rows][(i + 1) % cols] = data[i]; } }
- 행 인덱스:
((i + 1) / rows) % rows- 열 인덱스:
(i + 1) % cols
즉,i가 0부터 8까지 순회하면서,data[i]값을 위의 인덱스 계산으로arr에 넣음
🧩 최종 arr 상태:
arr = { {9, 5, 2}, {7, 4, 1}, {8, 3, 6} };🧩 sum 계산
for (i = 0; i < rows * cols; i++) { sum += arr[i / cols][i % cols] * (i % 2 == 0 ? 1 : -1); }2차원 배열을 순서대로 탐색하면서:
- 짝수 인덱스
(i % 2 == 0)→ 더함- 홀수 인덱스 → 뺌
➡︎
9 - 5 + 2 - 7 + 4 - 1 + 8 - 3 + 6 = 13
① 다른 모듈 내부에 있는 변수나 기능을 다른 모듈에서 사용하는 경우의 결합도
② 모듈 간의 인터페이스로 배열이나 오브젝트, 자료구조 등이 전달되는 경우의 결합도
③ 파라미터가 아닌 모듈 밖에 선언되어 있는 전역 변수를 참조하고 전역 변수를 갱신하는 식으로 상호작용하는 경우의 결합도
🖍️ ① 내용 결합도 ② 스템프 결합도 ③ 공통 결합도
상속(Inheritance), 메서드 오버라이딩(Method Overriding), 정적 변수(Static Variable), 변수 숨김(Variable Shadowing)
class parent{
static int total = 0;
int v = 1;
public parent(){
total += (++v);
show();
}
public void show(){
total += total;
}
}
class child extends parent{
int v = 10;
public child(){
v += 2;
total += v++;
show();
}
@Override
public void show(){
total += total*2;
}
}
class Main {
public static void main(String[] args) {
new child();
System.out.println(parent.total);
}
}
🖍️ 54
🩵 코드 시작:
new child();1️⃣ 먼저 parent 생성자가 실행
int v = 1; ++v; // v는 2가 됨 total += v; // total = 0 + 2 = 2 show(); // 여기서 child의 show()가 호출됨⚠️ 중요 포인트
show()는parent클래스의 메서드처럼 보이지만,child클래스에서 오버라이딩했기 때문에, 실제로는child의show()가 실행됨// child의 show() 실행 total += total * 2; // 2 + (2 * 2) = 6
total= 62️⃣ child 생성자가 실행
int v = 10; // child의 v (부모 v와는 다른 변수) v += 2; // v는 12 total += v++; // total = 6 + 12 = 18, v는 13이 됨 show(); // 다시 child의 show() 실행total += total * 2; // 18 + (18 * 2) = 54🔚 최종 결과
System.out.println(parent.total); // 결과: 54
- 동적 바인딩으로 인해 부모 생성자에서도 자식의 메서드가 호출됨
static변수 덕분에 값이 누적되어 최종적으로 54가 출력됨
🖍️ adapter
정확하지 않음
int main() {
int a = 0;
while (조건문) {
if (B[a] < 0)
B[a] = -B[a];
a++;
}
return(1);
}
🖍️
순서: ➊→➋→➌→➍→➎→➋→➏
흐름도 구성 노드
[Start] --> [a = 0] | v [➊ while (조건문)] <------------------------ / \ | No Yes | | | | [➋ return 1] v | [➌ if (조건문)] | / \ | No Yes | | | | | v | | [➍ B[a] = -B[a]] | \ / | | | [➎ a++] ----------------------- | [➏ return 1]
public class Main {
static int comp(int[] a, int st, int end) {
if (st >= end) return 0;
int mid = (st + end) / 2;
return a[mid] + Math.max(comp(a, st, mid), comp(a, mid + 1, end));
}
public static void main(String[] args) {
int[] values = {3, 5, 8, 12, 17};
System.out.println(comp(values, 0, values.length - 1));
}
}
🖍️ 20
🧩 main 함수
public static void main(String[] args) { int[] values = {3, 5, 8, 12, 17}; System.out.println(comp(values, 0, values.length - 1)); }
comp함수는values배열을0부터values.length - 1(즉, 0부터 4까지)까지의 범위로 분할하여 실행comp함수는 재귀적으로 배열을 나누고, 각 부분에서 가장 큰 값을 구해 반환🧩 comp 함수
static int comp(int[] a, int st, int end) { if (st >= end) return 0; int mid = (st + end) / 2; return a[mid] + Math.max(comp(a, st, mid), comp(a, mid + 1, end)); }
comp함수는 배열a와 인덱스st(start)와end(end)를 인자로 받아서 부분 배열의 합을 구하고, 그 중에서 최대값을 반환하는 함수
- 재귀 종료 조건:
st >= end이면 0을 반환, 이 조건은 배열의 크기가 1 이하일 때 재귀가 종료- 분할: 배열을 두 부분으로 나눔,
mid는 배열의 중간 인덱스- 부분합 계산:
comp(a, st, mid)는st부터mid까지의 부분 배열을 처리하고,comp(a, mid + 1, end)는mid + 1부터end까지의 부분 배열을 처리- 최대값 구하기: 두 부분의 결과를 비교한 후 더 큰 값을 선택하고,
a[mid]값을 더해 최종 결과를 계산✅ comp(values, 0, 4) 실행 흐름 표
comp(0,4) → 8+12 ├── comp(0,2) → a[1]+3+0 = 8 │ ├── comp(0,1) → a[0]+0+0 = 3 │ │ ├── comp(0,0) → 0 │ │ └── comp(1,1) → 0 │ └── comp(2,2) → 0 ├── comp(3,4) → a[3]+0+0 = 12 │ ├── comp(3,3) → 0 │ └── comp(4,4) → 0
class TreeNode:
def __init__(self, value):
self.value = value
self.children = []
def build_tree(li):
nodes = [TreeNode(i) for i in li]
for i in range(1, len(li)):
nodes[(i - 1) // 2].children.append(nodes[i])
return nodes[0]
def calc(node, level=0):
return node.value if level % 2 else 0 + sum(calc(n, level + 1) for n in node.children) if node else 0
li = [3, 5, 8, 12, 15, 18, 20]
root = build_tree(li)
print(calc(root))
🖍️ 13
🩵 클래스 TreeNode 정의
class TreeNode: def __init__(self, value): self.value = value self.children = []
TreeNode클래스는 트리의 각 노드를 나타냄__init__(): 노드의 값을 설정, 자식 노드들을 담을children리스트를 초기화🩵 build_tree 함수
def build_tree(li): nodes = [TreeNode(i) for i in li] for i in range(1, len(li)): nodes[(i - 1) // 2].children.append(nodes[i]) return nodes[0]
build_tree함수는 입력 리스트li를 이용해 트리를 만듦
먼저,li의 각 값에 대해TreeNode인스턴스를 만들어nodes리스트에 저장- 이후
for루프를 통해 각 노드의 부모 노드를 찾아서 자식으로 추가
nodes[(i - 1) // 2]는 현재 노드i의 부모 노드를 가리킴- 예를 들어,
i = 1일 때,(i - 1) // 2 = 0으로, 노드 1의 부모는 노드 0- 마지막으로 트리의 루트 노드(
nodes[0])를 반환
🌳 결과 트리 구조
nodes[0]: 3 ├── nodes[1]: 5 │ ├── nodes[3]: 12 │ └── nodes[4]: 15 └── nodes[2]: 8 ├── nodes[5]: 18 └── nodes[6]: 20🩵 calc 함수
calc함수는 트리의 각 노드를 깊이 우선 탐색(DFS) 방식으로 순회하며 계산한다.def calc(node, level=0): return node.value if level % 2 else 0 + sum(calc(n, level + 1) for n in node.children) if node else 0
level=0: 루트(시작점)level: 현재 노드가 트리의 몇 번째 레벨인지를 나타냄🔍 핵심: 조건부 삼항 연산자
return ( node.value if level % 2 # 👉 레벨이 홀수면 자기 값 반환 else 0 + sum(...) # 👉 짝수면 자기 값 무시하고 자식 노드들의 결과만 합침 if node # 👉 node가 None이면 무조건 0 반환 else 0 )
- True = 1 / False = 0
node.value: 현재 노드 값- 기본적으로, 노드의 값은 깊이에 따라 다르게 처리됨
level % 2 == 1: 홀수,node.value+ 자식들 합level % 2 == 0: 짝수, 자신의 값은 무시 + 자식들 합sum(calc(n, level + 1) for n in node.children)
현재 노드의 모든 자식 노드들에 대해calc()를 호출해서 합산, 재귀 호출node == None일 경우, 0을 반환nodes[0]: 3 → 무시 ├── nodes[1]: 5 → 포함 │ ├── nodes[3]: 12 → 무시 │ └── nodes[4]: 15 → 무시 └── nodes[2]: 8 → 포함 ├── nodes[5]: 18 → 무시 └── nodes[6]: 20 → 무시
🩵 실행
li = [3, 5, 8, 12, 15, 18, 20] root = build_tree(li) print(calc(root))3 / \ 5 8 / \ / \ 12 15 18 20
- 5 + 8 = 13
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value;
struct Node *next;
} Node;
Node* createNode(Node* head, int value) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->value = value;
new_node->next = head;
return new_node;
}
Node* reconnect(Node* head, int disconnect_count) {
Node *prev = NULL, *curr = head;
while (curr && curr->value != disconnect_count) {
prev = curr;
curr = curr->next;
}
if (!curr || curr == head) return head;
prev->next = curr->next;
curr->next = head;
head = curr;
return head;
}
int main() {
Node *head = NULL, *curr, *temp;
for (int i = 1; i <= 5; i++)
head = createNode(head, i);
head = reconnect(head, 3);
for (curr = head; curr != NULL; curr = curr->next)
printf("%d", curr->value);
// 메모리 해제
curr = head;
while (curr != NULL) {
temp = curr;
curr = curr->next;
free(temp);
}
return 0;
}
🖍️ 35421
🧩 구조체 정의
typedef struct Node { int value; struct Node *next; } Node;
Node라는 이름의 구조체를 정의value: 노드가 가지고 있는 값 (int형).next: 다음 노드를 가리키는 포인터, 이 포인터를 통해 연결된 리스트를 구성🧩 새 노드 생성 함수
Node* createNode(Node* head, int value) { Node* new_node = (Node*)malloc(sizeof(Node)); new_node->value = value; new_node->next = head; return new_node; }
createNode()함수는 새로운 노드를 생성하여 리스트의 맨 앞에 추가하는 함수
malloc을 사용하여 새로운 Node를 동적으로 할당- 할당된 새로운 노드의
value를 주어진value로 설정- 새로운 노드의
next는 현재의head를 가리키도록 설정하여, 리스트의 맨 앞에 이 노드를 추가- 함수는 생성된
new_node를 반환🧩 연결 리스트에서 특정 노드를 맨 앞으로 이동시키는 함수
Node* reconnect(Node* head, int disconnect_count) { Node *prev = NULL, *curr = head; ... }
reconnect함수는 특정 값(disconnect_count)을 가진 노드를 리스트에서 찾아 맨 앞으로 이동시키는 함수
prev: 현재 노드의 이전 노드를 가리키는 포인터curr: 현재 노드를 가리키는 포인터, 초기에는head로 설정됨while (curr && curr->value != disconnect_count) { prev = curr; curr = curr->next; }
while루프를 통해 리스트를 탐색하여disconnect_count값과 일치하는 노드를 찾음
prev는 항상curr의 이전 노드를 추적curr는 현재 노드를 추적if (!curr || curr == head) return head;
curr이NULL이면 값을 찾지 못한 경우이고,curr == head이면 이미 맨 앞에 있는 경우- 그런 경우에는 아무것도 하지 않고
head를 그대로 반환prev->next = curr->next; curr->next = head; head = curr;
prev->next = curr->next:prev노드의next가curr의next를 가리키도록 하여curr노드를 리스트에서 분리curr->next = head:curr노드를 리스트의 맨 앞에 추가하기 위해curr->next를 기존head로 설정head = curr:head를curr로 변경하여 리스트의 첫 번째 노드를curr로 설정head ↓ [5] → [4] → [3] → [2] → [1] → NULL ↑ ↑ prev curr head ↓ [5] → [4] → [3] → [2] → [1] → NULL ↑ ↑ prev curr • prev->next = curr->next → 4 → 2 • curr->next = head → 3 → 5 • head = curr → 새로운 head는 3🧩 main 함수
int main() { Node *head = NULL, *curr, *temp; for (int i = 1; i <= 5; i++) head = createNode(head, i); ... }
Node *head = NULL: 리스트의 헤드를 NULL로 초기화(빈 리스트)for (int i = 1; i <= 5; i++): 1부터 5까지 숫자를 가진 노드들을 생성하여 연결 리스트를 만듦createNode함수를 사용하여 각 숫자에 대한 노드를 리스트의 맨 앞에 추가
결과적으로head는5 -> 4 -> 3 -> 2 -> 1로 초기화됨head = reconnect(head, 3);
- 3을 리스트에서 찾아서 맨 앞에 이동시킴
- 결과적으로 리스트는
3 -> 5 -> 4 -> 2 -> 1for (curr = head; curr != NULL; curr = curr->next) printf("%d", curr->value);
- 리스트의 모든 값을 출력하는 루프
head부터 시작하여 각 노드를 출력
🧩 메모리 해제
curr = head; while (curr != NULL) { temp = curr; curr = curr->next; free(temp); }동적으로 할당한 메모리를 해제하는 코드
curr는 리스트의 현재 노드를 가리키고,temp는 메모리 해제를 위한 임시 포인터curr를 리스트를 따라 이동시키면서, 각 노드의 메모리를free함수로 해제free(temp)로curr가 가리키는 노드를 해제한 후,curr을 다음 노드로 이동시킴
#include <stdio.h>
typedef struct student {
char* name;
unsigned int score[3];
} Student;
int dec(int enc) {
return enc & 0xA5;
}
int sum(Student* p) {
return dec(p->score[0]) + dec(p->score[1]) + dec(p->score[2]);
}
int main() {
Student s[2] = { "Kim", {0xF0, 0xF5, 0xDB}, "Lee", {0xED, 0xD3, 0xF2} };
Student* p = s;
int result = 0;
for (int i = 0; i < 2; i++) {
result += sum(&s[i]);
}
printf("%d", result);
return 0;
}
🖍️ 908
🧩 구조체 정의
typedef struct student { char* name; int score[3]; } Student;
Student구조체는 학생의 이름과 점수 3개를 저장score[3]배열은 3개의 정수 점수를 저장
다만, 이 점수는 인코딩된 형태🧩 디코딩 함수
int dec(int enc) { return enc & 0xA5; }
&연산자는 비트AND연산0xA5는 16진수로 10100101- 즉, 인코딩된 점수에서 특정 비트만 남겨서 "디코딩"하는 역할
Kim: 0xF0(11110000)` & 0xA5(10100101) = 0xA0(10100000) = 160 0xF5(11110101) & 0xA5 = 0xA5 = 165 0xDB & 0xA5 = 0x81 = 129 → Kim의 총합: 160 + 165 + 129 = 454 Lee: 0xED & 0xA5 = 0xA5 = 165 0xD3 & 0xA5 = 0x81 = 129 0xF2 & 0xA5 = 0xA0 = 160 → Lee의 총합: 165 + 129 + 160 = 454🧩 합산 함수
int sum(Student* p) { return dec(p->score[0]) + dec(p->score[1]) + dec(p->score[2]); }
- 특정 학생 포인터
p의 세 점수를 디코딩해서 더함🧩 main 함수
for (int i = 0; i < 2; i++) { result += sum(&s[i]); } printf("%d", result);
result=sum[0] + sum[1]= 454 + 454 = 908
public class Main {
public static void main(String[] args) {
System.out.println(calc("5"));
}
static int calc(int value) {
if (value <= 1) return value;
return calc(value - 1) + calc(value - 2);
}
static int calc(String str) {
int value = Integer.valueOf(str);
if (value <= 1) return value;
return calc(value - 1) + calc(value - 3);
}
}
🖍️ 4
🩵 main()
public class Mian { public static void main(String[] args) { System.out.println(calc("5")); }
main()함수에서 "5"라는 문자열을calc()함수에 넘김- 문자열이므로 호출되는 건
calc(String str)🩵 메서드 오버로딩 (Overloading)
static int calc(String str) { int value = Integer.valueOf(str); if (value <= 1) return value; return calc(value - 1) + calc(value - 3); }
Integer.valueOf(str);: 문자열을 정수로 변환- 재귀적으로
calc(int)를 호출! (value - 1, value - 3)- ⚠️ 주의: 여기서 호출되는
calc(value - 1) + calc(value - 3)은int버전의calc()🔍 동작 순서 분석
"5" → calc(String) 호출됨 value = 5 calc(5 - 1) + calc(5 - 3) = calc(4) + calc(2)📌 calc(4) - static int calc(int value)
calc(4 - 1) + calc(4 - 2) = calc(3) + calc(2) = (calc(2) + calc(1)) + (calc(1) + calc(0)) = ((calc(1) + calc(0)) + 1) + (1 + 0) = ((1 + 0) + 1) + (1 + 0) = (1 + 1) + 1 = 2 + 1 = 3📌 calc(2) - static int calc(int value)
calc(2 - 1) + calc(2 - 2) calc(1) + calc(0) = 1 + 0 = 1🩵 최종 결과
calc("5") = calc(4) + calc(2) = 3 + 1 = 4