strcpy_s()
로 수정개행 문자
? 텍스트의 한줄이 끝남을 표시하는 문자/문자열 (= newline, EOL)
CRLF
LF
(CR
에서 변경, 강의자료는 CR
기준) Command-line argument
? main
함수가 가지는 parameter
int main(int argc, char** argv)
argc
: command line argument의 수argv
: char의 이중 포인터 => char[]의(string) 포인터Redefinition problem
: 같은 헤더 파일을 여러 개의 소스파일에서 include 시키는 경우 재정의 에러 발생
#ifndef
#pragma once
강의자료는 맥(CR) → 윈도우, 실습은 윈도우 → 맥(LF)
교재
: 리스트에 삭제할 아이템, one & only 존재
void UnsortedType::DeleteItem(ItemType item) {
location = 0;
while(item.ComparedTo(info[location]) != EQUAL)
location++;
info[loaction] = info[length - 1];
length--;
}
(a)
: 삭제할 item이 리스트에 존재하지 않는 경우 리스트 변경X
(교재의 코드에선 while 무한 루프 에러 → 검색횟수 제한)
void UnsortedType::DeleteItem(ItemType item) {
for (int location=0; location<length; location++){ //검색횟수 제한
if (item.ComparedTo(info[location] == EQUAL){
info[location] = info[length - 1];
length;
return; //같은 값 찾고 삭제하면 반복문 종료
}
}
(c)
: 삭제할 item과 같은 리스트의 모든 item 삭제
void UnsortedType::DeleteItem(ItemType item) {
int location = 0;
while (location < length) { //검색횟수 제한
if (item.ComparedTo(info[location]) == EQUAL){
info[location] = info[length - 1];
length--;
}
else
location++;
}
}
void SortedType::GetNextItem(ItemType& item)
{
currentPos++;
item = info[currentPos];
}
void SortedType::ResetList()
{
currentPos = -1;
}
MergeList(SortedType list1, SortedType list2, SortedType& result) {
list1.ResetList(); //GetNextItem() 위해 초기화
list2.ResetList();
result.ResetList(); //result 초기화 안하면 오류남
int length1 = list1.LengthIs(); //list1의 길이
int length2 = list2.LengthIs(); //list2의 길이
ItemType item;
//insert시 자동 정렬
for (int i=0; i<length1; i++) {
list1.GetNextItem(item); //item = info[0]
result.InsertItem(item);
}
for (int i=0; i<length2; i++) {
list2.GetNextItem(item); //item = info[0]
result.InsertItem(item);
}
int BinarySearchA(int array[], int sizeOfArray, int value) {
int midPoint;
int first = 0;
int last = sizeOfArray - 1;
bool found = false;
while (first <= last) { //검색 횟수 제한
midPoint = (first + last) / 2;
if (array[midPoint] == value) { //찾은 경우 break
found = true;
break;
}
else if (array[midPoint] > value)
last = midPoint - 1;
else if (array[midPoint] < value)
first = midPoint + 1;
}
if (found)
return midPoint; //배열에서 value의 index
else
return -1;
}
int BinarySearchB(int array[], int sizeOfArray, int value) {
int midPoint;
int first = 0;
int last = sizeOfArray - 1;
bool found = false;
while (first <= last) { //검색 횟수 제한
midPoint = (first + last) / 2;
if (array[midPoint] == value) { //찾은 경우 break
found = true;
break;
}
else if (array[midPoint] > value)
last = midPoint - 1;
else if (array[midPoint] < value)
first = midPoint + 1;
}
if (found)
//찾은 경우 -> 같은 값 리턴
return array[midPoint];
else
//찾지 못한 경우 -> 작은 값들 중 가장 큰 값 리턴 -> value-1에 대해 재귀
return BinarySearchB(array, sizeOfArray, value-1);
}
int BinarySearchC(int array[], int sizeOfArray, int value) {
int midPoint;
int first = 0;
int last = sizeOfArray - 1;
bool found = false;
while (first <= last) { //검색 횟수 제한
midPoint = (first + last) / 2;
if (array[midPoint] == value) { //찾은 경우 break
found = true;
break;
}
else if (array[midPoint] > value)
last = midPoint - 1;
else if (array[midPoint] < value)
first = midPoint + 1;
}
if (found)
//찾은 경우 -> 같은 값 리턴
return array[midPoint];
else
//찾지 못한 경우 -> 큰 값들 중 가장 작은 값 리턴 -> value+1에 대해 재귀
return BinarySearchB(array, sizeOfArray, value+1);
}
bool HouseType::operator<(HouseType house) const {
if (lastName < house.lastName)
return true;
else if (house.lastName < lastName)
return false;
else if (firstName < house.firstName)
return true;
else if (house.firstName < firstName)
return false;
else //같은 경우
return false;
}
bool HouseType::operator==(HouseType house) const {
if (lastName == house.lastName)
return true;
else
return false;
}
template<class ItemType>
StackType<ItemType>::StackType()
{
top = -1;
}
template<class ItemType>
void StackType<ItemType>::Push(ItemType newItem)
{
if (IsFull())
throw FullStack();
items[top] = newItem;
top++;
}
template<class ItemType>
void StackType<ItemType>::Pop()
{
if( IsEmpty() )
throw EmptyStack();
top--;
}
template<class ItemType>
ItemType StackType<ItemType>::Top()
{
if (IsEmpty())
throw EmptyStack();
return items[top];
}
#include <iostream>
#include "StackType.h"
using namespace std;
int main()
{
StackType<int> stack;
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
stack.Push(5);
stack.Push(6);
while (!stack.IsEmpty()) {
int top = stack.Top();
stack.Pop();
cout << top << endl;
}
}
template<class ItemType>
//기존 stack: reference로 안 받음
//copyStack: reference로 받음
void Copy(StackType<ItemType> stack, StackType<ItemType>& copyStack)
{
StackType<ItemType> tempStack;
while (!stack.IsEmpty()) {
ItemType item = stack.Top();
tempStack.Push(item);
stack.Pop(); //referenceX -> 함수 종료되면 기존 stacK에 영향 x
}
while (!tempStack.IsEmpty()) {
ItemType item = tempStack.Top();
copyStack.Push(item);
tempStack.Pop();
}
}
const int MAX_ITEMS = 200;
class DoubleStack
{
private:
int top_small; //1000 이하의 수 저장하는 스택의 top
int top_big; //1000 초과의 수 저장하는 스택의 top
int items[MAX_ITEMS];
public:
DoubleStack() : top_small(-1), top_big(200) {} //생성자
void Push(int item);
void Print();
};
void DoubleStack::Push(int item) {
if (item <= 1000) {
top_small++;
items[top_small] = item;
}
else if (item > 1000) {
top_big--;
items[top_big] = item;
}
}
void DoubleStack::Print() { //top부터 출력
for (int i = top_small; i >= 0; i--) {
cout << items[i] << ' ';
}
cout << endl;
for (int i = top_big; i < MAX_ITEMS; i++) {
cout << items[i] << ' ';
}
cout << endl;
}
void ReplaceItemA(StackType& stack, int oldItem, int newItem) {
StackType tempStack; //임시스택
while (!stack.IsEmpty()) {
if (stack.Top() == oldItem)
tempStack.Push(newItem);
else
tempStack.Push(stack.Top());
stack.Pop();
}
while (!tempStack.IsEmpty()) {
stack.Push(tempStack.Top());
tempStack.Pop();
}
}
//top은 인덱스니까 +1
void StackType::ReplaceItemB(int oldItem, int newItem) {
for (int i = 0; i < top+1; i++) {
if (items[i] == oldItem)
items[i] = newItem;
}
}
void ReplaceItemA(QueType& queue, int oldItem, int newItem) {
QueType tempQue; //임시큐 선언
//queue는 Enqueue & Dequeue 과정에서 순서가 뒤집히진 않지만,
//클라이언트 함수이므로 queue의 멤버 변수에 직접적으로 접근할 수 없기 때문에
//임시큐 필요
int item;
while (!queue.IsEmpty()) {
queue.Dequeue(item);
if (item == oldItem)
tempQue.Enqueue(newItem);
else
tempQue.Enqueue(item);
}
while (!tempQue.IsEmpty()) {
tempQue.Dequeue(item);
queue.Enqueue(item);
}
}
void QueType::ReplaceItemB(ItemType oldItem, ItemType newItem) {
//circular니까 case 나눠서
if (rear > front) {
for (int i = front+1; i <= rear; i++) { //front가 가리키고 있는 건 reserved 공간이니까
if (items[i] == oldItem)
items[i] = newItem;
}
}
else if (rear < front) { //rear == front인 경우는 empty
for (int i = (front+1)%maxQue; i <= rear+maxQue; i++) {
if (items[i] == oldItem)
items[i] = newItem;
}
}
}
bool IdenticalA(QueType& queue1, QueType& queue2) {
int item1, item2;
while (!queue1.IsEmpty() && !queue2.IsEmpty()) {
queue1.Dequeue(item1);
queue2.Dequeue(item2);
if (item1 == item2)
continue;
else
return false; //queue 내부에 서로 다른 아이템이 있는 경우 false
}
if (queue1.IsEmpty() && queue2.IsEmpty())
return true; //queue 내부에 서로 다른 아이템이 없고 두 queue의 길이가 같은 경우
else
return false; //두 queue의 길이가 다른 경우
}
bool QueType::IdenticalB(QueType& queue) {
ItemType item;
if (rear > front) {
for (int i = front + 1; i <= rear; i++) {
if (!queue.IsEmpty()) {
queue.Dequeue(item);
if (items[i] != item)
return false;
}
}
}
else if (rear < front) { //rear == front인 경우는 empty
for (int i = (front + 1) % maxQue; i <= rear + maxQue; i++) {
if (!queue.IsEmpty()) {
queue.Dequeue(item);
if (items[i] != item)
return false;
}
}
}
return true;
}
int LengthA(QueType queue) {
QueType tempQue;
int item;
int length = 0;
while (!queue.IsEmpty()) {
queue.Dequeue(item);
length++;
}
return length;
}
int QueType::LengthB() {
int length;
if (front > rear)
length = rear - front + maxQue;
else
length = rear - front;
return length;
}
QueType::QueType(int max)
{
maxQue = max;
front = 0;
rear = maxQue-1;
items = new ItemType[maxQue];
length = 0;
}
QueType::QueType()
{
maxQue = 500;
front = 0;
rear = maxQue-1;
items = new ItemType[maxQue];
}
void QueType::MakeEmpty()
{
front = 0;
rear = maxQue-1;
}
bool QueType::IsEmpty() const
{
return (length == 0);
}
bool QueType::IsFull() const
{
return (length == maxQue);
}
void QueType::Enqueue(ItemType newItem)
{
if (IsFull())
throw FullQueue();
else{
length++;
rear = (rear +1) % maxQue;
items[rear] = newItem;
}
}
void QueType::Dequeue(ItemType& item)
{
if (IsEmpty())
throw EmptyQueue();
else
{
front = (front + 1) % maxQue;
item = items[front];
length--;
}
}
int QueType::LengthIs() {
return length;
}
int minumum_pos
멤버 변수로 선언코드를 입력하세요
초기화되어 있는 스택(조건)의 모든 oldItem을 newItem으로 치환
클라이언트 함수
void ReplaceItemA(StackType& stack, ItemType oldItem, ItemType newItem) {
StackType tempStack; // 백업용 스택
ItemType topItem; // top 받는 아이템
while (!stack.IsEmpty()){
topItem = stack.Top();
stack.Pop();
if (topItem == oldItem)
tempStack.Push(newItem);
else
tempStack.Push(topItem);
}
while (!tempStack.IsEmpty()) {
topItem = tempStack.Top();
tempStack.Pop();
stack.Push(topItem);
}
}
void StackType::ReplaceItemB(ItemType oldItem, ItemType newItem) {
// 함수 설명: 링크 구조로 연결되어 있는 노드들을 top에서부터 시작하여 하나씩 검사해 가며
// olditem 값과 같은 아이템을 newitem으로 변경
NodeType* location = topPtr; // 현재 노드를 가리키기 위한 포인터 선언 및 초기화
while (location != NULL) {
if (location->info == oldItem) {
location->info = newItem; //교체
location = location->next;
}
else
location = location->next;
}
}
template <class ItemType>
void ReplaceItemA(QueType<ItemType>& queue, ItemType oldItem, ItemType newItem) {
//값 변경하고 돌려줘야 하니까 &
QueType<int> tempQue;
ItemType item;
while (!queue.IsEmpty()) {
queue.Dequeue(item);
if (item == oldItem)
tempQue.Enqueue(newItem);
else
tempQue.Enqueue(item);
}
while (!tempQue.IsEmpty()) {
tempQue.Dequeue(item);
queue.Enqueue(item);
}
}
template <class ItemType>
void QueType<ItemType>::ReplaceItemB(ItemType oldItem, ItemType newItem) {
NodeType<ItemType>*;location; //node 가리키는 포인터 ptr 선언
location = front; // 초기화
while (location != NULL) { //rear->next == NULL
if (location->info == oldItem) {
location->info = newItem;
location = location->next;
}
else
location = location->next;
}
}
SortedType (정렬 리스트는 오름차순으로 정렬되어 있음)
클라이언트 함수
template <class ItemType>
void MergeListsA(SortedType<ItemType>& listA, SortedType<ItemType>& listB, SortedType<ItemType>& result) {
ItemType itemA;
ItemType itemB;
listA.ResetList(); // currentPos = NULL로 초기화
listB.ResetList(); // currentPos = NULL로 초기화
//sortedList는 insert 과정에서 자동 정렬
for (int i = 0; i < listA.LengthIs(); i++) {
listA.GetNextItem(itemA);
result.InsertItem(itemA);
}
for (int i = 0; i < listB.LengthIs(); i++) {
listB.GetNextItem(itemB);
result.InsertItem(itemB);
}
}
멤버 함수
template <class ItemType>
void SortedType<ItemType>::MergeListsB(SortedType<ItemType>& other, SortedType<ItemType>& result) {
NodeType<ItemType>* ptr1 = listData;
NodeType<ItemType>* ptr2 = other.listData;
while (ptr1 != NULL && ptr2 != NULL) {
//ptr1 NULL 아니고 ptr2도 NULL 아닐 때 -> 하나라도 NULL 이면 나옴
result.InsertItem(ptr1->info);
result.InsertItem(ptr2->info);
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
//두 리스트의 길이가 다를 때, 긴 쪽을 뒤에 붙이는 예외 처리
if (ptr1 != NULL) { //ptr2는 null인데 ptr1은 null 아님 -> ptr2가 더 짧아서 먼저 끝남
while (ptr1 != NULL) {
result.InsertItem(ptr1->info);
ptr1 = ptr1->next;
}
}
else if(ptr2 != NULL) { //ptr1는 null인데 ptr2은 null 아님 -> ptr1가 더 짧아서 먼저 끝남
while (ptr2 != NULL) {
result.InsertItem(ptr2->info);
ptr2 = ptr2->next;
}
}
}
UnsortedType (결과 Unsorted List)
클라이언트 함수
template <class ItemType>
void MergeListsC(UnsortedType<ItemType>& listA, UnsortedType<ItemType>& listB, UnsortedType<ItemType>& result) {
ItemType itemA;
ItemType itemB;
listA.ResetList(); // currentPos = NULL로 초기화
listB.ResetList(); // currentPos = NULL로 초기화
for (int i = 0; i < listA.LengthIs(); i++) {
listA.GetNextItem(itemA);
result.InsertItem(itemA);
}
for (int i = 0; i < listB.LengthIs(); i++) {
listB.GetNextItem(itemB);
result.InsertItem(itemB);
}
}
멤버 함수
void UnsortedType<ItemType>::MergeListsD(UnsortedType<ItemType>& other, UnsortedType<ItemType>& result) {
NodeType<ItemType>* ptr1 = listData;
NodeType<ItemType>* ptr2 = other.listData;
while (ptr1 != NULL) {
result.InsertItem(ptr1->info);
ptr1 = ptr1->next;
}
while (ptr2 != NULL) {
result.InsertItem(ptr2->info);
ptr2 = ptr2->next;
}
}
교재
: 리스트에 아이템이 반드시 존재하는 것을 전제로 함
→ 존재하지 않을 경우 무한 루프 에러
(A)
: 존재하지 않는 아이템을 삭제할 경우 발생하는 오류 수정 (preLoc & location 이용)
template <class ItemType>
void UnsortedType<ItemType>::DeleteItemA(ItemType item) {
NodeType<ItemType>* predLoc = NULL; //이전 노드 가리키는 포인터
NodeType<ItemType>* location = listData; //현재 노드 가리키는 포인터
NodeType<ItemType>* tempLocation; //delete 위한 포인터
if (item == listData->info)
{
tempLocation = location;
listData = listData->next; // Delete first node. (listData->next == NULL)
delete tempLocation;
length--;
}
else {
while (location != NULL) { //같지 않으면 location 업데이트
if (item != (location->info)) {
predLoc = location;
location = location->next;
if (location == NULL)
cout << "존재 x" << endl;
}
else { //같으면 삭제
tempLocation = location;
predLoc->next = location->next;
location = location->next;
delete tempLocation;
length--;
}
}
}
}
template <class ItemType>
void UnsortedType<ItemType>::DeleteItemB(ItemType item)
{
NodeType<ItemType>* predLoc = NULL; //이전 노드 가리키는 포인터
NodeType<ItemType>* location = listData; //현재 노드 가리키는 포인터
NodeType<ItemType>* tempLocation; //delete 위한 포인터
if (item == listData->info)
{
tempLocation = location;
listData = listData->next; // Delete first node. (listData->next == NULL)
delete tempLocation;
length--;
}
else {
while (location != NULL) { //같지 않으면 location 업데이트
if (item != (location->info)) {
predLoc = location;
location = location->next;
}
else { //같으면 삭제
tempLocation = location;
predLoc->next = location->next;
location = location->next;
delete tempLocation;
length--;
}
}
}
}
근데 너무 슬프게도... 다 잘 되는데... 마지막 아이템 & 바로 이전 아이템이 중복인 경우 마지막 아이템이 삭제되지 않는 오류가 발생한다 왤까...?!?! 난 정말 맞게 짠 것 같은데...🥲
교재
: 리스트에 아이템이 반드시 존재하는 것을 전제로 함
→ 존재하지 않을 경우 무한 루프 에러
(A)
: 존재하지 않는 아이템을 삭제할 경우 발생하는 오류 수정 (preLoc & location) 이용
template <class ItemType>
void SortedType<ItemType>::DeleteItemA(ItemType item)
// Pre: item's key has been initialized.
// An element in the list has a key that matches item's.
// Post: No element in the list has a key that matches item's.
{
NodeType<ItemType>* predLoc = NULL; //이전 노드 가리키는 포인터
NodeType<ItemType>* location = listData; //현재 노드 가리키는 포인터
NodeType<ItemType>* tempLocation; //delete 위한 포인터
if (item == listData->info)
{
tempLocation = location;
listData = listData->next; // Delete first node. (listData->next == NULL)
delete tempLocation;
length--;
}
else {
while (location != NULL) { //같지 않으면 location 업데이트
if (item != (location->info)) {
predLoc = location;
location = location->next;
if (location == NULL)
cout << "존재 x" << endl;
}
else { //같으면 삭제
tempLocation = location;
predLoc->next = location->next;
location = location->next;
delete tempLocation;
length--;
return;
}
}
}
}
template <class ItemType>
void SortedType<ItemType>::DeleteItemB(ItemType item){
// Pre: item's key has been initialized.
// An element in the list has a key that matches item's.
// Post: No element in the list has a key that matches item's.
NodeType<ItemType>* predLoc = NULL; //이전 노드 가리키는 포인터
NodeType<ItemType>* location = listData; //현재 노드 가리키는 포인터
NodeType<ItemType>* tempLocation; //delete 위한 포인터
if (item == listData->info)
{
tempLocation = location;
listData = listData->next; // Delete first node. (listData->next == NULL)
delete tempLocation;
length--;
}
else {
while (location != NULL) { //같지 않으면 location 업데이트
if (item != (location->info)) {
predLoc = location;
location = location->next;
}
else { //같으면 삭제
tempLocation = location;
predLoc->next = location->next;
location = location->next;
delete tempLocation;
length--;
}
}
}
}
얘는 또 오류 안나는 걸 보면... UnsortedType 클래스 문제?
template <class ItemType>
void SortedType<ItemType>::PrintReverse() {
//논리적으론 맞는 것 같은데 잘 모르겠... 계속 오류 ㅠㅠ
NodeType<ItemType>* location;
for (int i = 0; i < length; i++) {
location = listData;
for (int j = 0; j < length - i - 1; j++) {
location = location->next; //last -> last-1 -> last-2 -> ... -> 0
}
ItemType item = location->info;
cout << item << endl;
}
}
void StackType::Copy(StackType& anotherStack) { //처음에 꼭 pass by reference
NodeType* ptr1; //anotherStack에 관한 포인터 (복사할 대상)
NodeType* ptr2; //self에 관한 포인터 (새롭게 쓰여지는 대상)
if (anotherStack.topPtr == NULL) // 비어있으면
topPtr = NULL;
else {
topPtr = new NodeType;
topPtr->info = anotherStack.topPtr->info;
ptr1 = anotherStack.topPtr->next;
ptr2 = topPtr;
while (ptr1 != NULL) {
ptr2->next = new NodeType;
ptr2 = ptr2->next;
ptr2->info = ptr1->info;
ptr1 = ptr1->next;
}
ptr2->next = NULL;
}
}