5. vector - mleg.cse.sc.edu

16
HW5 solution 5. Vector Write the definition for a class named Vector2D that stores information about a two- dimensional vector. The class should have methods to get and set the x component and the y component, where x and y are integers. Next, overload the * operator so that it returns the dot product of two vectors. The dot product of two-dimensional vectors A and B is equal to (AxBx) + (AyBy) . Finally, write a main subroutine that tests the * operation. //vector.cpp // //This program defines a class for 2D Vectors and tests // overloading of the * operator to compute the dot product. #include <iostream> #include <cstdlib> using namespace std; // -------------------------------- // ----- ENTER YOUR CODE HERE ----- // -------------------------------- class Vector2D { public: Vector2D(); Vector2D(int newx, int newy); void SetXY(int newx, int newy); int GetX(); int GetY(); int operator *(const Vector2D &v2); private: int x,y; }; // ====================== // Vector2D::Vector2D // Default Constructor // ====================== Vector2D::Vector2D()

Upload: others

Post on 19-Nov-2021

0 views

Category:

Documents


0 download

TRANSCRIPT

HW5 solution

5. Vector

Write the definition for a class named Vector2D that stores information about a two-dimensional vector. The class should have methods to get and set the x component and the y component, where x and y are integers.

Next, overload the * operator so that it returns the dot product of two vectors. The dot product of two-dimensional vectors A and B is equal to

(AxBx) + (AyBy) .

Finally, write a main subroutine that tests the * operation.

//vector.cpp

//

//This program defines a class for 2D Vectors and tests

// overloading of the * operator to compute the dot product.

#include <iostream>

#include <cstdlib>

using namespace std;

// --------------------------------

// ----- ENTER YOUR CODE HERE -----

// --------------------------------

class Vector2D

{

public:

Vector2D();

Vector2D(int newx, int newy);

void SetXY(int newx, int newy);

int GetX();

int GetY();

int operator *(const Vector2D &v2);

private:

int x,y;

};

// ======================

// Vector2D::Vector2D

// Default Constructor

// ======================

Vector2D::Vector2D()

{

x=0;

y=0;

}

// ======================

// Vector2D::Vector2D

// Constructor to initialize X,Y

// ======================

Vector2D::Vector2D(int newx, int newy)

{

x=newx;

y=newy;

}

// ======================

// Vector2D::SetXY

// Method to change X,Y

// ======================

void Vector2D::SetXY(int newx, int newy)

{

x=newx;

y=newy;

}

// ======================

// Vector2D::GetXY

// Methods to get the X and Y component

// ======================

int Vector2D::GetX()

{

return (x);

}

int Vector2D::GetY()

{

return (y);

}

// ======================

// Vector2D::*

// Overrides * to compute the dot product

// ======================

int Vector2D::operator *(const Vector2D &v2)

{

return (x*v2.x) + (y*v2.y);

}

// ======================

// main function

// ======================

int main()

{

// Some test vectors

Vector2D v1(10,0), v2(0,10), v3(10,10), v4(5,4);

cout << "(" << v1.GetX() << "," << v1.GetY() << ") * (" << v2.GetX()

<< "," << v2.GetY() << ") = " << v1*v2 << endl;

cout << "(" << v2.GetX() << "," << v2.GetY() << ") * (" << v3.GetX()

<< "," << v3.GetY() << ") = " << v2*v3 << endl;

cout << "(" << v3.GetX() << "," << v3.GetY() << ") * (" << v4.GetX()

<< "," << v4.GetY() << ") = " << v3*v4 << endl;

return 0;

}

// --------------------------------

// --------- END USER CODE --------

// --------------------------------

7. Prime Numbers

Define a class named PrimeNumber that stores a prime number. The default constructor should set the prime number to 1. Add another constructor that allows the caller to set the prime number. Also add a function to get the prime number. Finally, overload the prefix and postfix ++ and -- operators so they return a PrimeNumber object that is the next largest prime number (for ++) and the next smallest prime number (for --). For example, if the object’s prime number is set to 13, then invoking ++ should return a PrimeNumber object whose prime number is set to 17. Create an appropriate test program for the class.

#include <iostream>

using namespace std;

class PrimeNumber

{

private:

int num;

bool isPrime(int num);

public:

PrimeNumber();

PrimeNumber(int val);

int get();

const PrimeNumber operator ++();

const PrimeNumber operator --();

};

PrimeNumber::PrimeNumber() : num(1)

{

}

PrimeNumber::PrimeNumber(int val) : num(val)

