C++/Fundamentals of Data Structures in C++(Horowitz)

C++ Fundamentals of Data Structures(C++ 자료구조론) 2.3 연습문제 1~6

꾸준함. 2017. 7. 28. 14:34

[Exercises 1]

/*

Use the six operations defined in this section for an ordered list to arrive at an ADT specification for such a list

이번 섹션에 언급된 여섯가지의 연산을 이용해 정렬된 리스트의 ADT를 작성해본다

*/

 

//ADT를 작성할 때는 추상적으로 작성해야하지만 어쩌다보니 클래스를 정의하였다.(물론 문법적으로 틀린부분이 있을 수 있습니다)

class orderedList

{

private:

        int *arr;

        int length;

public:

        orderedList(int n):length(n)

        {

               arr = new int[n];

               for (int i = 0; i < n; i++)

                       arr[i] = 0; //0으로 전부 초기화

        }

        int GetLength() //(1) Find the length, n, of the list(리스트의 길이를 반환)

        {

               return length;

        }

        void Print() //(2) Read the list from left to right(리스트의 처음부터 끝까지 출력)

        {

               for (int i = 0; i < length; i++)

                       cout << arr[i] << " ";

               cout << endl;

        }

        int GetElement(int i) //(3) Retrieve the ith element, 0<=i<n(i번째 데이터 반환)

        {

               return arr[i];

        }

        void StoreElement(int i, int newElement) //(4) Store a new value into the ith position, 0<=i<n(i번째 칸에 데이터를 입력)

        {

               arr[i] = newElement;

        }

        void AddElement(int i, int newElement) //(5) Insert a new element at the position i, 0<=i<n, causing elements numbered i, i+1, ..., n-1 to become numbered i+1, i+2, ... n

               //i번째 칸에 데이터를 입력하되 이미 데이터가 있는 경우 i번째 데이터를 덮어쓰지 않고 한칸씩 미뤄서 리스트의 크기가 +1 되도록 한다

        {

               int *newArr;

               if (arr[i] != 0)

               {

                       int newSize = length + 1;

                       newArr = new int[newSize]; //한칸씩 늘리고

                       for (int j = i; j < newSize - 1; j++)

                              arr[i + 1] = arr[i]; //한칸씩 미룬다

                       for (int i = 0; i < newSize - 1; i++)

                              newArr[i]=arr[i];

                       newArr[i] = newElement;

               }

               else

               {

                       arr[i] = newElement;

               }

        }

        void DeleteElement(int i) //(6) Delete the element at position i, 0<=i<n, causing elements numbered i+1, ..., n-1 to become numbered i, i+1, ..., n-2

               ////i번째 칸에 데이터를 삭제하되 i번째 데이터부터 한칸씩 땡겨서 삭제시킨다. 결과적으로 리스트의 크기가 -1 되도록 한다

        {

               if (arr[i] == 0)

                       return;

               else

               {

                       for (int j = i; j < length; j++)

                              arr[j] = arr[j + 1]; //한칸씩 땡긴다

                       int newSize = length - 1;

                       int *newArr = new int[newSize];

                       for (int i = 0; i < newSize; i++)

                              newArr[i] = arr[i];

               }

        }

};

[Exercises 2]

/*

If a=(a0, ..., an-1) and b=(b0, ..., bm-1) are ordered lists,

a0~an-1까지의 데이터를 갖는 a 리스트와 b0~bm-1까지의 데이터를 갖는 b리스트가 정렬된 리스트들이라면

then a<b if ai=bi for 0<=i<j and aj<bj, or, if ai=bi, for 0<=i<n and n<m.

0<=i<j의 조건에서 ai=bi aj<bj의 조건이 동시에 만족하거나 0<=i<n n<m의 조건이 동시에 만족할 때 ai=bi이면 a<b이다.

Write a function that returns -1, 0, or +1, depending upon whether a<b, a=b, or a>b.

a<b일 때 -1, a=b일 때 0, a>b일 때 1을 반환하는 함수를 작성한다

*/

#include <iostream>

#include <ctime>

#include <cstdlib>

using namespace std;

 

class orderedList

{

private:

        int *arr;

        int length;

public:

        orderedList(int n) :length(n)

        {

               arr = new int[n];

               for (int i = 0; i < n; i++)

                       arr[i] = 0; //0으로 전부 초기화

        }

        int GetLength() //(1) Find the length, n, of the list(리스트의 길이를 반환)

