I was assigned to create a chained hash table using a vector of vectors. It is designed to hold objects of type Entry. I have written all of the functions and the constructor but when I try to use the constructor that reads an input and then output it back to me in order of keys, whichever string was on the last line of the .txt file its reading from is gone. I think its a problem with my constructor because when I try to use get to get that specific value from the table before printing it its gone. I was hoping for some insight to where I might be going wrong from someone with a little more experience. Thanks. Heres my code:
Entry Header File:
#ifndef entry_h
#define entry_h
// entry.h - defines class Entry
#include <string>
#include <iosfwd>
class Entry {
public:
// constructor
Entry(unsigned int key = 0, std::string data = "");
// access and mutator functions
unsigned int get_key() const;
std::string get_data() const;
static unsigned int access_count();
void set_key(unsigned int k);
void set_data(std::string d);
// operator conversion function simplifies comparisons
operator unsigned int () const;
// input and output friends
friend std::istream& operator>>
(std::istream& inp, Entry &e);
friend std::ostream& operator<<
(std::ostream& out, Entry &e);
private:
unsigned int key;
std::string data;
static unsigned int accesses;
};
#endif /* entry_h */
Table header file:
//
// table.h
//
//
#ifndef table_h
#define table_h
#include <string>
#include <vector>
#include <algorithm>
#include "entry.h"
using namespace std;
class Table {
public:
Table(unsigned int max_entries = 100);
//Builds empty table to hold 100 entries
Table(unsigned int entries, std::istream& input);
//Builds table to hold entries, reads and puts them 1 at a time
~Table();
//Destructor
void put(unsigned int key, std::string data);
//Creates new entry for the table
//Updates if key is used
void put(Entry e);
//Creates a copy of e in the table
string get(unsigned int key) const;
//Returns string associated with key
//Returns empty string if key isnt used
bool remove(unsigned int key);
//Removes entry in given key
//Returns true of removed, false of no entry
int find(Entry e);
//index in second array that e exists, 0 if not found
friend std::ostream& operator<< (std::ostream& out, const Table& t);
//Prints each entry in the table in order of their key
private:
int size;
int num_entries;
unsigned int hashkey(unsigned int key) const;
vector<vector<Entry> > A;
};
#endif /* table_h */
Table Implementation File:
//table.cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include "table.h"
using namespace std;
Table::Table(unsigned int max_entries){
max_entries = 100;
size = max_entries * 2;
A.resize(size);
}
Table::Table(unsigned int entries, std::istream& input){
size = entries*2;
A.resize(size);
num_entries = entries;
Entry temp;
for (size_t i = 0; i < entries; i++) {
input >> temp;
put(temp);
}
}
Table::~Table() {
A.clear();
}
void Table::put(unsigned int key, std::string data){
Entry e;
e.set_key(key);
e.set_data(data);
put(e);
num_entries++;
}
void Table::put(Entry e) {
if (A[hashkey(e.get_key())].empty()) {
A[hashkey(e.get_key())].push_back(e);
}
else {
for(size_t i = 0; i < A[hashkey(e.get_key())].size(); i++) {
if (A[hashkey(e.get_key())][i].get_key() == e.get_key()) {
remove(A[hashkey(e.get_key())][i].get_key());
break;
}
}
A[hashkey(e.get_key())].push_back(e);
}
}
string Table::get(unsigned int key) const {
if( A[hashkey(key)].size() == 0) {
return "";
}
else {
for (size_t i = 0; i < A[hashkey(key)].size(); i++) {
if (A[hashkey(key)][i].get_key() == key) {
return A[hashkey(key)][i].get_data();
}
else {
return "";
}
}
}
}
bool Table::remove(unsigned int key) {
for (size_t i = 0; i < A[hashkey(key)].size(); i++) {
if (A[hashkey(key)][i].get_key() == key) {
swap(A[hashkey(key)][i],A[hashkey(key)][A[hashkey(key)].size() - 1]);
A[hashkey(key)].pop_back();
num_entries--;
return true;
}
else {
return false;
}
}
}
int Table::find(Entry e) {
for (size_t i = 0; i < A[hashkey(e.get_key())].size(); i++) {
if (A[hashkey(e.get_key())][i] == e) {
return i;
}
else {
return 0;
}
}
}
ostream& operator << (ostream& out, const Table& t) {
vector<Entry> order;
for(size_t i = 0; i < t.A.size(); i++) {
for (size_t j = 0; j < t.A[i].size(); j++) {
order.push_back(t.A[i][j]);
}
}
sort(order.begin(), order.end());
for(Entry k: order) {
out << k << endl;
}
return out;
}
unsigned int Table::hashkey(unsigned int key) const{
const double c = 1.61803;
// return key % size;
return (int)(size*((key * c) - (int)(key * c)));
}
Related
I'm working on an x/y coordinate maze solving project.
I have a problem with my Maze object, whose data members are locations which also are objects of int row, int col and enum Direction {right down left up done}.
When I run my debugger, error messages come up that say "invalid use of this outside of non static member function" on the Maze object.
Why is this coming up? I don't understand how this message is showing if I'm not using any this->endLocation statement anywhere in my Maze.cpp file.
#include "maze-proj1.h"
using namespace std;
Maze::Maze() {
validLocationCount = 0;
validLocations = NULL;
startLocation = endLocation;
}
Maze::~Maze() {
if(validLocations != NULL) {
delete [] validLocations;
}
validLocations = NULL;
validLocationCount = 0;
}
Location Maze::getStartLocation() const {
return startLocation;
}
bool Maze::isValidLocation(const Location &loc) const {
int count = 0;
for (int i = 0; i < validLocationCount; i++) {
if (loc == validLocations[i]) {
count++;
}
}
if (count == validLocationCount){
return true;
}
return false;
}
bool Maze::isEndLocation(const Location &loc) const {
return loc == endLocation;
}
istream &operator>>(istream &is, Maze &m) {
is >> m.validLocationCount;
m.validLocations = new Location[m.validLocationCount];
for(int i = 0; i < m.validLocationCount; i++){
is >> m.validLocations[i];
}
is >> m.startLocation;
is >> m.endLocation;
}
class Maze {
public:
Maze(void);
~Maze();
Location getStartLocation(void) const;
bool isValidLocation(const Location &loc) const;
bool isEndLocation(const Location &loc) const;
friend istream &operator>>(istream &is, Maze &m);
private:
Maze(const Maze &) { assert(false); }
const Maze &operator=(const Maze &)
{ assert(false); return *this; }
int validLocationCount;
Location *validLocations;
Location startLocation, endLocation;
};
#endif
In the code shown below, in the function void printExpensiveThanT(..) i'm supposed to print out the destination, distance and the price for the offers which are more expensive than the offer T in the function, sorted in ascending order by the distance value.
I'm not sure what should i use to sort them, i experimented something with vectors but it didn't work out so i deleted it.
Any help would be appreciated.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
class Transport {
protected:
char destination[100];
int basePrice;
int distance;
public:
Transport() {}
Transport(char *destination, int basePrice, int distance) {
strcpy(this->destination, destination);
this->basePrice = basePrice;
this->distance = distance;
}
virtual ~Transport() {}
virtual int priceTransport() = 0;
friend bool operator<(const Transport &t1, const Transport &t2) {
return t1.distance<t2.distance;
}
int getDistance(){ return distance; }
char *getDestination() { return destination; }
int getPrice() { return basePrice; }
};
class AutomobileTransport : public Transport {
private:
bool ifDriver;
public:
AutomobileTransport() {}
AutomobileTransport(char *destination, int basePrice,int distance, bool ifDriver) : Transport(destination,basePrice,distance) {
this->ifDriver = ifDriver;
}
void setIfDriver(bool ifDriver) {
this->ifDriver = ifDriver;
}
bool getIfDriver() {
return ifDriver;
}
int priceTransport() {
if(ifDriver) {
basePrice+=basePrice*20/100;
}
return basePrice;
}
friend bool operator<(const AutomobileTransport &a1, const AutomobileTransport &a2) {
return a1.distance<a2.distance;
}
};
class VanTransport: public Transport {
private:
int passengers;
public:
VanTransport() {}
VanTransport(char *destination, int basePrice, int distance, int passengers) : Transport(destination, basePrice, distance) {
this->passengers = passengers;
}
void setPassengers(int passengers) {
this->passengers = passengers;
}
int getPassengers() {
return passengers;
}
int priceTransport() {
for(int i = 0; i < passengers; i++) {
basePrice-=200;
}
return basePrice;
}
friend bool operator<(const VanTransport &k1, const VanTransport &k2) {
return k1.distance<k2.distance;
}
};
void printExpensiveThanT(Transport **offers,int n,AutomobileTransport &T) {
Transport *tmp;
for(int i = 0; i <= n; i++){
if(offers[i]->priceTransport() > T.priceTransport())
cout<<offers[i]->getDestination()<<" "<<offers[i]->getDistance()<<" "<<offers[i]->getPrice()<<endl;
}
}
int main() {
char destination[20];
int type,price,distance,passengers;
bool driver;
int n;
cin>>n;
Transport **offers;
offers=new Transport *[n];
for (int i=0; i<n; i++) {
cin>>type>>destination>>price>>distance;
if (type==1) {
cin>>driver;
offers[i]=new AutomobileTransport(destination,price,distance,driver);
} else {
cin>>passengers;
offers[i]=new VanTransport(destination,price,distance,passengers);
}
}
AutomobileTransport at("Ohrid",2000,600,false);
printExpensiveThanT(offers,n,at);
for (int i=0; i<n; i++) delete offers[i];
delete [] offers;
return 0;
}
Since you're dealing with pointers, the easiest thing to do is to use std::vector and std::sort:
#include <vector>
//...
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(),
[](Transport* left, Transport* right) { return *left < *right; });
// print out the values
for (auto it : sortedVect)
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
}
Also, your original code looped one more than it should (i <= n was wrong).
Edit:
If your compiler doesn't support the C++ 11 syntax, here is an alternate solution:
#include <vector>
//...
bool Sorter(Transport* left, Transport* right)
{ return *left < *right; }
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(), Sorter);
// print out the values
std::vector<Transport*>::iterator it = sortedVect.begin();
while (it != sortedVect.end())
{
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
++it;
}
}
in my C++ class we are finally getting conceptually fairly deep (well, relatively!) and I'm struggling with building a class from a previous class.
Here is my first class header, which builds partially filled array objects. To my knowledge, it is fully functional:
#ifndef PARTIALARRAY_H
#define PARTIALARRAY_H
#include <iostream>
#include <string.h>
using namespace std;
typedef int ITEM_TYPE;
ITEM_TYPE const MAX = 50;
class PartialArray
{
public:
//-----------------------------------------ctors:-----------------------------------------
PartialArray();
PartialArray(const int init[], int used);
//-----------------------------------------member functions:-----------------------------------------
void PrintArray();
int Search(ITEM_TYPE key);
int Append(ITEM_TYPE appendMe);
int ShiftRight(int shiftHere);
int ShiftLeft(int shiftHere);
int InsertBefore(ITEM_TYPE insertThis, int insertHere);
int InsertAfter(ITEM_TYPE insertThis, int insertHere);
int Delete(int deleteHere);
void DeleteRepeats();
int NumUsed();
void Sort();
void Reverse();
string ErrorDescr(int failCode);
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& operator [] (ITEM_TYPE x);
private:
//-----------------------------------------member vars:-----------------------------------------
ITEM_TYPE a[MAX];
int numUsed;
};
#endif // PARTIALARRAY_H
And here are the class functions:
#include "partialarray.h"
#include <iostream>
#include <string.h>
using namespace std;
//-----------------------------------------ctors:-----------------------------------------
PartialArray::PartialArray()
{
numUsed=0;
}
PartialArray::PartialArray(const int init[], int used)
{
numUsed = used;
for(int i=0; i<numUsed; i++)
{
a[i]=init[i];
}
}
//-----------------------------------------member functions:-----------------------------------------
//Prints the array up to its last used element
void PartialArray::PrintArray()
{
for(int i=0; i<numUsed; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
//Searches the array for a particular value and returns the index at which the value first appears
int PartialArray::Search(ITEM_TYPE key)
{
for(int i=0; i<numUsed; i++)
{
if(a[i]==key)
return i;
}
return -1;
}
//Takes a number and appends it to the end of the array after the last interesting element
int PartialArray::Append(ITEM_TYPE appendMe)
{
if(numUsed<MAX)
a[numUsed++] = appendMe;
else
return 1;
return 0;
}
//Shifts all elements of the array to the right starting at a particular index
int PartialArray::ShiftRight(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[numUsed-1];
for(int i=numUsed; i>=shiftHere; i--)
{
a[i] = a[i-1];
}
a[shiftHere] = save;
return 0;
}
else
return 2;
}
//Shifts all elements of the array to the left starting at a particular index
int PartialArray::ShiftLeft(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[shiftHere];
for(int i=shiftHere; i<numUsed; i++)
{
a[i] = a[i+1];
}
a[numUsed-1] = save;
return 0;
}
else
return 2;
}
//Takes a number and a position and inserts the number before that position in the array shifting the elements to the right
int PartialArray::InsertBefore(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else
{
numUsed++;
ShiftRight(insertHere);
a[insertHere] = insertThis;
}
return 0;
}
//Takes a number and a position and inserts the number after that position in the array shifting the elements to the right
int PartialArray::InsertAfter(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else if(numUsed>=MAX)
return 1;
else
{
numUsed++;
ShiftRight(insertHere+1);
a[insertHere+1] = insertThis;
}
return 0;
}
//Takes a position and removes that item from the array, shifting all the elements to the left
int PartialArray::Delete(int deleteHere)
{
if(deleteHere <= numUsed)
{
ShiftLeft(deleteHere);
numUsed--;
return 0;
}
else
return 2;
}
//Deletes repeated elements in the array and replaces the with 0
void PartialArray::DeleteRepeats()
{
for(int i=0;i<numUsed;i++)
{
ITEM_TYPE n=a[i];
for(int j=i+1; j<numUsed;j++)
{
if(n == a[j])
{
Delete(j);
j--;
}
}
}
}
//Returns number of interesting elements in the array
int PartialArray::NumUsed()
{
return numUsed;
}
//Utilizes a bubble sort algorithm
void PartialArray::Sort()
{
bool swap = true;
int j = 0;
int save;
while (swap==true)
{
swap = false;
j++;
for (int i = 0; i < numUsed - j; i++)
{
if (a[i] > a[i + 1])
{
save = a[i];
a[i] = a[i + 1];
a[i + 1] = save;
swap = true;
}
}
}
}
void PartialArray::Reverse()
{
for(int i=0;i<numUsed-1;i++)
{
ITEM_TYPE save = a[numUsed-1];
ShiftRight(i);
a[i] = save;
}
}
//Returns the appropriate error description for a particular fail code
string PartialArray::ErrorDescr(int failCode)
{
switch(failCode)
{
case -1:
return "ERROR: item not found";
break;
case 1:
return "ERROR: array is full";
break;
case 2:
return "ERROR: unused index";
break;
default:
return "UNKNOWN ERROR";
break;
}
}
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& PartialArray::operator [](ITEM_TYPE x)
{
return a[x];
}
Now, here is where things have gotten tricky. To build the two dimensional array class, I'm supposed to create an array of arrays. I'm at a loss as to how I should go about this, and after tinkering and googling for a few hours I've only become more confused. Specifically, the <<, [], and [](constant version) operators and the TwoDArray constructor have thrown me for a loop, and I'm stuck without much sense of what to do next. Here is the TwoD header file:
#ifndef TWODARRAY_H
#define TWODARRAY_H
#include "partialarray.h"
#include <iostream>
#include <string.h>
typedef int ITEM_TYPE;
class TwoDArray
{
friend ostream& operator << (ostream &outs, const TwoDArray& printMe);
public:
//ctors:
TwoDArray();
//member functions:
//PartialArray& operator [](int index); //[ ] operator for the TwoDArray object
//PartialArray operator [](int index) const; //[ ] operator for the TwoDArray object (const version)
int Append(int appendMe, int row);
int InsertBefore(int insertMe, int row, int column);
int InsertAfter(int insertMe, int row, int column);
int Delete(int row, int column);
bool Search(ITEM_TYPE key, int &row, int &column);
private:
//member vars:
PartialArray a[MAX];
};
#endif // TWODARRAY_H
And this is what I've tried to define thus far:
TwoDArray::TwoDArray()
{
const int array0[]= {0};
PartialArray array(array0, MAX);
}
ostream& operator << (ostream &outs, const TwoDArray& printMe)
{
for(int i=0;i<MAX;i++)
{
outs << printMe.a[i];
}
return outs;
}
Ideally, the << operator will print an m by n array of items.
Constraints: Cannot use STL for dynamic array implementation.
I've been stuck on this problem for a while now and my research into the answer hasn't yielded anything fruitful yet. Any help would be greatly appreciated!
So I'm trying to write a program that will generate recommendations to users based on the way they have rated various books. In order to do that I need to be able to read in a .txt file that contains a list of authors and titles of books. The format of the .txt is "Author,Book" with each entry on its own line.
I want to fill a dynamic array with Book class objects as I read from the .txt file. Because STL is not allowed for this project, I needed to write my own implementation.
The processing of the file went alright, I was able to display the author and book of each entry on separate lines using cout.
Now I am stuck trying to fill my dynamic array elements with the entries. My class to hold the data is Book and contains a struct of data members.
I am suspicious that the problem is with my function in my dynamic array template implementation.
template<class Recommend>
void DArray<Recommend>::add(const Recommend &obj)
I will eventually want to use this template to hold class objects for users and ratings.
Right now my code appears to fill the array with the proper number of entries, but all but the last element are fill with what looks like Book objects from the default constructor.
Here is the relevant code:
P1.cpp:
//P1.cpp
#include "stdafx.h"
#include "Book.h"
#include "Member.h"
#include "Rating.h"
#include <iostream>
#include <fstream>
using namespace std;
void readBooks(string bookTxt)
{
Book newBook;
DArray<Book> bookArray;
string line;
ifstream file(bookTxt);
if (file.is_open())
{
while (!(file.eof()))
{
getline(file, line, ',');
newBook.bookData.author = line;
getline(file, line, '\n');
newBook.bookData.title = line;
newBook.bookData.year = 2004; //Place holder
newBook.setIsbn();
bookArray.add(newBook);
}
for (int i = ZERO; i < 55; i++)
{
cout << bookArray[i].bookData.author << endl;
cout << bookArray[i].bookData.title << endl;
cout << bookArray[i].bookData.year << endl;
cout << bookArray[i].bookData.isbn << endl;
}
file.close();
}
else cout << "Error: Unable to open file";
}
int main()
{
readBooks("books.txt");
int wait;
cin >> wait;
return 0;
}
Book.h
//Book.h
#ifndef BOOK_H
#define BOOK_H
#include <string>
using namespace std;
const int ZERO = 0;
const int ONE = 1;
template<class Recommend>
class DArray
{
private:
Recommend *array;
int size;
int bitSize;
public:
DArray()
{
size = ZERO;
array = new Recommend[ONE];
}
DArray(int initSize)
{
size = initSize;
array = new Recommend[size];
}
~DArray()
{
delete[] array;
}
DArray(const DArray &rhs);
DArray &operator= (const DArray &rhs);
DArray &operator= (const Recommend &rhs);
Recommend& operator[] (int index);
void add(const Recommend &obj);
int getSize();
void setSize(int size);
void clear();
void remove(int index);
void* getPtr();
};
class Book
{
//Generate a unique int for book ISBN
int generateIsbn();
public:
struct data
{
unsigned long int isbn;
int year;
string title, author;
};
data bookData;
//Constructors (Default and Initializing)
Book()
{
bookData.author = "";
bookData.title = "";
bookData.isbn = ZERO;
bookData.year = ZERO;
}
Book(int initYear, string initTitle, string initAuthor)
{
bookData.author = initAuthor;
bookData.title = initTitle;
bookData.year = initYear;
bookData.isbn = generateIsbn();
}
//Book File IO Functions
void loadFile(ifstream books) const;
void saveFile(ofstream &books);
//Mutator Functions
void addBook(int addYear, string addTitle, string addAuthor);
void setIsbn();
void setYear(data bookData);
void setTitle(data bookData);
void setAuthor(data bookData);
//Accessor Functions
Book getBook(data bookData) const;
unsigned long int getIsbn() const;
int getYear() const;
string getTitle() const;
string getAuthor() const;
};
template<class Recommend>
DArray<Recommend>::DArray(const DArray &rhs)
{
size = rhs.size;
array = new Recommend[size];
for (int i = ZERO; i < size; i++)
array[i] = rhs.array[i];
}
template<class Recommend>
Recommend& DArray<Recommend>::operator[] (int index)
{
return array[index];
}
template<class Recommend>
DArray<Recommend>& DArray<Recommend>::operator= (const DArray &rhs)
{
if (this == &rhs)
return *this;
//if (rhs.size == ZERO)
//clear();
setSize(rhs.size);
for (int i = ZERO; i < size; i++)
array[i] = rhs.array[i];
return *this;
}
template<class Recommend>
DArray<Recommend>& DArray<Recommend>::operator= (const Recommend &rhs)
{
if (this == &rhs)
return *this;
array[size] = rhs;
return *this;
}
template<class Recommend>
int DArray<Recommend>::getSize()
{
return size;
}
template<class Recommend>
void DArray<Recommend>::setSize(int resize)
{
if (resize < 0)
{
Recommend *temp;
temp = new Recommend(resize);
for (int i = ZERO; i < resize; i++)
temp[i] = array[i];
delete[] array;
array = temp;
size = resize;
}
else
clear();
}
template<class Recommend>
void DArray<Recommend>::add(const Recommend &obj)
{
if (size == ZERO)
{
array[ZERO] = obj;
size++;
}
else
{
int newSize = (size + ONE);
Recommend *temp;
temp = new Recommend[newSize];
for (int i = ZERO; i < (size - ONE); i++)
temp[i] = array[i];
temp[(newSize - ONE)] = obj;
delete[] array;
size = newSize;
array = temp;
}
}
template<class Recommend>
void DArray<Recommend>::remove(int index)
{
if (index <= ZERO)
{
if (size == ONE)
clear();
else
{
for (int i = index; i < (size - ONE); i++)
array[i] = array[i + ONE];
size--;
}
}
}
template<class Recommend>
void DArray<Recommend>::clear()
{
delete[] array;
size = 0;
}
template<class Recommend>
void* DArray<Recommend>::getPtr()
{
return array;
}
#endif
Book.cpp:
//Book.cpp
#include "stdafx.h"
#include "Book.h"
const unsigned long int ISBN_MIN = 100000;
const unsigned long int ISBN_MAX = 999999;
//Generate a unique isbn
int Book::generateIsbn()
{
unsigned long long int isbn;
isbn = this->bookData.title.length();
isbn += this->bookData.title.size();
isbn += this->bookData.author.length();
isbn += this->bookData.title.capacity();
isbn += this->bookData.author.size();
isbn += this->bookData.author.capacity();
isbn *= this->bookData.year;
isbn = isbn % ISBN_MAX + ISBN_MIN;
isbn += this->bookData.author[ONE];
isbn += this->bookData.title[ONE];
isbn += this->bookData.author[ZERO];
isbn += this->bookData.title[ZERO];
static_cast<int>(isbn);
return isbn;
}
void Book::addBook(int addYear, string addTitle, string addAuthor)
{
bookData.author = addAuthor;
bookData.title = addTitle;
bookData.year = addYear;
bookData.isbn = generateIsbn();
}
unsigned long int Book::getIsbn() const
{
return bookData.isbn;
}
void Book::setIsbn()
{
this->bookData.isbn = generateIsbn();
}
A sample of book.txt
Neil Shusterman,The Shadow Club
Jeff Smith,Bone Series
Art Spiegelman,Maus: A Survivor's Tale
Amy Tan,The Joy Luck Club
J R R Tolkien,The Lord of the Rings
J R R Tolkien,The Hobbit
Eric Walters,Shattered
H G Wells,The War Of The Worlds
Patricia C. Wrede,Dealing with Dragons
John Wyndham,The Chrysalids
Sample of the output:
0
0
0
0
0
0
0
0
John Wyndham
The Chrysalids
2004
360893
I feel bad about asking for help, but I'm really stuck here. Thank you in advance.
Inside DArray::add when you copy the values from the old array you check for i < (size - ONE), that skips the last item, since you do it each time you add an item nothing gets copied and only the last item added remains.
This main program should ask the user to put in some numbers and store them into a dynamic array. The array should then be outputted its contents in a straight line, no end line commands, with a comma in between. I can't figure out how to start the program.
If you guys can help me find a way to do this, I would be eternally thankful!
Here is ListType.h:
#ifndef LISTTYPE_H_INCLUDED
#define LISTTYPE_H_INCLUDED
#include <iostream>
class ListType {
public:
ListType(size_t=10);
virtual ~ListType();
virtual bool insert(int)=0;
virtual bool erase();
virtual bool erase(int)=0;
virtual bool find(int) const=0;
size_t size() const;
bool empty() const;
bool full() const;
void output(std::ostream& out) const;
friend std::ostream& operator << (std::ostream&, const ListType&);
protected:
int *items;
size_t capacity;
size_t count;
};
#endif // LISTTYPE_H_INCLUDED
here is UListType.h:
#ifndef ULISTTYPE_H_INCLUDED
#define ULISTTYPE_H_INCLUDED
#include <iostream>
class UListType: public ListType {
public:
UListType(size_t=10);
bool insert(int);
bool erase(int);
bool find(int) const;
};
#endif // ULISTTYPE_H_INCLUDED
here is OListType.h:
#ifndef OLISTTYPE_H_INCLUDED
#define OLISTTYPE_H_INCLUDED
#include <iostream>
class OListType: public ListType {
public:
OListType(size_t=10);
bool insert(int);
bool erase(int);
bool find(int) const;
};
#endif // OLISTTYPE_H_INCLUDED
here is ListType.cpp:
#include "ListType.h"
ListType::ListType (size_t a) {
capacity = a;
count = 0;
items = new int [capacity];
}
ListType::~ListType() {
delete [] items;
}
bool ListType::erase() {
count = 0;
return 0;
}
size_t ListType::size() const {
return (count);
}
bool ListType::empty() const {
return (count == 0);
}
bool ListType::full() const {
return (count == capacity);
}
void ListType::output(std::ostream& out) const {
for (int i = 0; i < count; i++) {
if (i > 0) {
out << ", ";
}
out << items[i];
}
}
std::ostream& operator << (std::ostream& out, const ListType& my_list) {
my_list.output(out);
return out;
}
here is UListType.cpp
#include "ListType.h"
#include "UListType.h"
UListType::UListType (size_t c): ListType(c) {}
bool UListType::insert(int item) {
if (full()) {
int *newitems;
capacity *=2;
newitems = new int[capacity];
for (size_t i =0; i < count; ++i){
newitems[i] = items[i];
}
delete [] items;
items = newitems;
}
items[count++] = item;
return true;
}
bool UListType::erase(int item) {
bool result = false;
size_t i=0;
while ( i < count && items [i] != item) {
++i;
}
if (i < count) {
items[i] = items[-- count];
result = true;
}
return result;
}
bool UListType::find(int item) const {
size_t i = 0;
while (i < count && items [i] != item) {
++i;
}
return i;
}
here is OListType.cpp
#include "ListType.h"
#include "OListType.h"
OListType::OListType(size_t c): ListType(c) {}
bool OListType::insert(int item) {
size_t i = count;
if (full()) {
int *newitems;
capacity *=2;
newitems = new int[capacity];
while (i > 0 && items[i-1] > item){
newitems[i] = items[i];
}
delete [] items;
items = newitems;
}
items[count++] = item;
return true;
}
bool OListType::erase(int item) {
bool found=false;
size_t i=0, j= count-1, mid;
while (i <= j && !(found)){
mid = (i + j)/2;
if (item < items [mid])
j = mid - 1;
else if (item > items [mid])
i = mid + 1;
found = items [mid] == item;
}
if (found) {
for (i = mid; i < count - 1; ++i) {
items [i] = items [i +1];
}
--count;
}
return found;
}
bool OListType::find (int item) const {
bool found=false;
size_t i=0, j= count-1, mid;
while (i <= j && !(found)){
mid = (i + j)/2;
if (item < items [mid])
j = mid - 1;
else if (item > items [mid])
i = mid + 1;
found = items [mid] == item;
}
return found;
}
#include "ListType.h"
#include "UListType.h"
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
int main()
{
UListType UL;
cout << "How many numbers do you want to put it?" << endl;
int n;
cin >> n;
cout << "All right, enter " << n << " numbers:" << endl;
int x;
for(int k=0; k<n; ++k)
{
cin >> x;
// do something with x
}
return(0);
}
You already have everything you need. Try the following
#include <iostream>
#include "OListType.h"
using namespace std;
int main()
{
OListType list;
int n;
do
{
cout << "Add a number [Y/n]?";
char a;
cin >> a;
if (a != 'n')
{
cin >> n;
list.insert(n);
}
else
{
list.output(cout);
break;
}
}while (1);
return 0;
}