{

}

int PrimeNumber::get()

{

return num;

}

bool PrimeNumber::isPrime(int num)

{

for (int i = num-1; i > 1; i--)

{

if ((num % i) == 0)

return false;

}

return true;

}

const PrimeNumber PrimeNumber::operator ++()

{

int nextprime = num;

do

{

nextprime++;

} while (!isPrime(nextprime));

return PrimeNumber(nextprime);

}

const PrimeNumber PrimeNumber::operator --()

{

int previousprime = num;

do

{

previousprime--;

if (previousprime < 1)

{

return PrimeNumber(1);

}

} while (!isPrime(previousprime));

return PrimeNumber(previousprime);

}

// MAIN FUNCTION

int main()

{

PrimeNumber p1, p2(13);

cout << p1.get() << endl;

cout << p2.get() << endl;

PrimeNumber p3 = p1++;

cout << p3.get() << endl;

PrimeNumber p4 = p2++;

cout << p4.get() << endl;

PrimeNumber p5 = p2--;

cout << p5.get() << endl;

cout << "Enter a character to quit." << endl;

char c;

cin >> c;

return 0;

}

11. Anagram Finder

Write a function that determines if two strings are anagrams. The function should not be case sensitive and should disregard any punctuation or spaces. Two strings are anagrams if the letters can be rearranged to form each other. For example, “Eleven plus two” is an anagram of “Twelve plus one”. Each string contains one “v”, three “e’s”, two “l’s”, etc. Test your function with several strings that are anagrams and non-anagrams. You may use either the string class or a C-style string.

#include <iostream>

#include <string>

#include <cctype>

using namespace std;

void build_histogram(int letters[], string s);

void build_histogram(int letters[], string s)

{

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

letters[i] = 0;

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

{

char c = toupper(s[i]);

if (isalpha(c))

{

int index = static_cast<int>(c) -

static_cast<int>('A');

letters[index]++;

}

}

}

int main( )

{

string s1, s2;

int letter_histogram1[26], letter_histogram2[26];

cout << "Enter two strings." << endl;

getline(cin, s1);

getline(cin, s2);

build_histogram(letter_histogram1, s1);

build_histogram(letter_histogram2, s2);

// If histograms are identical they are anagrams

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

{

if (letter_histogram1[i] != letter_histogram2[i])

{

cout << "They are not anagrams." << endl;

char wait;

cin >> wait;

return 0;

}

}

cout << "They are anagrams!" << endl;

cout << "Enter a character to exit." << endl;

char wait;

cin >> wait;

return 0;

}

2. Polynomial class.

Using dynamic arrays, implement a polynomial class with infix operators +, -, *.

Discussion:

In a polynomial, a variable is placeholder for coefficient. If term is missing, the

coefficient is 0. For example, the cubic polynomial 2x

3 -3x + 4

or, written out as C++ code, 2*x*x*x –3*x + 4

has the coefficients for terms as listed:

degree 3 term has coefficient 2,

degree 2 term has coefficient 0,

degree 1 term has coefficient -3, and

degree 0 term has coefficient 4.

Note that the term with degree 2 is missing, but we will use a coefficient of 0 to indicate

that. Observe that the size of the coefficient array is 4, one more than the degree.

Use of sparse matrix techniques not recommended. We will assume that there are few

missing terms.

The student is to provide these member functions:

default constructor,

copy constructor,

operator=

destructor

parameterized constructor to create an arbitrary

polynomial

operator+

operator-

operator*

assign and inspect function (or functions) for

coefficients, indexed by exponent

function to evaluate polynomial as a value of type double

The student is to decide on whether these are to be member, friend, or neither

(standalone).

NOTES:

The default constructor creates an empty polynomial. A zero polynomial has degree 0,

since it has only the zero degree coefficient.

In the coefficient array, the index is the value of the exponent of term having this

coefficient. For example, the index 0 entry is the constant coefficient, the index 1 entry is

coefficient of the linear term, the index 2 entry is the coefficient of the quadratic term

(term in x2), etc.

The size of the coefficient array include a degree 0 entry, so the size is the degree of the

polynomial + 1.

Odd error messages associated with overloading some of the operators occur if you try to

pass a Polynomial object to one of the functions by const reference and do not

implement both these operator[] implementations,

//This version of operator[] is used when an indexed

//expression is used as an l-value.

double& operator[](int degree);

//This version of operator[] is used when an indexed

//expression is used as an r-value.

const double& operator[](int degree)const;

Instead of difficult-to-understand compiler error messages, you may get linker errors,