        {

               return length;

        }

        void Print() //(2) Read the list from left to right(리스트의 처음부터 끝까지 출력)

        {

               for (int i = 0; i < length; i++)

                       cout << arr[i] << " ";

               cout << endl;

        }

        int GetElement(int i) //(3) Retrieve the ith element, 0<=i<n(i번째 데이터 반환)

        {

               return arr[i];

        }

        void StoreElement(int i, int newElement) //(4) Store a new value into the ith position, 0<=i<n(i번째 칸에 데이터를 입력)

        {

               arr[i] = newElement;

        }

        void sort() //정렬

        {

               for (int i = 0; i < length; i++)

               {

                       for (int j = i + 1; j < length; j++)

                       {

                              if (arr[j] < arr[i])

                              {

                                      int temp = arr[i];

                                      arr[i] = arr[j];

                                      arr[j] = temp;

                              }

                       }

               }

        }

        int Compare(orderedList &b)

        {

               int result = 0;

               for (int i = 0; i < length; i++)

                       if (arr[i] == b.arr[i])

                              result++;

               if (result == 0)

               {

                       cout << "동일한 수가 없으므로 비교 불가" << endl;

                       return -1000;

               }

               else

               {

                       if (length < b.length)

                              return -1;

                       else if (length == b.length)

                              return 0;

                       else

                              return 1;

               }

        }

};

 

int main(void)

{

        orderedList a(10), b(12);

        srand((unsigned)time(NULL));

        for (int i = 0; i < a.GetLength(); i++)

               a.StoreElement(i, rand() % 20 + 1);

        a.sort();

        cout << "a 리스트: ";

        a.Print();

        cout << endl;

        for (int i = 0; i < b.GetLength(); i++)

               b.StoreElement(i, rand() % 20 + 1);

        b.sort();

        cout << "b 리스트: ";

        b.Print();

        cout << endl;

        cout << "두 리스트를 비교했을 때: " << a.Compare(b) << endl;

        return 0;

}


[Exercises 3]

/*

Modify function Add so that it reduces the size of c.termArray to c.terms prior to termination

함수를 종료하기 전에 c.termArray의 크기를 c.terms로 줄이도록 Add 함수를 수정해라.

*/

#include <iostream>

using namespace std;

 

class Polynomial; //forward declaration

 

class Term

{

        friend Polynomial;

private:

        float coef;

        int exp;

};

 

class Polynomial

{

private:

        Term *termArray; //array of nonzero terms

        int capacity;

        int terms; //number of nonzero terms

public:

        Polynomial()

        {

               capacity = 1;

               terms = 0;

               termArray = new Term[capacity];

        }

        void NewTerm(const float theCoeff, const int theExp)

        {

               //Add a new term to the end of termArray

               if (terms == capacity)

               {

                       //double capacity of termArray

                       capacity *= 2;

                       Term *temp = new Term[capacity]; //new array

                       copy(termArray, termArray + terms, temp);

                       delete[]termArray; //deallocate old memory

                       termArray = temp;

               }

               termArray[terms].coef = theCoeff;

               termArray[terms++].exp = theExp;

        }

        Polynomial Add(Polynomial b)

        {

               //Return the sum of the polynomials *this and b

               Polynomial c;

               int aPos = 0, bPos = 0;

               while ((aPos < terms) && (bPos < b.terms))

               {

                       if (termArray[aPos].exp == b.termArray[bPos].exp)

                       {

                              float t = termArray[aPos].coef + b.termArray[bPos].coef;

                              if (t)

                                      c.NewTerm(t, termArray[aPos].exp);

                              aPos++;

                              bPos++;

                       }

                       else if (termArray[aPos].exp < b.termArray[bPos].exp)

                       {

                              c.NewTerm(b.termArray[bPos].coef, b.termArray[bPos].exp);

                              bPos++;

                       }

                       else

                       {

                              c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

                              aPos++;

                       }

               }

               //add in remaining terms of *this

               for (;aPos < terms; aPos++)

                       c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

               //add in remaining terms of b(x)

               for (;bPos < b.terms;bPos++)

                       c.NewTerm(termArray[bPos].coef, b.termArray[bPos].exp);

 

               //추가된 부분

               Term *temp = new Term[c.terms]; //new array

               copy(c.termArray, c.termArray + c.terms, temp);

               delete[]termArray;

               c.termArray = temp;

 

               return c;

        }

};

 

[Exercises 4]

