실습 코드(예외처리,코드구성 등)
싱글리 링크드 리스트
-
bool empty()
-
void append(int data)
- 예외: if(empty())
- tail의 다음에다 append한다
-
void insertion(int idx)
- 예외 : if(idx == 0) 안에서 if(listSize == 0) 일때, if(idx == listSize), if(idx < 0 || idx > listSize)
- 중간에 insert할때 for문 : 조금만 돌림 for(int i=0; i <idx-1; i++)
- for문을 조금만 돌려서 insert할 노드의 직전 노드를 찾는다
-
void delection(int idx)
- 예외 : if(idx ==0) 안에서 if(listSize == 1) 일때, if(empty() || idx<0 || idx>=listSize)
- 중간의 delete할때 for문 : 삭제할 노드와 삭제할 "직전"노드를 구함
- for문이 끝났을때 삭제한 노드가 tail 노드였다면 직전노드를 tail로 설정
-
void print()
더블리 링크드 리스트
싱글리 리스트와 예외 처리문 delection 메소드 빼고 동일
delection 메소드 에 아래와 같은 예외처리 하나만 추가된다.
=> if(idx == listSize-1) : tail 노드 삭제하는 연산
- 싱글리 리스트에서 중간 삽입시에, 삭제할 노드가 tail 노드인지 물어보던 문장을 제거
배열
-
배열은 예외처리문 아예 없음!!
-
멤버변수 : int* arr, int arrSize;
-
생성자 : 배열 arr을 모두 0으로 초기화 (인덱스 0~arrSize 모두 0으로 초기화)
-
void left_shift(int count)
- int front_number = arr[0]; 생성
- 이중 for문 돌리면서 원소들을 앞으로 떙기고 맨 뒤에다 front_number 삽입
- for (int i = 1; i <= arrSize - 1; i++) arr[i-1] = arr[i];
- front_number = arr[0]; 으로 최신화
-
void right_shift(int count)
- int back_number = arr[arrSize-1]; 생성
- 이중 for문 돌리면서 원소들을 뒤로 떙기고 맨 앞에다 back_number 삽입
- for (int i = arrSize - 2; i >= 0; i--) arr[i+1] = arr[i];
- back_number = arr[arrSize-1]; 으로 최신화
-
void reverse(int idx1, int idx2)
- 배열 복사본 result에다 arr 원소 할당
- 1중 for문만 돌려도 된다.
- for(int i=0; i<= idx2-idx1; i++) result[idx1+i] = arr[idx2-i];
- arr = result
-
void add(int idx, int data)
- for문 ㅈㄴ 조금만 돌림 => for(int i=listSize-2; i >= idx; i--)
-
void remove(int idx)
- for(int i=idx+1; i <= arrSize-1; i++)
- 맨 마지막 종료 직전에, arr[arrSize-1] = 0 할당하는 것 까먹지말기!!!!!
-
void set(int idx, int data)
-
void print()
-
void find(int data)
스택(1) - 배열구현
-
멤버변수 : topIndex, capacity, int* arr
-
topIndex = -1 로 꼭 초기화할것!!
-
int size(), bool empty() 모두 topIndex 로 코드구성
-
int push()
- 예외 : if(topIndex+1 == capacity) 일때 FULL 인상태.
-
void pop(), void top()
- 예외 : if(empty())
스택(2) - 싱글리 링크드리스트 구현
-
node* topNode;
- head와 tail을 선언하지 않고 topNode 하나만 선언
-
멤버변수 : node* topNode, int listSize;
-
push, pop 모두 맨앞에서(head 위치에서) 진행
-
push 는 FULL 에 대해 따로 예외처리하지 않는다
중위표기식 -> 후위표기식(W3_P2)
-
int형을 저장하던 스택을 char형을 저장하도록 코드 수정하는거 잊지말기!!
-
CASE1) + 또는 -
- 스택에 쌓인 연산자를 "모두" 출력하며 동시에 제거한다.
- while(!stack.empty()) cout << s.top(); s.pop();
- 다 제거됐다면 스택에 str[i] 을 push!!!
- 스택에 쌓인 연산자를 "모두" 출력하며 동시에 제거한다.
-
CASE2) * 또는 /
- 스택에서 * 또는 / 가 계속 쭈르르 나올때까지 계속 출력하면서 제거한다
- while(stack.top() == '*' || stack.top() == '/') cout <<s.top(); s.pop();
- 다 제거됐다면 스택에 str[i] 를 push!!
- 스택에서 * 또는 / 가 계속 쭈르르 나올때까지 계속 출력하면서 제거한다
-
CASE3) 숫자
- 그냥 출력하면됌
- 각 연산식의 테스트케이스가 끝나기 직전에 마지막으로 스택에 잔여 연산자들을 모두 출력, 제거한다
- while(!s.empty()) cout << s.top(); s.pop();
후위표기식 -> 중위표기식(W3_P4)
-
w3_p2와 달리, 연산자 케이스를 나누지 않고 숫자와 연산자 케이스 2개로만 나눈다.
-
CASE1) str[i] == '+' 또는 '-' 또는 '*' 또는 '/'
- 스택의 상위의 숫자 2개를 변수 int num1, num2에 입력받고 연산을 진행하고 그 결과를 스택에 push한다
- "/" 와 "-" 연산의 경우 num2-num1 과 num2/num1 를 진행
-
CASE2) 숫자일때
- 스택에 push
-
테스트케이스가 끝나면, 스택에서 연산의 최종 결과물 s.top() 을 출력해준다.
- case2일때 str[i] 에서 반드시 '0' 을 빼줘서 (str[i]-'0') 문자를 숫자로 만들고 스택에 push할것!
큐(1) - 배열 구현
-
멤버 변수 : frontIndex, rearIndex, int* arr, int arrSize, int capacity
-
rearIndex 는 마지막 인덱스의 다음을 나타낸다
-
예외처리할거 특별히 없음. empty() 랑 FULL 일때만 잘 처리해주기
-
enqueue(), dequeue()
-
front()
-
rear() : return arr[rearIndex-1]; 를 리턴해주기!! rearIndex 인덱스가 아니다!!!
-
empty()
큐(2) - 싱글리 링크드 리스트 구현
-
멤버변수: node frontNode, node rearNode, int listSize;
-
enqueue
- 예외 : if(empty()) => 최초 삽입시 frontNode = rearNode = newNode; 로 초기화
- rearNode 에서 삽입이 발생
-
dequeue
- 예외 : if( listSize == 1 ), if(empty())
- frontNode 에서 삭제가 발생
-
front
- 예외 : if(empty())
카드게임(1) (W4_P2)
- 선언할 변수 : winner, p1_score, p2_score, last_score
- for문 안에서는 int player1 = q1.front(); / int player2 = q2.front(); 를 하기
- 이긴 사람에게 계속해서 채력을 추가해줌
if(player1 > player2)
{
winner = 1;
last_score = player1 - player2;
p1_score++;
}
카드게임(2) (W4_P4)
- w2_p2 에서 일부분만 수정하면 끝!
- 진 사람에게 채력을 추가해줌 (<=> w2_p2 문제는 이긴 사람에게 채력을 추가해줬음)
벡터
-
void insert(int idx, int data)
- 예외 종류
- 배열이 꽉 찼을때 reserve( ) 호출 => if ( n == capacity )
- if ( idx < 0 || idx >= n )
-
void reserve(int size) : 더블링 구현 (사이즈 2배로 늘려줌)
- int newArr = new int[size]; // 새로운 배열에 복사
- 맨 마지막에 capacity = size 로 설정하기!!
- arr = newArr;
- delete[ ] newArr;
-
void erase(int idx)
-
부수적인 메소드 : size, empty, at, set
리스트
- 멤버변수 : node header, node trailer, int listSize
- 생성자 : 반드시 header 와 trailer 에 NULL 을 할당하지 않고, new node; 를 할당하기!!!!
- begin()
- header -> next 를 리턴. => header의 "다음" 노드를 리턴!!!!!
- end()
- trailer 를 리턴
- insert
- 주어진 pos "앞에다" insert
- erase
- 예외구문 : if (pos == trailer), if (empty())
- 부가적인 메소드들
- nextP : pos가 trailer이면 그대로 있고, 아니면 pos->next 로 이동
- prevP : pos->prev가 header 이면 그대로 있고, 아니면 pos->prev 로 이동
- insertFront, insertBack, eraseFront, eraseBack
- empty, find, print
W5_P2
-
자주하는 실수 : for문 안에서 p = list.nextP(p); 하는것 까먹질말것!!!
-
for문 돌릴때 3가지 CASE 로 나눌것
-
CASE1) if(i == 0) 즉, if(p == list.begin()) 으로, 맨 처음 합을 구할때
- sum += p->data; sum += p->next->data;
-
CASE2) if(i == n-1) 즉, if(p == list.end()->prev)), 맨 마지막 합을 구할때
- sum += p->data; sum += p->prev->data;
-
CASE3) 그냥 중간에 합을 구할때
- sum += p->prev->data; sum += data; sum += p->next->data;
W5_P4
반드시!!!!!!!!!!!!!!!!!!!!!!! 리스트 사이즈가 1일때를 따로 예외처리해줄 것.
if(count == 1) // 리스트가 사이즈가 1일때
cout << 0; // 최댓값과 최솟값의 차이는 0
break; // 그 테스트케이스에 대한 반복문을 종료시킴
트리
-
노드 멤버변수 : node parent, vector<node> childList, int data
- 노드 생성자 : this->parent, this->data 값을 할당
-
find
- for문 돌려서 if(data == list[i]->data) 일때의 인덱스 i를 리턴
-
생성자
- root 노드 초기화후 nodeList에 push_back
-
void insertNode(int parData, int data)
- nodeList에다 newNode 를 push_back 해주는 것 까먹지 말것!
- 예외
- if( find (data, nodeList) != -1) => 삽입하려는 data노드가 이미 존재하는 경우
- int idx = find(parData, nodeList) / if(idx == -1) => 부모 노드가 트리에 없는 경우
-
void deleteNode(int data)
- 예외 : if(idx == -1) 2) if(delNode == root)
- 삭제할 것들 목록 3개 (부모의 childList에서, 메모리에서, nodeList에서 삭제)
// vector<node*>& child = parNode->childList;- child.erase(child.begin() + find(data, child)); // 부모의 childList에서 삭제
- delete nodeList[idx]; // 메모리에서 삭제. => delete delNode; 로 대체 가능!!!
- nodeList.erase(nodeList.begin() + idx); // nodeList에서 삭제
-
부가적인 메소드들
- printAncestors, printDepth
- if(curNode == root) 가 될때만 신경써서 처리 잘 해주기!
- printParent, printChild, maxChild
- printAncestors, printDepth
전위순회, 후위순회
- W7_P1 (전위순회)
void Tree::preOrder(node* pos, int count)
{
cout << count << ' ';
for (int i = 0; i < pos->childList.size(); i++)
{
preOrder(pos->childList[i], count + 1);
}
}
- W7_P3 (후위순회)
- W7_P1 전위순회에서 cout 출력 위치를 for문 아래로만 바꿔주면 끝이다!
void Tree::preOrder(node* pos, int count)
{
for (int i = 0; i < pos->childList.size(); i++)
{
preOrder(pos->childList[i], count + 1);
}
cout << count << ' ';
}
- W7_P2 (external 노드 개수 구하기)
int Tree::postOrder(node* pos)
{
int count = 0;
if (pos->childList.size() == 0) // external 노드인 경우
return 1;
for (int i = 0; i < pos->childList.size(); i++) // 자신의 각 자식으로 부터 계산된
{ // external 노드 개수를 합산해서 그 결과를 자신의 external 노드 개수로 만들기
count += postOrder(pos->childList[i]);
}
return count;
}
- 폴더 용량 계산하기 (W7_P4)
- 노드의 데이터 필드로 int data 외에 int folderSize; 추가
- 후위순회 진행시 return할때 count 에다 자신의 폴더용량 값(pos->size)도 추가해서 리턴 하는 것 까먹지 말기!
int Tree::postOrder(node* pos)
{
int count = 0;
if (pos->childList.size() == 0)
return pos->size;
for (int i = 0; i < pos->childList.size(); i++)
{
count += postOrder(pos->childList[i]);
}
return count + pos->size; // 각 서브트리의 용량을 sum에 모두 더했다면, 마지막에는 자신의 폴더 용량도 더해야지 총 용량이 된다.
}
void Tree::folderSize(int data, int folder)
{
int idx = find(data, nodeList);
if (idx == -1)
{
cout << -1 << endl;
return;
}
node* curNode = nodeList[idx];
curNode->size = folder;
}
Author And Source
이 문제에 관하여(실습 코드(예외처리,코드구성 등)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@msung99/실습-코드예외처리코드구성-등저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)