which is an even harder situation, since linker errors are not associated with any

particular line in your source.

The alternative is to pass by value. In this example, that is not a problem but in general,

passing a class object has the potential for a large amount of copying of data, so const

reference is the desirable way to do it.

Neither of the operator functions for multiply, add or subtract check for zero lead

coefficients. For polynomials that have many zero terms, these functions should account

for the zero entries. Two polynomials of high degree with few nonzero terms will waste

considerable time multiplying zero entries using this technique. The fix is the use of a

linked list (Chapter 17), or the STL list (Chapter 19.)

//file: ch10Prog2.cpp

//Polynomial class -- Chapter 10 Programming Problem #2

#include <iostream>

using namespace std;

class Polynomial

{

public:

Polynomial(); // creates an empty polynomial

Polynomial(const Polynomial&);

// The size of the coefficient array is degree of the polynomial + 1.

Polynomial(double coefficient[], int size);

~Polynomial();

//Use indexed polynomial as r-value to inspect coefficient

//and as l-value to assign coefficient

double& operator[](int degree);

//This is required if we are to have const correctness

const double& operator[](int degree)const;

const Polynomial& operator=(const Polynomial & rhs);

int misuse();

//friend functions:

friend double evaluate(const Polynomial& ploy, double arg);

friend Polynomial operator+(const Polynomial& lsh,

const Polynomial& rhs);

friend Polynomial operator-(const Polynomial& lsh,

const Polynomial& rhs);

friend Polynomial operator*(const Polynomial& lsh,

const Polynomial& rhs);

private:

double * coef;

int size;

};

int main()

{

Polynomial empty;

double one[] = {1};

Polynomial One(one, 1);

double quad[] = {3, 2, 1};

double cubic[] = {1, 2, 0, 3};

Polynomial q(quad, 3); // q is 3 + 2*x + x*x

Polynomial c(cubic, 4);// c is 1 + 2*x + 0*x*x + 3*x*x*x

Polynomial p = q; // test copy constructor

Polynomial r;

r = q; //test operator=

r = c;

cout << "Polynomial q " << endl;

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

cout << "term with degree " << i

<< " has coefficient " << q[i] << endl;

}

cout << "Polynomial c " << endl;

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

cout << "term with degree " << i

<< " has coefficient " << c[i] << endl;

}

cout << "value of q(2) is " << evaluate(q, 2) << endl;

cout << "value of p(2) is " << evaluate(p, 2) << endl;

cout << "value of r(2) is " << evaluate(r, 2) << endl;

cout << "value of c(2) is " << evaluate(c, 2) << endl;

r = q + c;

cout << "value of (q + c)(2) is " << evaluate(r, 2) << endl;

r = q - c;

cout << "value of (q - c)(2) is " << evaluate(r, 2) << endl;

r = q * c;

cout << "size of q*c is " << r.mySize() << endl;

cout << "Polynomial r (= q*c) " << endl;

for(int i = 0; i < r.mySize(); i++)

cout << "term with degree " << i

<< " has coefficient " << r[i] << endl;

cout << "value of (q * c)(2) is " << evaluate(r, 2) << endl;

return 0;

}

int Polynomial::mySize()

{

return size;

}

// creates an empty polynomial

Polynomial::Polynomial():coef(0), size(0)

{// deliberately empty

}

const Polynomial& Polynomial::operator=(const Polynomial & rhs)

{

if(rhs.coef == coef) //if both coefficient arrays start at the same

return rhs; //place our two Polynomials are the same.

else

{

delete [] coef;

coef = new double[rhs.size];

for(int i = 0; i < rhs.size; i++)

coef[i] = rhs.coef[i];

size = rhs.size;

}

return rhs;

}

Polynomial::Polynomial(const Polynomial& rhs) : size(rhs.size)

{

coef = new double[rhs.size];

for(int i = 0; i < rhs.size; i++)

coef[i] = rhs.coef[i];

}

Polynomial::Polynomial(double coefficient[],

int newSize) : size(newSize)

{

coef = new double[size];

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

coef[i] = coefficient[i];

}

Polynomial::~Polynomial()

{

delete [] coef;

}

//return the coefficient of term in variable to exponent 'degree'

const double& Polynomial::operator[](int degree) const

{

return coef[degree];

}

double& Polynomial::operator[](int degree)

{

return coef[degree];

}

double max(double lhs, double rhs)

{

return (lhs > rhs) ? lhs : rhs;

}

// friend function and operator function implementations