/*

Write C++ functions to input and output polynomials represented as in this section.

이번 섹션에 표현된 다항식을 입력하고 출력하는 함수를 작성한다

Your function should overload the << and >> operators.

이 함수들은 <<, >> 연산자를 오버로드 시켜야한다

*/

#include <iostream>

using namespace std;

 

class Polynomial; //forward declaration

 

class Term

{

        friend Polynomial;

        friend ostream &operator<<(ostream &os, const Polynomial &c); //Term 클래스의 멤버 변수 참조 위해

private:

        float coef;

        int exp;

};

 

class Polynomial

{

private:

        Term *termArray; //array of nonzero terms

        int capacity;

        int terms; //number of nonzero terms

public:

        Polynomial()

        {

               capacity = 1;

               terms = 0;

               termArray = new Term[capacity];

        }

        void NewTerm(const float theCoeff, const int theExp)

        {

               //Add a new term to the end of termArray

               if (terms == capacity)

               {

                       //double capacity of termArray

                       capacity *= 2;

                       Term *temp = new Term[capacity]; //new array

                       copy(termArray, termArray + terms, temp);

                       delete[]termArray; //deallocate old memory

                       termArray = temp;

               }

               termArray[terms].coef = theCoeff;

               termArray[terms++].exp = theExp;

        }

        Polynomial Add(Polynomial b)

        {

               //Return the sum of the polynomials *this and b

               Polynomial c;

               int aPos = 0, bPos = 0;

               while ((aPos < terms) && (bPos < b.terms))

               {

                       if (termArray[aPos].exp == b.termArray[bPos].exp)

                       {

                              float t = termArray[aPos].coef + b.termArray[bPos].coef;

                              if (t)

                                      c.NewTerm(t, termArray[aPos].exp);

                              aPos++;

                              bPos++;

                       }

                       else if (termArray[aPos].exp < b.termArray[bPos].exp)

                       {

                              c.NewTerm(b.termArray[bPos].coef, b.termArray[bPos].exp);

                              bPos++;

                       }

                       else

                       {

                              c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

                              aPos++;

                       }

               }

               //add in remaining terms of *this

               for (;aPos < terms; aPos++)

                       c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

               //add in remaining terms of b(x)

               for (;bPos < b.terms;bPos++)

                       c.NewTerm(termArray[bPos].coef, b.termArray[bPos].exp);

 

               Term *temp = new Term[c.terms]; //new array

               copy(c.termArray, c.termArray + c.terms, temp);

               delete[]termArray;

               c.termArray = temp;

 

               return c;

        }

        //입출력

        friend ostream &operator<<(ostream &os, const Polynomial &c);

        friend istream &operator>>(istream &is, Polynomial &c);

};

 

ostream &operator<<(ostream &os, const Polynomial &c)

{

        for(int i=0; i<c.terms; i++)

               os << c.termArray[i].coef << "x^(" << c.termArray[i].exp << ") " << " + ";

        os << endl;

        return os;

}

 

istream &operator>>(istream &is, Polynomial &c)

{

        float coef;

        int exp;

        int newTerms;

        cout << "입력할 개수: ";

        is >> newTerms;

        for (int i = 0; i < newTerms; i++)

        {

               cout << "계수, 지수 입력: ";

               is >> coef >> exp;

               c.NewTerm(coef, exp);

        }

        return is;

}

 

int main(void)

{

        Polynomial p1;

        cin >> p1;

        cout << "입력한 다항식: " << p1 << endl;

        return 0;

}


[Exercises 5]

/*

Write a C++ function that multiplies two polynomials represented as in this secition.

이 섹션에서 표현한 두 다항식을 곱하는 함수를 작성한다.

*/

#include <iostream>

using namespace std;

 

class Polynomial; //forward declaration

 

class Term

{

        friend Polynomial;

        friend ostream &operator<<(ostream &os, const Polynomial &c); //Term 클래스의 멤버 변수 참조 위해

private:

        float coef;

        int exp;

};

 

class Polynomial

{

private:

        Term *termArray; //array of nonzero terms

        int capacity;

        int terms; //number of nonzero terms

public:

        Polynomial()

        {

               capacity = 1;

               terms = 0;

               termArray = new Term[capacity];

        }

        void NewTerm(const float theCoeff, const int theExp)

