반응형

8.6> BaseArray 클래스를 상속받아 스택으로 작동하는 MyStack 클래스를 작성하라.

<코드>

#include <iostream>

 

using namespace std;

 

class BaseArray{

private:

        int capacity;//배열의 크기

        int *mem;//정수 배열을 만들기 위한 메모리의 포인터

protected:

        BaseArray(int capacity=100){ //디폴트 매개변수 100

               this->capacity=capacity;

               mem=new int[capacity]; //캐패시티 크기로 동적 배열 형성

        }

        ~BaseArray(){delete []mem;} //동적 메모리 힙으로 반환

        void put(int index, int val){mem[index]=val;} //인덱스에 매개변수 삽입

        int get(int index){return mem[index];} //해당 인덱스에서 정수 가져옴

        int getCapacity(){return capacity;} //용량 리턴

};

 

class MyStack : public BaseArray{

private:

        int rear; //마지막 인덱스 리어

public:

        MyStack(int capacity,int rear);

        void push(int arg); //마지막에 원소 추가

        int capacity(); //스택 용량

        int length(); //스택 길이

        int pop(); //마지막 원소 꺼내옴

};

MyStack::MyStack(int capacity=100,int rear=-1):BaseArray(capacity) {this->rear=rear;}

void MyStack::push(int arg) {rear++; put(rear,arg);}

int MyStack::capacity() {int cap=getCapacity(); return cap;}

int MyStack::length(){return rear+1;}

int MyStack::pop(){int out=get(rear); rear--; return out;}

 

int main(void){

MyStack mStack(100);

        int n;

        cout << "스택에 삽입할 5개의 정수를 입력하라>> ";

        for(int i=0;i<5;i++){

               cin >> n;

               mStack.push(n); //큐에 삽입

        }

        cout<<"스택 용량: " <<mStack.capacity()<<", 스택 크기:"<<mStack.length()<<endl;

        cout<<"스택의 모든 원소를 팝하여 출력한다>> ";

        while(mStack.length()!=0){

               cout<<mStack.pop()<<' '; //큐에서 제거하여 출력

        }

        cout<<endl<<"큐의 현재 크기 : "<<mStack.length()<<endl;

        return 0;

}

 

<결과창>

  

 

반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C++' 카테고리의 다른 글

Printer Class  (0) 2017.12.31
ROM RAM class  (0) 2017.12.31
MyQueue Class  (0) 2017.12.31
Stack class  (0) 2017.12.25
Statistics class  (0) 2017.12.25
반응형

5.6> 문제 5번의 MyIntStack를 수정하여 다음과 같이 선언하였다. 스택에 저장할 수 있는 정수의 최대 개수는 생성자에서 주어지고 size 멤버에 유지한다. MyIntStack 클래스를 작성하라.


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
 
using namespace std;
 
