I have a problem as shown on the following image
I have added all the code of the monom.cpp ,
Probably the problem that I did not set the temp well is the help how to set temp, the result that i should return it's polinom = 0;it's
The degree of the polynomial and for example I add polynomial x ^ 2 + 1
The degree of the polynomial is 2
void Polinom::add(const Monomial const & monomial)
int base = monomial.getCoff();
int exp = monomial.getExpo();
bool foundBase = false;
Monomial* temp = new Monomial[size + 1];
for (int i = 0; i < size; i++)
{
Monomial monom;
monom = monomials[i];
if (exp == monom.getExpo())
{
monom.setCoff(base + monom.getCoff());
foundBase = true;
}
temp[i] = monom;
}
if (!foundBase)
{
monomials[size] = Monomial(monomial);
delete[] monomials;
monomials = temp;
}
else
{
delete[] temp;
}
Monomial.cpp
int Monomial::counter = 0;
Monomial::Monomial()
{
setCoff(1);
setExpo(0);
counter++;
}
Monomial::Monomial(int a)
{
setCoff(a);
setExpo(0);
counter++;
}
Monomial::Monomial(int a, int b)
{
setCoff(a);
setExpo(b);
counter++;
}
Monomial::~Monomial()
{
counter--;
}
void Monomial::setCoff(int x)
{
coff = x;
}
void Monomial::setExpo(int x)
{
expo = x;
}
int Monomial::getCoff() const
{
return coff;
}
int Monomial::getExpo() const
{
return expo;
}
int Monomial::getNumberOfMonomials()
{
return counter;
}
const Monomial& Monomial:: operator = (const Monomial& right)
{
coff = right.coff;
expo = right.expo;
return (*this);
}
string Monomial:: operator+(const Monomial& right)
{
if (right.getExpo() == this->getExpo()) {
this->setCoff(this->getCoff() + right.getCoff());
return "True";
}
return "False";
}
Related
In this code, it runs fine when I have declared only one object of polynomial class. But as soon as I declare two objects of polynomial class, it does not show any error, but the code does not run. Not even the first line of int main().
I have checked all other functions individually. The only problem is declaration of more than one polynomial class objects!!!
#include<iostream>
#include<fstream>
#include<string>
#include<cstring>
#include<math.h>
using namespace std;
string space_rem(string s)
{
int i;
string res;
for(i=0;i<s.size();i++)
{
if(s[i] != ' ')
res+=s[i];
}
return res;
}
string all_in_powers(string s) //writes every variable in string in its power form x^(i)
{ //e.g. abca is written as a^(1)b^(1)c^(1)a^(1)
string temp = s;
if(temp.size()==0)
return temp;
int i;
if(temp[temp.size()-1]>='a'&&temp[temp.size()-1]<='z')
temp+="^(1)";
string res;
char x;
for(i=0;i<temp.size()-3;i++)
{
x=temp[i];
if(x>='a' && x<='z' && temp[i+1]!='^') //if variable not in power form
{
res+=x;
res+="^(1)"; //writes ab as a^(1)b^(1)
}
else
{
res+=x; //variable in power form so copy as it is
}
}
for(i=temp.size()-3;i<temp.size();i++)
{
res+=temp[i];
}
return res;
}
class polynomial_term //stores everything regarding a polynomial term
{
public:
int powers[26]={0}; //power of each variable from a to z
string pol; //string representation of term without coefficient
int coeff; //coefficient of term
char sign;
int pow_sum; //positive or negative
public:
void full_term(string s); //inputs string form and puts all the data of the term in this class's object
void string_construct(); //makes the string representation pol from the powers array
void pol_pow(string s); //gathers data of total power of each variable from input string
void display(); //displays the complete polynomial term
polynomial_term operator * (polynomial_term); //to multiply two terms
bool operator < (polynomial_term);
bool operator > (polynomial_term);
bool operator == (polynomial_term);
void display_pow();
polynomial_term operator + (polynomial_term);
void copy_frm(polynomial_term);
};
void polynomial_term::copy_frm(polynomial_term B)
{
for(int i=0;i<26;i++)
{
powers[i]=B.powers[i];
}
coeff=B.coeff;
pol=B.pol;
sign=B.sign;
pow_sum=B.pow_sum;
}
void polynomial_term:: display_pow()
{
for(int i=0;i<26;i++)
{
cout<<powers[i]<<" ";
}
cout<<endl;
}
void polynomial_term::display()
{
/*if(coeff==0)
{
cout<<"0\n";
}*/
if(coeff==1)
{
if(pol.size()!=0)
cout<<pol<<endl;
else
{
cout<<1<<endl; //only coefficient printed as pol is empty
}
}
else
{
if(coeff!=-1)
cout<<coeff<<pol<<endl;
else
cout<<"-"<<pol<<endl;
}
}
void polynomial_term::string_construct() //generates pol member of polynomial term class using powers array
{
pol.clear();
/*if(coeff!=1)
{
pol+=to_string(coeff);
}*/
for(int i=0;i<26;i++)
{
if(powers[i]!=0)
{
pol+=(char)(i+'a');
if(powers[i]!=1)
{
pol+="^(";
pol+=to_string((powers[i]));
pol+=')';
}
}
}
}
void polynomial_term::pol_pow(string s) //
{
char x;
if(s.size()==0)
return;
for(int i=0;i<s.length();i++)
{
x=s[i];
if(x>='a'&&x<='z')
{
string tmp;
int pow;
for(int j=i+3;s[j]!=')';j++) //gathers power of variable in tmp string
{
tmp+=s[j];
}
pow=stoi(tmp);
powers[x-'a']+=pow;
}
}
pow_sum=0;
for(int i=0;i<26;i++)
{
pow_sum+=powers[i];
}
}
void polynomial_term::full_term(string s) //inputs raw string and organises its data in the polynomial_term class object
{
sign='+'; //default sign
coeff=1; //default coefficient
for(int i=0;i<26;i++)
{
powers[i]=0;
}
pol.clear();
pow_sum=0;
int i=0;
if(s[0]=='-')
{
sign='-';
i++;
}
string tmp;
while(i<s.size() && s[i]>='0' && s[i]<='9') //tmp collects the coefficient part
{
tmp+=s[i];
i++;
}
if(tmp.size()>0)coeff=stoi(tmp);
if(sign=='-')
coeff*=-1;
tmp="";
if(1)
{
for(int j=i;j<s.length();j++)
{
tmp+=s[j];
}
}
s=tmp;
s=all_in_powers(s);
pol_pow(s);
string_construct();
}
polynomial_term polynomial_term::operator * (polynomial_term B) //returns multiplication of terms
{
polynomial_term res;
res.coeff=coeff*B.coeff;
if(res.coeff<0)
res.sign='-';
string temp=pol+B.pol;
temp=all_in_powers(temp);
res.pol_pow(temp);
res.string_construct();
return res;
}
bool polynomial_term::operator < (polynomial_term B) //lexicographic order comparison
{
// bool flag=0;
/*if(pow_sum==B.pow_sum)
{
for(int i=0; i<26; i++)
{
if(powers[i]>B.powers[i])
{
//if(B.powers[i]==0)
//return false;
return false;
}
else if(powers[i]<B.powers[i])
{
return true;
}
}
}*/
for(int i=0; i<26; i++)
{
if(powers[i]>B.powers[i])
{
//if(B.powers[i]==0)
//return false;
return true;
}
else if(powers[i]<B.powers[i])
{
return false;
}
}
return false;
}
bool polynomial_term::operator > (polynomial_term B) //lexicographic order comparison
{
for(int i=0; i<26; i++)
{
if(powers[i]>B.powers[i])
return false;
else
{
if(powers[i]<B.powers[i])
return true;
else
continue;
}
}
return false;
}
bool polynomial_term::operator == (polynomial_term B)
{
for(int i=0;i<26;i++)
{
if(powers[i] != B.powers[i])
return false;
}
return true;
}
polynomial_term polynomial_term::operator + (polynomial_term B) //return addition of polynomial_terms
{
polynomial_term C;
if(pol!=B.pol)
{
cout<<"Error: Adding two non_compatible polynomial terms!!\n";
}
C.coeff = coeff+B.coeff;
if(C.coeff<0)
C.sign='-';
else
C.sign='+';
C.pol=pol;
//cout<<"*\n";
C.pol_pow(all_in_powers(pol));
//cout<<"**\n";
C.string_construct();
//cout<<"*\n";
return C;
}
class polynomial
{
public:
polynomial_term terms[10000];
int term_count;
string expression;
public:
void expression_generate();
polynomial(): term_count(0),expression("0")
{
polynomial_term X;
X.full_term("0");
for(int i=0;i<10000;i++)
{
terms[i].copy_frm(X);
}
}
polynomial(string s) //constructor segregates terms and stores them in terms array
{
//cout<<"uo\n";
polynomial_term X;
X.full_term("0");
for(int i=0;i<10000;i++)
{
terms[i].copy_frm(X);
}
s=all_in_powers(s);
polynomial_term tmp;
string temp="";
int i;
for(i=0;!(i!=0 && s[i]=='+'|| s[i]=='-') && i<s.size();i++) //put first term in the array
{
temp+=s[i];
}
cout<<"***"<<i<<endl;
tmp.full_term(temp);
terms[0]=tmp;
temp="";
term_count=1;
while(i<s.size())
{
if(s[i]=='+' )
{
temp="";
i++;
while(s[i]!='+' && s[i]!='-' && i<s.size())
{
temp+=s[i];
i++;
}
tmp.full_term(temp);
terms[term_count]=tmp;
term_count++;
}
else if(s[i]=='-')
{
temp="-";
i++;
while(s[i]!='+' && s[i]!='-' && i<s.size())
{
temp+=s[i];
i++;
}
tmp.full_term(temp);
terms[term_count]=tmp;
term_count++;
}
}
expression_generate();
}
void lexicosort();
void powersort();
void display_terms();
//void expression_generate();
void display();
bool found(polynomial_term);
};
void polynomial::display_terms()
{
for(int i =0;i<term_count;i++)
{
terms[i].display();
}
}
void polynomial::display()
{
cout<<expression<<endl;
}
void polynomial::powersort()
{
polynomial_term least;
int least_index,i,j;
for(i=0;i<term_count;i++)
{
least = terms[i];
least_index = i;
for(j=i;j<term_count;j++)
{
if(terms[j].pow_sum<least.pow_sum)
{
least=terms[j];
least_index=j;
}
}
polynomial_term temp = terms[i];
terms[i] = terms[least_index];
terms[least_index] = temp;
}
}
void polynomial::lexicosort()
{
polynomial_term least;
int least_index,i,j;
for(i=0;i<term_count;i++)
{
least = terms[i];
least_index = i;
for(j=i;j<term_count;j++)
{
if(terms[j]<least)
{
least=terms[j];
least_index=j;
}
}
polynomial_term temp = terms[i];
terms[i] = terms[least_index];
terms[least_index] = temp;
}
}
void polynomial::expression_generate()
{
// cout<<"**\n";
expression.clear();
expression="";
if(term_count==0)
{
//cout<<"*\n";
expression="0";
return;
}
for(int i=0;i<term_count;i++)
{
//cout<<"lolo\n";
if(terms[i].coeff==0)
{
if(i==1)
{
expression="0";
return;
}
else
{
continue;
}
}
if((terms[i].coeff)!=1 && (terms[i].coeff)!=-1)
{
if(i!=0)
expression += terms[i].sign;
expression += to_string(terms[i].coeff);
}
else
{
if(i!=0)
expression += terms[i].sign;
}
expression += terms[i].pol;
}
}
bool polynomial::found(polynomial_term X)
{
for(int i=0;i<term_count;i++)
{
if(X==terms[i])
return true;
}
return false;
}
/*polynomial comp(polynomial A) //compresses by grouping similar terms (terms that can be added)
{
A.lexicosort();
A.expression_generate();
A.powersort();
A.expression_generate();
polynomial_term tmp;
tmp.copy_frm(A.terms[0]);
polynomial res;
for(int i=1;i<A.term_count;i++)
{
if(!(A.terms[i]==tmp))
{
res.terms[res.term_count].copy_frm(tmp);
res.term_count++;
tmp.copy_frm(A.terms[i]);
}
else
{
polynomial_term X=tmp+A.terms[i];
tmp.copy_frm(X);
}
}
res.expression_generate();
return res;
}*/
int main()
{
cout<<"*\n";
polynomial A("a");
// polynomial B;
cout<<"*\n";
polynomial B("a+b+b+a");
A.display();
cout<<"*\n";
/* A.lexicosort();
A.expression_generate();
A.powersort();
A.expression_generate();
cout<<"*\n";
A.display_terms();
cout<<"*\n";*/
//res.expression_generate();
//res.display();
}
So I have to write a string class, and I need help with reading from a file into a vector of string classes I've created. It somewhat works, as it reads from the file but it repeats the the word read in a few times depending on which word it's on.
// .h
/*Class description:
A string class. Various functions for the class.
String is passed into objects of the class. Reads
and writes to files.*/
#ifndef MYString12_H
#define MYString12_H
#include <fstream>
using namespace std;
class MYString12
{
public:
MYString12();
MYString12(const MYString12 & mstr);
MYString12(const char* ptr);
~MYString12();
MYString12& operator = (const MYString12& argStr);
friend MYString12 operator + (const MYString12& str1, const MYString12& str2);
char operator [] (int index);
bool operator > (const MYString12& argStr2);
bool operator < (const MYString12& argStr2);
bool operator == (const MYString12& argStr);
friend istream& operator >> (istream& istr, MYString12& argStr);
friend ostream& operator << (ostream& istr, MYString12& argStr);
int length() const;
int capacity()const;
char at(int index);
const char* c_str()const;
static int getCurrentCount();
static int getCreatedCount();
private:
char* str;
int cap = 20;
int end;
const int compareTo(const MYString12& argStr);
static int currentCount;
static int createdCount;
};
#endif
Here is class cpp file
// MYString12.cpp
#include "stdafx.h"
#include "MYString12.h"
#include <iostream>
#include <iomanip>
#include <math.h>
#include <cstdlib>
using namespace std;
int MYString12::createdCount = 0;
int MYString12::currentCount = 0;
// default constructor
MYString12::MYString12()
{
cap = 20;
end = 0;
str = new char[cap];
str[end] = '\0';
createdCount++;
currentCount++;
}
// copy constructor
MYString12::MYString12(const MYString12& mstr)
{
this->end = mstr.end;
this->cap = mstr.cap;
this->str = new char[mstr.cap];
while (end >= cap) {
cap += 20;
}
for (int i = 0; i < end; i++) {
str[i] = mstr.str[i];
}
//mstr.str[end] = '\0';
createdCount++;
currentCount++;
}
// constructor with string passed in
MYString12::MYString12(const char* ptr)
{
int i = 0;
while (ptr[i] != '\0') {
end++;
i++;
}
while (end >= cap) {
cap += 20;
}
str = new char[cap];
for (int j = 0; j < end; j++) {
str[j] = ptr[j];
}
createdCount++;
currentCount++;
}
// destructor
MYString12::~MYString12()
{
delete[] str;
currentCount--;
}
// overloaded assignment operator
GAString12& GAString12::operator = (const GAString12& mstr)
{
if (this == &mstr) {
return *this;
}
this->end = mstr.end;
this->cap = mstr.cap;
while (end >= cap) {
cap += 20;
}
for (int i = 0; i < end; i++) {
str[i] = mstr.str[i];
}
//mstr.str[end] = '\0';
return *this;
}
// overloaded concatanation operator
MYString12 operator + (const MYString12& str1, const MYString12& str2)
{
int temp = str1.end + str2.end + 1;
char tempArray[200];
int i = 0;
int j = 0;
while (i < temp)
{
if (i < str1.end)
{
tempArray[i] = str1.str[i];
i++;
} else {
tempArray[i] = str2.str[j];
i++;
j++;
}
}
tempArray[i] = '\0';
MYString12 concatenatedObj(tempArray);
return concatenatedObj;
}
// overloaded index operator
char MYString12::operator [] (int index)
{
return str[index];
}
// overloaded greater than operator
bool MYString12::operator > (const MYString12& argStr)
{
if ((*this).compareTo(argStr) > 0)
{
return true;
}
else {
return false;
}
}
// overloaded less than operator
bool MYString12::operator < (const MYString12& argStr)
{
if ((*this).compareTo(argStr) < 0)
{
return true;
}
else {
return false;
}
}
// overloaded equals equals operator
bool MYString12::operator == (const MYString12& argStr)
{
if ((*this).compareTo(argStr) == 0)
{
return true;
}
else {
return false;
}
}
// compares ascii values of objStr and argStr
const int MYString12::compareTo(const MYString12& argStr)
{
int asciiSubtraction = 0;
int limit = 0;
if (end <= argStr.end)
{
limit = end;
}
else {
limit = argStr.end;
}
int i = 0;
while (i <= limit && (str[i] == argStr.str[i])) {
i++;
}
asciiSubtraction = str[i] - argStr.str[i];
return asciiSubtraction;
}
// overloaded extraction operator
istream& operator >> (istream& istr, MYString12& argStr)
{
char temp[100];
istr >> temp;
argStr = GAString12(temp);
return istr;
}
// overloaded insertion operator
ostream& operator << (ostream& ostr, MYString12& argStr)
{
int i = 0;
while (argStr.str[i] != '\0')
{
ostr << argStr.str;
i++;
}
return ostr;
}
// returns size of passed in string
int MYString12::length() const
{
return end;
}
// returns size of memory allocated
int MYString12::capacity() const
{
return cap;
}
// returns a char of string at passed index
char MYString12::at(int index)
{
if (index < 0 || index > end) {
return '\0';
}
else {
return str[index];
}
}
// returns passed in string as c string
const char* MYString12::c_str() const
{
createdCount++;
currentCount++;
return str;
}
// returns the amount of alive instances of class
int MYString12::getCurrentCount()
{
return currentCount;
}
// returns the amount of overall created instances of class
int MYString12::getCreatedCount()
{
return createdCount;
}
And here is main
// main
int main()
{
vector<MYString12> word(100);
ifstream fin;
fin.open("infile3.txt");
if (fin.fail()) {
cout << "Error." << endl;
exit(1);
}
int wordCount = 0;
while (fin >> word[wordCount]) {
cout << word[wordCount];
system("pause");
wordCount++;
}
word.resize(wordCount);
fin.close();endl;
return 0;
}
It doesn't print out to the console any of the words. Nothing is printed. Why doesn't it print?
Trying to familiarize myself with the "Rule of 3" and Im having trouble getting a Copy Constructor to work. One of the class private members is returning 0 when it should have a value of 3.
Im not sure as to why when the Copy Constructor function is performed, a value of 0 is supplied to that classes private member. The member in question is theSize which is returned via the size() function in class.cpp.
class.h
class Catalog {
public:
Catalog (int maxCapacity = 100)
int size() const;
int capacity() const;
void add (Book b);
Catalog(const Catalog& c);
~Catalog();
Catalog& operator= (constCatalog& c) {
if (this != &c) {
delete[] books;
books = new Book[theCapacity];
*books = *(c.books);
}
return *this;
}
private:
Book* books;
int theCapacity;
int theSize;
};
class.cpp
Catalog::Catalog(int maxCapacity) {
theCapacity = maxCapacity;
theSize = 0;
books = new Book[theCapacity];
}
int Catalog::size() const {
return theSize();
}
int Catalog::capacity() const {
return theCapacity;
}
void Catalog::add (Book b)
{
if (theSize < theCapacity || contains(b.getID())) {
if (theSize == 0) {
books[0] = b;
theSize++;
}
else {
if (!contains(b.getID())) {
int i = theSize;
for (; i && b < books[i-1]; --i) {
books[i] = books[i - 1];
}
books[i] = b;
for (; i; --i) {
books[i - 1] = books[i - 1];
}
theSize++;
}
else {
for (int i = 0; i < theSize; ++i) {
if (b == books[i]) {
books[i] = b;
}
}
}
}
// Debugging only
/*for (int i = 0; i < theSize; i++) {
//cout << books[i] << endl;
}*/
}
}
bool Catalog::contains(std::string bookID) const
{
for (int i = 0; i < theSize; ++i)
{
if (books[i].getID() == bookID)
return true;
}
return false;
}
Catalog::Catalog(const Catalog& c) {
books = new Book[c.theSize];
for (int i = 0; i < c.theSize; i++) {
books[i] = c.books[i];
}
Catalog::~Catalog() {
delete[] books;
}
Later in main.cpp when I call c1.size() where c1 is the result of return c in another function that through use of the debugger comes from the Copy Constructor and then goes to the Destructor. However, c1.size() is returning as 0 though the Copy Constructor theSize = c.size() has a value of 3 when stepped through.
book.cpp
using namespace std;
/**
* Create a book.
*
* #param id the Gutenberg ID for this book
* #param authorInfo the author of the book
* #param title the title of the book
*/
Book::Book (std::string theId, std::string authorInfo, std::string theTitle)
: id(theId), authorName(authorInfo), title(theTitle)
{
}
bool Book::operator< (const Book& b) const
{
return id < b.id;
}
bool Book::operator== (const Book& b) const
{
return (id == b.id);
}
std::ostream& operator<< (std::ostream& out, const Book& b)
{
cout << b.getID() << "\t"
<< b.getAuthor() << "\t"
<< b.getTitle();
return out;
}
std::istream& operator>> (std::istream& in, Book& b)
{
string line;
getline (in, line);
if (!in.good())
return in;
int tab1 = line.find ("\t");
int tab2 = line.find ("\t", tab1+1);
string id = line.substr(0, tab1);
string author = line.substr (tab1+1, tab2-tab1-1);
string title = line.substr(tab2+1);
b.setID (id);
b.setAuthor (author);
b.setTitle (title);
return in;
}
main.cpp
using namespace std;
Catalog readCatalog(const string& fileName)
{
Catalog c;
ifstream in (fileName);
in >> c;
in.close();
return c;
}
Catalog mergeCatalogs (const Catalog& cat1, const Catalog& cat2)
{
Catalog result (cat1.size() + cat2.size());
int i = 0;
int j = 0;
while (i < cat1.size() && j < cat2.size())
{
Book b1 = cat1.get(i);
Book b2 = cat2.get(j);
if (b1.getID() < b2.getID())
{
result.add(b1);
++i;
}
else
{
result.add(b2);
++j;
}
}
while (i < cat1.size())
{
result.add(cat1.get(i));
++i;
}
while (j < cat2.size())
{
result.add(cat2.get(j));
++j;
}
return result;
}
void mergeCatalogFiles (const string& catalogFile1, const string& catalogFile2)
{
Catalog c1, c2;
c1 = readCatalog(catalogFile1);
cout << catalogFile1 << " contained " << c1.size() << " books." << endl;
c2 = readCatalog(catalogFile2);
cout << catalogFile2 << " contained " << c2.size() << " books." << endl;
Catalog c3 = mergeCatalogs (c1, c2);
cout << "Their merge contains " << c3.size() << " books." << endl;
cout << c3 << flush;
}
int main (int argc, char** argv)
{
if (argc != 3)
{
cerr << "Usage: " << argv[0] <<
"catalogFile1 catalogFile2" << endl;
return -1;
}
string file1 = argv[1];
string file2 = argv[2];
mergeCatalogFiles (file1, file2);
if (Counted::getCurrentCount() == 0)
{
cout << "No memory leak detected." << endl;
return 0;
}
else
{
cout << "Memory leak detected: " << Counted::getCurrentCount() << endl;
return -2;
}
}
Follow rule of zero: use std::vector<Book> to replace the array pointer and the size.
Your capacity is a limit on the size.
When at capacity. use equal range to find where to insert, replace last element then std rotate.
Managing both resources and business logic in the same class is bug prone. Do one thing at a time.
Try something more like this instead:
class Catalog
{
public:
Catalog (int maxCapacity = 100);
Catalog(const Catalog& c);
~Catalog();
int size() const;
int capacity() const;
void add (const Book &b);
Book* find(const std::string &bookID) const;
Catalog& operator= (Catalog c);
private:
Book* books;
int theCapacity;
int theSize;
void swap(Catalog &c);
};
#include "class.h"
#include <algorithm>
Catalog::Catalog(int maxCapacity)
{
theCapacity = maxCapacity;
theSize = 0;
books = new Book[theCapacity];
}
Catalog::Catalog(const Catalog& c)
{
theCapacity = c.theCapacity;
books = new Book[theCapacity];
for(int i = 0; i < c.theSize;; ++i)
books[i] = c.books[i];
theSize = c.theSize;
}
Catalog::~Catalog()
{
delete[] books;
}
Catalog& Catalog::operator= (const Catalog &c)
{
if (this != &c)
Catalog(c).swap(*this);
return *this;
}
void Catalog::swap(Catalog &c)
{
std::swap(books, c.books);
std::swap(theSize, c.theSize);
std::swap(theCapacity, c.theCapacity);
}
int Catalog::size() const
{
return theSize;
}
int Catalog::capacity() const
{
return theCapacity;
}
void Catalog::add (const Book &b)
{
Book *book = find(b.getID());
if (book) {
*book = b;
}
else if (theSize < theCapacity)
{
int i;
for (i = theSize; i && b < books[i-1]; --i) {
books[i] = books[i - 1];
}
books[i] = b;
++theSize;
}
// Debugging only
/*
for (int i = 0; i < theSize; ++i) {
cout << books[i] << endl;
}
*/
}
Book* Catalog::find(const std::string &bookID) const
{
for (int i = 0; i < theSize; ++i)
{
if (books[i].getID() == bookID)
return &books[i];
}
return 0;
}
That being said, this would be much simpler and easier to manage if you use std::vector and STL algorithms. Let the STL do the hard work for you:
#include <vector>
class Catalog
{
public:
Catalog (int initialCapacity = 100);
int size() const;
int capacity() const;
void add (const Book &b);
Book* find(const std::string &bookID) const;
private:
std::vector<Book> books;
};
#include "class.h"
#include <algorithm>
Catalog::Catalog(int initialCapacity)
{
books.reserve(initialCapacity);
}
int Catalog::size() const
{
return books.size();
}
int Catalog::capacity() const
{
return books.capacity();
}
void Catalog::add (const Book &b)
{
Book *book = find(b.getID());
if (book) {
*book = b;
}
else {
books.insert(std::upper_bound(books.begin(), books.end(), b), b);
}
// Debugging only
/*
for (Book &book: books) {
cout << book << endl;
}
*/
}
Book* Catalog::find(const std::string &bookID) const
{
auto iter = std::find_if(books.begin(), books.end(), [&bookID](const Book &b){ return (b.getID() == bookID); });
if (iter != books.end())
return &*iter;
return 0;
}
im working on a little scrabblegame which i read a txtfile and create a hashtable for all words inside. Word is a specific class which contains a vector of .
i want to create a hashmap by my own and define the length of my "Dictionary" is 50000. im using a nullpointer to reserve all index of my array. If i want to print to my hashtable, compiler tells me a segmentation fault. does any one seems the error?
the headerfile:
class Dictionary {
public:
Dictionary();
Dictionary(string filepath);
friend std::ostream& operator<<(std::ostream& os, const Dictionary& obj);
bool find(const Word& word);
vector<Word> allPossibleWords(const vector<Character>& tiles);
// struct compare {
//
// bool operator()(const Word& a, const Word& b) {
// return a.operator<(b);
// }
// } myCompare;
vector<Word> m_allWords;
vector<Word>::iterator itVecWords;
static const int table_size = 500000;
// std::array <Word*, table_size> arrWords = {nullptr};
Word* arrWords[table_size] = {nullptr};
int hash(Word new_word);
void addItem(Word word);
void printHashTable();
the cpp:
Dictionary::Dictionary(string filepath) {
ifstream datei(filepath.c_str());
while (datei.good() && !datei.eof()) {
string temp;
string temp1;
string::size_type pos;
getline(datei, temp);
pos = temp.find(" ");
temp1 = temp.substr(0, pos);
Word new_word(temp1);
addItem(new_word);
}
datei.close();
}
std::ostream& operator<<(std::ostream& os, const Dictionary& obj) {
for (int i = 0; i < obj.m_allWords.size(); i++) {
os << obj.m_allWords[i] << endl;
}
return os;
}
bool Dictionary::find(const Word& word) const {
if (std::binary_search(m_allWords.begin(), m_allWords.end(), word)) {
return true;
}
return false;
}
vector<Word> Dictionary::allPossibleWords(const vector<Character>& tiles) const {
vector<Word> ergebnis;
string tmp;
int cnt = 0;
for (int i = 0; i < tiles.size(); i++) {
tmp += tiles[i].GetC();
}
sort(tmp.begin(), tmp.end());
for (int i = 1; i <= tiles.size(); i++) {
do {
string piece = tmp.substr(0, i);
do {
Word search = Word(piece);
//Überschreibt immer der in Ergebnis existierte Wert
if (find(search) && std::find(ergebnis.begin(), ergebnis.end(), search) == ergebnis.end()) {
ergebnis.push_back(search);
}
} while (next_permutation(piece.begin(), piece.end()));
} while (next_permutation(tmp.begin(), tmp.end()));
}
return ergebnis;
}
int Dictionary::hash(Word new_word) {
int index = 0;
for (auto u : new_word.new_Character) {
index += (int) u.GetC();
}
index = index * (int) new_word.new_Character.at(0).GetC();
index = index * (int) new_word.new_Character.at(new_word.new_Character.size() - 1).GetC();
return index % table_size;
}
void Dictionary::addItem(Word word) {
int index = hash(word);
if (arrWords[index] == nullptr) {
arrWords[index] = new Word(word);
} else {
Word* ptr = arrWords[index];
Word* neu = new Word(word);
while (ptr->getNextWord() != nullptr) {
ptr = ptr->getNextWord();
}
ptr->setNextWord(neu);
}
}
void Dictionary::printHashTable() {
Word* tmp;
for (int i = 0; i < table_size; i++) {
tmp = arrWords[i];
if (tmp != nullptr) {
tmp->printWord();
cout << "Index : " << i;
}
tmp = tmp->getNextWord();
}
}
class Word {
public:
Word();
Word(string m_wort);
int length() const;
int points() const;
friend std::ostream& operator<<(std::ostream& os, const Word& obj);
bool operator==(const Word& right) const; /
bool operator!=(const Word& right) const;
bool contains(const Character& c) const;
Word substr(int start, int end) const;
bool operator<(const Word& right) const;
vector <Character> new_Character;
Word* Next = nullptr;
void setNextWord(Word*);
Word* getNextWord();
void printWord();
string getWordAsString();
CPP File:
void Word::setNextWord(Word* w) {
Next = w;
}
Word* Word::getNextWord() {
return Next;
}
void Word::printWord() {
string s = "";
for (int i = 0; i < new_Character.size(); i++) {
s += new_Character.at(i).GetC();
}
cout << s << endl;
}
string Word::getWordAsString() {
string s;
for (int i = 0; i < new_Character.size(); i++) {
s += new_Character.at(i).GetC();
}
return s;
}
I have method of class Stack, which compares 2 objects of this class:
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
and uses the method of class Time:
bool comparison(Time &time) {
if ((this->hours == time.hours) && (this->minutes == time.minutes) && (this->seconds == time.seconds))
return true;
return false;
When I try to use this comman in main:
bool temp = stack3.comparison(stack4);
MVS underlines |stack4| and shows me the error:
a reference of type "Time &"(non-const qualified) cannot be initialized with a value of type Stack<Time>
How could I handle this problem?
Thanks for your answers :)
There is class Stack:
class Stack {
private:
T *stackPr;
int size;
int top;
public:
//----------------CONSTRUCTORS-----------------
Stack(int n) {
if (n > 0)
size = n;
else
size = 10;
stackPr = new T[size];
top = -1;
}
Stack() {
size = 10;
stackPr = new T[size];
top = -1;
}
Stack(Stack &stack) {
stackPr = new T[stack.size];
size = stack.size;
top = stack.top;
for (int i = 0; i < size; i++)
stackPr[i] = stack.stackPr[i];
}
Stack(T *objs, int sizeMass) {
size = sizeMass;
stackPr = new T[size];
for (int i = 0; i < sizeMass; i++) {
this->push(objs[i]);
}
}
//----------------DESTRUCTOR-------------------
~Stack() {
delete[] stackPr;
}
//-----------------METHODS---------------------
//Add element to stack
void push(T &element) {
if (top == size - 1)
cout << "\nThere's no more place!!!\n";
else {
top++;
stackPr[top] = element;
cout << "\nElement was succesfully pushed\n";
}
}
//Read + Delete
T pop() {
if (top == -1)
cout << "\nStack is empty\n";
else {
T temp = stackPr[top];
stackPr[top] = 0;
top--;
cout << "\nElement was succesfully poped and deleted\n";
return temp;
}
}
//Read
T popup() {
if (top == -1)
cout << "\nStack is empty\n";
else {
cout << "\nElement was succesfully popped\n";
return stackPr[top];
}
}
//Comparison of 2 stacks
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
};
Try this, in your Stack class
change:
bool comparison(T &stack) {
for this:
bool comparison(Stack<T> &stack) {
First of all, abandon this comparison function, it hinders your code, use == instead.
Secondly, use const Stack<T> in your comparison function.
And finally, use auto to deduce the type of the variables.
Here is an example that shows the basics of what I just wrote:
#include <iostream>
using namespace std;
struct Time
{
bool operator==(const Time& time)
{
return true;// adjust it with your own needs.
}
};
template<typename T>
struct Stack
{
T val;
Stack(T& val_): val(val_) {}
bool operator==(const Stack<T>& stack)
{
return this->val == stack.val; // here is your business logic of comparison
}
};
int main()
{
Time t1;
Time t2;
Stack<Time> myStack1(t1);
Stack<Time> myStack2(t2);
auto temp = myStack1 == myStack2;
cout << temp << endl;
return 0;
}