Polynomial operator+(const Polynomial& lhs, const Polynomial& rhs)

{

const int sumSize = max(lhs.size, rhs.size);

double* sumCoefs = new double[sumSize];

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

sumCoefs[i] = lhs.coef[i] + rhs.coef[i];

return Polynomial(sumCoefs, sumSize);

}

Polynomial operator-(const Polynomial& lhs, const Polynomial& rhs)

{

int sumSize = max(lhs.size, rhs.size);

double* sumCoefs = new double[sumSize];

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

sumCoefs[i] = lhs.coef[i] - rhs.coef[i];

return Polynomial(sumCoefs, sumSize);

}

// Notes:

// The multiplication routine does not check for zero lead

// coefficients. It also assumes few zero terms.

Polynomial operator*(const Polynomial& lhs, const Polynomial& rhs)

{

int i; int j;

int prodSize = lhs.size + rhs.size;

double* prodCoefs = new double[prodSize];

for(i = 0; i < prodSize; i++)

prodCoefs[i] = 0;

for(i = 0; i < lhs.size; i++)

for(j = 0; j < rhs.size; j++)

prodCoefs[i + j] += lhs[i] * rhs[j];

return Polynomial(prodCoefs, prodSize);

}

double evaluate(const Polynomial& poly, double arg)

{

double value = 0;

int i;

for(i = poly.size - 1; i >= 0; i--)

value = poly[i] + arg * value;

return value;

}

This is the output from this program follows.

Polynomial q

term with degree 0 has coefficient 3

term with degree 1 has coefficient 2

term with degree 2 has coefficient 1

Polynomial c

term with degree 0 has coefficient 1

term with degree 1 has coefficient 2

term with degree 2 has coefficient 0

term with degree 3 has coefficient 3

value of q(2) is 11

value of p(2) is 11

value of r(2) is 29

value of c(2) is 29

value of (q + c)(2) is 40

value of (q - c)(2) is -18

size of q*c is 7

Polynomial r (= q*c)

term with degree 0 has coefficient 3

term with degree 1 has coefficient 8

term with degree 2 has coefficient 5

term with degree 3 has coefficient 11

term with degree 4 has coefficient 6

term with degree 5 has coefficient 3

term with degree 6 has coefficient 0

value of (q * c)(2) is 319

19. HTML Convert

HTML files use tags enclosed in angle brackets to denote formatting instructions. For example, <B> indicates bold, <I> indicates italics, etc. If a web browser is displaying an HTML document that contains < or > then it may mistake these symbols for tags. This is a common problem with C++ files, which contain many <'s and >'s. For example, the line "#include <iostream>" may result in the browser interpreting <iostream> as a tag.

As an example, given the following input file:

#include <iostream>

int main()

{

int x=4;

if (x < 3) x++;

cout << x << endl;

}

The program should produce a textfile with the following contents:

<PRE>

#include &lt;iostream&gt;

int main()

{

int x=4;

if (x &lt; 3) x++;

cout &lt;&lt; x &lt;&lt; endl;

}

</PRE>

You can test your output file by opening it with a web browser. The contents should appear identical to the original source code.

//htmlconvert.cpp

//

// This program reads in a C++ file and outputs HTML tags

// for the < and > symbols.

#include <iostream>

#include <fstream>

#include <cstring>

#include <string>

using namespace std;

// ======================

// main function

// ======================

int main()

{

string filename; // Input file to convert

string outputname; // Output file with .html on the end

char c;

int i;

ifstream inStream;

ofstream outStream;

cout << "Enter filename to convert: " << endl;

cin >> filename;

// --------------------------------

// ----- ENTER YOUR CODE HERE -----

// --------------------------------

// Open the input file

inStream.open(filename.c_str());

if (inStream.fail())

{

cout << "I/O failure opening file." << endl;

exit(1);

}

// Create the output file

outputname = filename + ".html";

outStream.open(outputname.c_str());

// First, output the <PRE> tag

outStream << "<PRE>" << endl;

// Loop through the input file intil nothing else to get

while (!inStream.eof())

{

inStream.get(c); // Get one character

// Output &lt; or &gt; or original char

if (c=='<')

{

outStream << "&lt;";

}

else if (c=='>')

{

outStream << "&gt;";

}

else outStream << c;

}

// Output end /PRE tag

outStream << "</PRE>" << endl;

// --------------------------------

// --------- END USER CODE --------

// --------------------------------

inStream.close();

outStream.close();

cout << "Conversion done. Results in file " << outputname << endl;

return 0;

}