class MyIntStack{
private:
    int *p; //스택 메모리로 사용할 포인터
    int size//스택의 최대 크기
    int tos; //스택의 탑을 가리키는 인덱스
public:
    MyIntStack();
    MyIntStack(int size);
    MyIntStack(MyIntStack& s);
    ~MyIntStack();
    bool push(int n); //정수 n을 스택에 푸쉬 꽉차있으면 false 아니면 true
    bool pop(int &n);  //스택의 탑에 있는 값을 n에 pop 한다 스택이 비었으면 false 아니면 true
};
MyIntStack::MyIntStack(){size=1;    p=new int[size];    tos=-1;} //기본 생성자 정의 tos=-1은 empty state를 나타낸다.
MyIntStack::MyIntStack(int size){this->size=size;    p=new int[size];    tos=-1;} //인자 size가 동적 배열의 크기를 결정한다.
//tos=-1이 empty 를 뜻하는 이유는 배열의 인덱스가 0부터 시작하기 때문이다.
MyIntStack::MyIntStack(MyIntStack& s){this->size=s.size
    p=new int[s.size]; //깊은 복사를 위해 새로운 동적메모리를 힙에서 size만큼 받아온다.
    for(int i=0;i<s.size;i++){
    (this->p)[i]=(s.p)[i];
    } //포인터에 할당된 동적메모리의 경우 깊은 복사를 위해
//새로운 할당을 해준 후 배열의 원소를 일일히 복사하여 넣어준다.
this->tos=s.tos;}
MyIntStack::~MyIntStack(){
    if(this->p) //p에 주소값이 NULL이 아니면
        delete []p; //p가 가리키는 동적메모리 반환
}
bool MyIntStack::push(int n){
    if((tos+1)==size//index는0부터 시작해서 1을 더해서 검사함
        return false;
    else{
        p[++tos]=n; //증가시키고 대입해준다.
        return true;
    }
}
bool MyIntStack::pop(int &n){
    if(tos==-1//empty면
        return false;
    else{
        n=p[tos--]; //대입하고 감소시킨다.
        return true;
    }
}
int main(void){
    MyIntStack a(10); //size 10짜리 마이인트스택 a
    a.push(10); //a에 10 삽입 pos=0
    a.push(20);//a에 20 삽입 pos=1
    MyIntStack b=a; //MyIntStack b(a); 와 같다.
    //객체로 초기화 하여 객체 생성,복사생성자 실행됨(깊은복사)
    b.push(30); //b에 30 삽입 pos=2
    int n;
    a.pop(n); //20 pop, pos=0이됨
    cout<<"스택 a에서 팝한 값 "<<n<<endl;
    b.pop(n); //30 pop, pos=1이됨
    cout<<"스택 b에서 팝한 값 "<<n<<endl;
    b.pop(n); //20 pop, pos=0이됨
    cout<<"스택 b에서 팝한 값 "<<n<<endl;
    b.pop(n); //10 pop, pos=-1이됨
    cout<<"스택 b에서 팝한 값 "<<n<<endl;
    cout<<b.pop(n)<<endl//pos=-1, empty state 라서 0 리턴
    return 0;
}
 
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C++' 카테고리의 다른 글

Book 클래스  (1) 2017.11.09
Accumulator 클래스  (0) 2017.11.09
포인터의 증감  (0) 2017.11.09
변수와 포인터와 참조  (0) 2017.11.08
float와 double  (0) 2017.11.05
반응형

인하대학교 전자공학과 데이터 구조 포인터, 어레이 과제 (pointer, array)


인하대학교 전자공학과 데이터 구조 하노이의 탑, 이진 탐색(binary search, tir, recursive)


인하대학교 전자공학과 데이터 구조 시스템 스택, 선형 리스트 (system stack, linear list)


인하대학교 전자공학과 데이터 구조 preorder, postorder, max heap


인하대학교 전자공학과 데이터 구조 dfs, bfs, 프림, 크루스칼 (prim, kruskal)


소스코드, 수도코드, 플로우차트(순서도), 분석 및 고찰, 결과창 등이 들어있는 보고서입니다.


전부 만점받은 보고서입니다. 

반응형
반응형

1. Using the binary search function, show the status of the system stack diagram such as below the example after each function call for the iterative and recursive function.




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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COMPARE(mid,searchnum)  (((mid)<(searchnum)) ? (1) : (((mid)>(searchnum)) ? (-1) : (0)))  //미들값과 찾는값의 크기를 비교하여 해당 값 반환
/* mid<searchnum 이면 -1 반환, mid>searchnum이면 1 반환, mid=searchnum이면 1 반환*/
#define MAX_SIZE 1001 //상수 MAX_SIZE는 1001
#define ITERATIONS 16 //상수 ITERATIONS는 16
int count=0;
int binsearch_rec(int list[], int searchnum, int left, int right);
int binsearch_itr(int list[], int searchnum, int left, int right);
int main(void)
{
    int i;
    int list[MAX_SIZE]; //int형 배열 list 선언, 배열의 크기는 MAX_SIZE=1001
    for(i=0;i<MAX_SIZE;i++)
    {
        list[i]=i; //각 배열의 원소의 값을 번호로 초기화
    }
        printf("binsearch_rec 이용 0~32에서 6찾기 : %d\n",binsearch_rec(list,6,0,32));
        printf("binsearch_itr 이용 0~32에서 6찾기 : %d\n",binsearch_itr(list,6,0,32));
    return 0;
}
int binsearch_itr(int list[], int searchnum, int left, int right)  //반복적으로 짠 이진탐색
{
    int middle; //int형 변수 middle 선언
    printf("*******binsearch_itr 호출*******\n");
    while(left<=right) //left가 right 이하일때 반복
    {middle=(left+right)/2;  //미들은 left와 right의 산술평균
    switch(COMPARE(list[middle],searchnum))  //COMPARE 의 값을 받아와 그에 따라 switch-case로 판단
    {
    case -1 : left=middle+1;  
                break;    //-1경우 left에 middle+1로 대입 후 break
    case 0 :    return middle;
                break//0경우 middle값 리턴 후 break
    case 1 : right=middle-1;
                break//1경우 right에 middle-1로 대입 후 break
    }
    }
    return -1//while 루프가 깨졌을 경우 반환값 -1
}
int binsearch_rec(int list[], int searchnum, int left, int right) //recursive function으로 짠 이진탐색
{
    int middle;//int형 변수 middle 선언
    printf("*******binsearch_rec %d 호출*******\n",i);
    while(left<=right)//left가 right 이하일때 반복 recursive function이라서 if 를 써도 무방하다.
    {middle=(left+right)/2;//미들은 left와 right의 산술평균
    switch(COMPARE(list[middle],searchnum)) //COMPARE 의 값을 받아와 그에 따라 switch-case로 판단
    {
    case -1 :
                return binsearch_rec(list,searchnum,middle+1,right);
                break//-1경우 binsearch_rec함수의 left자리에 middle+1, right 인자에 right 넣어 호출 후 break
    case 0 :
                return middle; 
                break//0의 경우 middle값 리턴 후 break
    case 1 : 
                return binsearch_rec(list,searchnum,left,middle-1);
                break//1경우 binsearch_rec함수의 left자리에 left, right 인자에 middle-1 넣어 호출 후 break
    }
    }
    return -1//while 루프가 깨졌을 경우 반환값 -1
}
cs




*아래쪽 binserach_rec 이용 0~32에서 6찾기 오타입니다. rec를 itr로 바꿔주세요.




2. We can maintain a linear list circularly in an array, circle[MAX_SIZE]. We set up front and rear indices similar to those used for a circular queue.

(a) Obtain a formula in terms of front, rear, and MAX_SIZE for the number of elements in the list.

(b) Write a function that deletes the k-th element in the list.

(c) Write a function that inserts an element, item, immediately after the k-th element.

(d) What is the time complexity of your functions for (b) and (c)?




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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 8 // 배열의 기본 최대 크기 상수 8
int multi=1//배열의 크기를 동적 메모리 할당할 때 사용할 전역 변수 multi
int front = 0//원형 선형 리스트의 front 전역 변수
int rear = 0//원형 선형 리스트의 rear 전역 변수
void del_list(int *list); //k번째 원소 삭제 함수
void insert_list(int *list); //k번째 다음 공간에 원소 삽입 함수
void init(int *arr); //배열을 0으로 초기화 하는 함수, 0을 빈 공간으로 사용하였다.
void print(int *arr); // 배열 프린트 함수
void full(int *list); // 배열이 꽉찼을 때 동적 메모리로 배열의 크기를 늘려주는 함수
int menu(); //메뉴 호출 함수
int main(void)
{
    int *arr; //포인터변수 arr, 배열의 크기를 정확히 알 수 없기 때문에 포인터를 배열처럼 사용한다.
    int m; //메뉴 번호로 사용할 변수 m
    arr=(int*)malloc(sizeof(int)*MAX_SIZE); //sizeof(int)*MAX_SIZE 만큼의 크기의 메모리를 지정
    init(arr); // arr을 0으로 이니셜라이징
    while(1//무한루프
    {m=menu(); //m이 -1이면 루프 탈출
    if(m==-1)
        break;
    else if(m==1)  //m이 1이면 배열 출력
        print(arr);
    else if(m==2//m이 2면 원소 삽입 함수 호출
        insert_list(arr);
    else if(m==3//m이 3이면 원소 삭제 함수 호출
        del_list(arr);
    }
    free(arr); //arr의 동적 메모리 free
    return 0;
}
void del_list(int *list)
{
    int i,k;
    printf("인덱스를 입력하세요: ");
    scanf("%d"&k);
    if(front==rear)  //front는 맨 앞 원소의 인덱스 바로 앞을 말한다. rear를 증가하지않고 둘을 검사하면 empty 검사이다.
        printf("리스트가 비어있습니다.\n");
    else if(list[k]==0// 0값을 empty로 사용하였다.
        printf("이미 비어있는 공간입니다.\n");
    else
    {
        for(i=k;i<MAX_SIZE*multi;i++)  //k번째 원소를 삭제할 것이기 때문에  k부터 전체 배열크기 이전까지 반복해준다.
            list[i]=list[i+1]; // 하나 다음 원소를 이전의 공간에 대입해준다. 즉 왼쪽으로 한칸씩 당긴다.
        rear=(rear-1)%(MAX_SIZE*multi); // rear를 하나 감소해준다. 나머지로 하는 이유는 circular이기 때문이다.
    }
    list[MAX_SIZE*multi-1]=0//꽉찼을 때 이함수를 호출하면 마지막에 쓰레기 값이 들어가므로 마지막 원소에 0을 대입해준다.
    print(list); //배열 프린트
}
void insert_list(int *list)
{
    int i,k,item;
    printf("k번째 원소 뒤에 item을 넣습니다. 차례로 입력하세요: ");
    scanf("%d %d",&k,&item);
        rear=((rear)+1) % (MAX_SIZE*multi);  //insert 함수는 rear를 증가시키고 시작한다.
        if(front==rear)   //front와 rear가 같으면 full 함수를 호출한다.
        {    
            full(list);
    for(i=(MAX_SIZE*multi/2);i<MAX_SIZE*multi;i++//full함수때문에 전역변수 multi가 2배가 된 후이기때문에 나머지 2를 해준다.
        list[i]=0;} // 즉 처음에 인덱스가 0~7 이었으나 full이후 0~15가 되었으므로 8~15를 0으로 초기화 시켜준다. 그 이후 역시 같다.
        if(k+1==MAX_SIZE*multi) 
            /*이것은 마지막 배열공간을 k로택한 경우이다. 이경우 원래대로라면 맨 처음의 경우front를 7로 바꾸고 인덱스 0에 원소를 삽입해야한다.
            하지만 이 경우 함수가 너무 복잡해지기 때문에 나는 차라리 이전의 배열 공간에 있었던 원소들을 한칸씩 오른쪽으로 밀고 index 1에 
            원하는 값을 대입하기로 하였다. 이 방법은 k값이 마지막 배열공간일 때만 신경쓰면 되고, front값을 처음에 0으로 설정해 놓았을 경우
            절대로 프로그램이 종료할 때까지 다른 값으로 바뀌지 않기 때문에 매우 직관적이다. 배열이 꽉찰 경우는 이미 앞에서 검사했기 때문에
            문제가 없다.*/
    {
        for(i=multi*(MAX_SIZE)-1;i>0;i--)
        {list[i]=list[i-1];} // 오른쪽으로 한칸씩 원소를 밀었다.
            list[1]=item; //1번 index에 원하는 값 대입
    }
        else if(k>=rear)  //위의 방법으로 원형 선형 리스트를 구현하였기 때문에 k가 rear 이상인 경우는 전부 걸러낼 수 있다.
            {printf("잘못된 입력입니다.\n");
        rear--;} // 그리고 처음에 rear를 증가시키고 시작했기 때문에 다시 빼준다.
        else{
        for(i=multi*(MAX_SIZE)-1;i>k;i--//이것은 일반적인 경우로 k번째 다음에 공간을 만들기 위해 제일 마지막 원소부터 그 이전원소를 하나씩 오른쪽으로 밀어주는 것을
        {list[i]=list[i-1];}              // 반복문으로 나타낸 것이다. 
            list[k+1]=item;                // k+1 index를 기점으로 원소를 하나씩 오른쪽으로 민 후 원하는 자리에 item을 대입해준다.
    }
        print(list);  //배열 프린트
}
void init(int *arr)
{
    int i;
    for(i=0;i<MAX_SIZE*multi;i++)
        arr[i]=0;
}
void print(int *arr)
{
    int i;
    for(i=0;i<MAX_SIZE*multi;i++)
        printf("%3d ",arr[i]);  //예쁘게 하려고 3d로 자리수를 맞춰주었다.
    printf("\n");
    printf("front   :   %d    rear   :   %d\n",front,rear);
}
int menu()
{
    int m;
    printf("=====================\n");
    printf("1. 리스트 출력\n2. 원소 입력(입력한 인덱스 바로 뒤에 삽입)\n3. 원소 삭제(입력한 인덱스의 원소)\n(-1은종료)\n");
    printf("=====================");
    scanf("%d"&m);
    return m;
}
void full(int *list)
{
    multi*=2//전역변수의 크기를 2배씩 늘려준다.
    realloc(list,sizeof(int)*MAX_SIZE*multi); // 따라서 배열이 꽉 찰때마다 크기가 2배씩 계속 증가한다.
    front=0//front를 0으로 만들어준다. 위에서 말했듯이 바뀔 일이 없다.
    rear=((MAX_SIZE*multi)/2); // rear는 하나가 더 채워졌으므로 8,16,32 .. 등이 된다.
}
cs





반응형

+ Recent posts