        {

               //Add a new term to the end of termArray

               if (terms == capacity)

               {

                       //double capacity of termArray

                       capacity *= 2;

                       Term *temp = new Term[capacity]; //new array

                       copy(termArray, termArray + terms, temp);

                       delete[]termArray; //deallocate old memory

                       termArray = temp;

               }

               termArray[terms].coef = theCoeff;

               termArray[terms++].exp = theExp;

        }

        Polynomial Add(Polynomial b)

        {

               //Return the sum of the polynomials *this and b

               Polynomial c;

               int aPos = 0, bPos = 0;

               while ((aPos < terms) && (bPos < b.terms))

               {

                       if (termArray[aPos].exp == b.termArray[bPos].exp)

                       {

                              float t = termArray[aPos].coef + b.termArray[bPos].coef;

                              if (t)

                                      c.NewTerm(t, termArray[aPos].exp);

                              aPos++;

                              bPos++;

                       }

                       else if (termArray[aPos].exp < b.termArray[bPos].exp)

                       {

                              c.NewTerm(b.termArray[bPos].coef, b.termArray[bPos].exp);

                              bPos++;

                       }

                       else

                       {

                              c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

                              aPos++;

                       }

               }

               //add in remaining terms of *this

               for (;aPos < terms; aPos++)

                       c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

               //add in remaining terms of b(x)

               for (;bPos < b.terms;bPos++)

                       c.NewTerm(termArray[bPos].coef, b.termArray[bPos].exp);

              

               Term *temp = new Term[c.terms]; //new array

               copy(c.termArray, c.termArray + c.terms, temp);

               delete[]termArray;

               c.termArray = temp;

              

               return c;

        }

        Polynomial Multiplication(Polynomial b) //곱셈

        {

               Polynomial c;

               c.NewTerm(0, 0);

               for (int i = 0; i < terms; i++)

               {

                       Polynomial temp;

                       for (int j = 0; j < b.terms; j++)

                       {

                              temp.NewTerm(termArray[i].coef*b.termArray[j].coef, termArray[i].exp+b.termArray[j].exp); //계수는 곱하고, 지수는 더하고

                       }

                       /*

                       cout << endl << "temp: " << temp << endl;

                       cout << "c: " << c << endl;

                       */

                       c = c.Add(temp);

               }

               for (int i = 0; i < c.terms; i++)

               {

                       for (int j = i + 1; j < c.terms; j++)

                       {

                              if (c.termArray[i].exp == c.termArray[j].exp) //같은 지수일 떄 계수를 더하는 for

                              {

                                      c.termArray[i].coef += c.termArray[j].coef;

                                      c.termArray[j].coef = 0;

                              }

                       }

               }

               return c;

        }

        //입출력

        friend ostream &operator<<(ostream &os, const Polynomial &c);

        friend istream &operator>>(istream &is, Polynomial &c);

};

 

ostream &operator<<(ostream &os, const Polynomial &c)

{

        for (int i = 0; i<c.terms; i++)

               if(c.termArray[i].coef!=0)

                       os << c.termArray[i].coef << "x^(" << c.termArray[i].exp << ") " << "+" ;

        os << endl;

        return os;

}

 

istream &operator>>(istream &is, Polynomial &c)

{

        float coef;

        int exp;

        int newTerms;

        cout << "입력할 개수: ";

        is >> newTerms;

        for (int i = 0; i < newTerms; i++)

        {

               cout << "계수, 지수 입력: ";

               is >> coef >> exp;

               c.NewTerm(coef, exp);

        }

        return is;

}

 

int main(void)

{

        Polynomial p1, p2;

        for (int i = 0; i < 2; i++)

        {

               p1.NewTerm(i + 1, i + 1);

        }

        cout << "p1 다항식: " << p1 << endl;

        for (int i = 1; i < 3; i++)

        {

               p2.NewTerm(i, i);

        }

        cout << "p2 다항식: " << p2 << endl;

        Polynomial p3 = p1.Multiplication(p2);

        cout << "p1*p2: " << p3 << endl;

        return 0;

}


[Exercises 6]

/*

Write a c++ function that evaluates a polynomial at a value x0 using the representation of this section

이 섹션에서 표현한 다항식에 x0를 대입했을 때의 결과값을 반환하는 함수를 작성하시오

*/

#include <iostream>

using namespace std;

 

class Polynomial; //forward declaration

 

class Term

{

        friend Polynomial;

        friend ostream &operator<<(ostream &os, const Polynomial &c); //Term 클래스의 멤버 변수 참조 위해

private:

        float coef;

        int exp;

};

 

class Polynomial

{

private:

        Term *termArray; //array of nonzero terms

        int capacity;

        int terms; //number of nonzero terms

public:

        Polynomial()

        {

               capacity = 1;

               terms = 0;

               termArray = new Term[capacity];

        }

        void NewTerm(const float theCoeff, const int theExp)

        {

               //Add a new term to the end of termArray

               if (terms == capacity)

               {

                       //double capacity of termArray

                       capacity *= 2;

                       Term *temp = new Term[capacity]; //new array

                       copy(termArray, termArray + terms, temp);

                       delete[]termArray; //deallocate old memory

                       termArray = temp;

               }

               termArray[terms].coef = theCoeff;

               termArray[terms++].exp = theExp;

        }

        Polynomial Add(Polynomial b)

        {

               //Return the sum of the polynomials *this and b

               Polynomial c;

               int aPos = 0, bPos = 0;

               while ((aPos < terms) && (bPos < b.terms))

               {

                       if (termArray[aPos].exp == b.termArray[bPos].exp)

                       {

                              float t = termArray[aPos].coef + b.termArray[bPos].coef;

                              if (t)

                                      c.NewTerm(t, termArray[aPos].exp);

                              aPos++;

                              bPos++;

                       }

                       else if (termArray[aPos].exp < b.termArray[bPos].exp)

                       {

                              c.NewTerm(b.termArray[bPos].coef, b.termArray[bPos].exp);

                              bPos++;

                       }

                       else

                       {

                              c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

                              aPos++;

                       }

               }

               //add in remaining terms of *this

               for (;aPos < terms; aPos++)

                       c.NewTerm(termArray[aPos].coef, termArray[aPos].exp);

               //add in remaining terms of b(x)

               for (;bPos < b.terms;bPos++)

                       c.NewTerm(termArray[bPos].coef, b.termArray[bPos].exp);

 

               Term *temp = new Term[c.terms]; //new array

               copy(c.termArray, c.termArray + c.terms, temp);

               delete[]termArray;

               c.termArray = temp;

 

               return c;

        }

        Polynomial Multiplication(Polynomial b) //곱셈

        {

               Polynomial c;

               c.NewTerm(0, 0);

               for (int i = 0; i < terms; i++)

               {

                       Polynomial temp;

                       for (int j = 0; j < b.terms; j++)

                       {

                              temp.NewTerm(termArray[i].coef*b.termArray[j].coef, termArray[i].exp + b.termArray[j].exp); //계수는 곱하고, 지수는 더하고

                       }

                       c = c.Add(temp);

               }

               return c;

        }

        float Eval(float x) //x 대입했을 때 결과값

        {

               float result = 0;

               for (int i = 0; i<terms; i++)

               {

                       float temp = 1; //곱셈이므로 temp 1

                       for (int j = 0; j < termArray[i].exp; j++)

                              temp *= x; //지수 계산

                       result += (temp*termArray[i].coef);

               }

               return result;

        }

        //입출력

        friend ostream &operator<<(ostream &os, const Polynomial &c);

        friend istream &operator>>(istream &is, Polynomial &c);

};

 

ostream &operator<<(ostream &os, const Polynomial &c)

{

        for (int i = 0; i<c.terms; i++)

               if (c.termArray[i].coef != 0)

                       os << c.termArray[i].coef << "x^(" << c.termArray[i].exp << ") " << "+";

        os << endl;

        return os;

}

 

istream &operator>>(istream &is, Polynomial &c)

{

        float coef;

        int exp;

        int newTerms;

        cout << "입력할 개수: ";

        is >> newTerms;

        for (int i = 0; i < newTerms; i++)

        {

               cout << "계수, 지수 입력: ";

               is >> coef >> exp;

               c.NewTerm(coef, exp);

        }

        return is;

}

 

int main(void)

{

        Polynomial p1;

        for (int i = 0; i < 2; i++)

        {

               p1.NewTerm(i + 1, i + 1);

        }

        cout << "P1 다항식: " << p1 << endl;

        cout << "p1 다항식에 2를 대입할 경우: " << p1.Eval(2) << endl;

        return 0;

}



[참고] Fundamentals of Data Structures in C++(Horowitz, Sahni, Mehta) 원서


*영어로 적혀있는 문제를 제가 의역한 것이기 때문에 오역이 있을 수 있습니다. 양해 부탁드립니다.

반응형