Sorting Vector(Bubble sort) c++ - c++

I have class Date, functions bubbleSort, isAfter and printVector. So my task is: Use the function bubbleSort to sort vector type objects Date(using function isAfter which compares dates). I've done something but it doesn't works, so can anyone help me with this?
Function bubble sort(doesn't works with "Date", works fine with integers ,strings...).
Here is my code:
//isAfter
template<>
bool isAfter(const Date &first, const Date &second) {
if (first.getYear() == second.getYear()) {
if (first.getMonth() == second.getMonth()) {
if (first.getDay() == second.getDay()) {
cout << first.toString() << " is equal to " << second.toString() << endl;
return false;
} else if (first.getDay() > second.getDay()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getDay() < second.getDay()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
} else if (first.getMonth() > second.getMonth()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getMonth() < second.getMonth()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
} else if (first.getYear() > second.getYear()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getYear() < second.getYear()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
return false;
}
//bubbleSort
template<typename T>
void bubbleSort(vector<T> &vec) {
bool swapp= true;
while (swapp) {
swapp= false;
for (unsigned int i = 0; i < vec.size()- 1; i++) {
if (vec[i] > vec[i + 1]) {
swap(vec[i], vec[i + 1]);
swapp = true;
}
}
}
}
so how can i add isAfter in bubbleSort to work fine with "Date" objects?

If this is always the sort order for dates and you control that type, you could implement the comparison operators operator<, operator>, operator<=, operator>=, operator== and operator!= for that type.
Otherwise, the conventional approach is to modify your sorting algorithm to accept a custom comparator (by convention, having the interface of operator<, which requires you to flip your comparison) from its callers, something like:
template <typename T, typename Compare>
void bubbleSort(vector<T> &vec, Compare compare) {
// as you currently have, but using compare(a, b) instead of a < b
}
template <typename T>
void bubbleSort(vector<T> &vec) {
bubbleSort(vec, std::less<>());
}
Then callers can use isAfter like this:
bubbleSort(dates, [](const Date& a, const Date& b) { return isAfter(b, a); });

Related

How to Skip Parsing of Token in Rapidjson

I have to Parse only certain Tokens in Data Structure using RapidJson.And skip other tokens to save time.
For eg. How to parse only "t" token without parsing other tokens
{
"hello": "world",
"t": true ,
"f": false,
"n": null,
}
I am using Iterative Parsing ,How do I parse only a certain token 'Key' .I have tried checking the 'Key' value to my required token and then retuening from code but program stopped executing.
struct MyHandler : public BaseReaderHandler<UTF8<>, MyHandler> {
bool Null() { cout << "Null()" << endl; return true; }
bool Bool(bool b) { cout << "Bool(" << boolalpha << b << ")" << endl; return true; }
bool Int(int i) { cout << "Int(" << i << ")" << endl; return true; }
bool Uint(unsigned u) { cout << "Uint(" << u << ")" << endl; return true; }
bool Int64(int64_t i) { cout << "Int64(" << i << ")" << endl; return true; }
bool Uint64(uint64_t u) { cout << "Uint64(" << u << ")" << endl; return true; }
bool Double(double d) { cout << "Double(" << d << ")" << endl; return true; }
bool String(const char* str, SizeType length, bool copy) {
cout << "String(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
return true;
}
bool StartObject() { cout << "StartObject()" << endl; return true; }
bool Key(const char* str, SizeType length, bool copy) {
cout << "Key(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
return true;
}
bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl;
return true; }
bool StartArray() { cout << "StartArray()" << endl; return true; }
bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl;
return true; }
};
//char* readBuffer is my json data in char array
MyHandler handler;
Reader reader;
StringStream ss(readBuffer);
reader.IterativeParseInit();
while (!reader.IterativeParseComplete()) {
reader.IterativeParseNext<kParseDefaultFlags>(ss, handler);
}
Thank You
You must maintain a state in your Handler set / unset depending if you have encountered the key you want to pass.
It is not straightforward because you must take into account that you can encounter the same key at various (nested) level.
If really you want to continue in this direction you can have a look in rapidjson example here https://github.com/Tencent/rapidjson/tree/master/example/filterkey
This make the opposite of your need, parsing everything except the given key. That should give you a good starting point.
Another solution is to use DOM parsing and "clean" after parsing the unwanted keys, which is much more easier. Off course it will not have the same performance but at least you will free memory associated with token you do not need.
auto itr = myDoc.MemberBegin();
while (itr != myDoc.MemberEnd())
{
if (itr->name == "keyIWantToKeep")
itr++;
else
itr = myDoc.EraseMember(itr);
}

How would you insert a number in a specific place in an array?

#include <iostream>
class Vector
{
public:
int size;
int* contents;
int capacity;
Vector();
~Vector();
void PushFront(int value);
//void Vector(int initialCapacity);
void PushBack(int value);
int& At(int index);
int& operator[](int index);
void Clear();
int Size();
bool IsEmpty();
void Resize(int newSize);
void Reserve(int newCapacity);
int GetCapacity();
void EraseAt(int index);
void Erase(int value);
int Find(int value);
bool Contains(int value);
void Insert(int value, int index);
};
So these are the function declarations I used for the other file, these are included for reference.
#pragma once
#include <iostream>
#include <string>
#include "Header.h"
//double* vPointer;
double* vPointer;
int* myArray[];
Vector::Vector()
{
std::cout << "Vector Class Created." << std::endl;
capacity = 10,
contents = new int[capacity],
size = 0;
}
Vector::~Vector() // Deallocates any memory the container needed to allocate
{
delete[] vPointer;
std::cout << "Vector Class Deallocated." << std::endl;
}
void Vector::PushFront(int value) // Adds a single value to beginning of the container
{
for (int i = 0; i <= size; ++i)
{
if (value < vPointer[capacity])
{
Reserve(capacity + 1);
}
if (i == value)
{
std::cout << "testing." << std::endl;
}
if (i > value)
{
std::cout << "testing (code 2)." << std::endl;
}
}
}
void Vector::PushBack(int value) // Adds a single value to end of the container
{
if (size == capacity)
{
Reserve(capacity + 1);
}
contents[size] = value;
size++;
};
void Vector::Reserve(int newCapacity) // Allocates room for at least this many values. Does not shrink the storage
{
if (capacity < newCapacity)
{
int* newArray = new int[newCapacity];
for (int i = 0; i < size; i++)
{
newArray[i] = contents[i];
}
delete[] contents;
contents = newArray;
capacity = newCapacity;
}
}
int& Vector::At(int index) // Return a reference to the element at the given index. If unable, throws an exception.
{
return contents[index];
}
int& Vector::operator[](int index) // Return a reference to the element at the given index. If unable, throws an exception.
{
std::cout << contents[index] << std::endl;
return contents[index];
}
void Vector::Clear() // Remove all elements from the container
{
size = 0;
}
int Vector::Size() // Returns the number of elements in this container
{
return size;
std::cout << size;
}
bool Vector::IsEmpty() // Returns whether or not the container has any elements
{
std::cout << "Container has the following number of elements: " << vPointer << std::endl;
return vPointer;
}
void Vector::Resize(int newSize) // Adds or removes elements from the end of the container to achieve the given new size
{
if (newSize < size)
{
size == newSize;
std::cout << newSize << std::endl;
}
else if (newSize > capacity)
{
Reserve(newSize);
size == newSize;
return;
}
else
{
std::cout << "something went wrong! Attempting to ReSize Anyways..." << std::endl;
size = newSize;
std::cout << "Vector Resized. newSize = " << newSize << std::endl;
}
}
int Vector::GetCapacity() // Returns the amount of allocated space
{
return capacity;
}
void Vector::EraseAt(int index) // Removes the value at the given index, decreasing the contained size
{
for (int i = 0; i < size; i++)
{
if (vPointer[i] == index)
{
std::cout << "semi-functional." << std::endl;
}
}
}
void Vector::Erase(int value) // Removes one value from the container: the first that matches
{
for (int i = 0; i < size; i++)
{
if (value == vPointer[i])
{
vPointer[i] = vPointer[i + 1];
}
else
{
//cout << "can't erase a value that does not exist." << endl;
return;
}
}
}
int Vector::Find(int value) // Returns the index of the given value, -1 if not found
{
for (int i = 0; i < size; i++)
{
if (value == vPointer[i])
{
std::cout << "Value Found : " << i << std::endl;
return i;
}
else
{
return -1;
std::cout << "Value Not Found" << std::endl;
}
if (value != vPointer[i])
{
std::cout << "Value Found : " << i << std::endl;
return i;
}
}
}
bool Vector::Contains(int value) // Returns true if this value is in the container
{
for (int i = 0; i < size; i++)
{
if (value < size)
{
std::cout << "The Value " << value << " Is In The Container." << std::endl;
return value;
return true;
}
else
{
std::cout << "The Value Is Not Within The Container." << std::endl;
return false;
}
}
}
void Vector::Insert(int value, int index) // Insert the given element at the given position. Position 0 should insert the element at the beginning of the container
{
}
Its Here ^^^ where I'm having the problems. Some of the things I try to program don't want to work at all, and I can't use the because the project is to make a 'vector' class using arrays. I'm lost as how to insert an integer into an array in this case, because I can't find the array that we allocated. Teacher says its here, but I can't seem to call it at all.
#include <iostream>
#include "Header.h"
#include <vector>
//using namespace std;
int main(int argc, char* argv[])
{
Vector myVector;
std::cout << "Initializing 'Vector' Array..." << std::endl;
std::cout << " " << std::endl;
std::cout << "myVector.PushBack():" << std::endl;
//myVector.PushBack
myVector.PushBack(3);
std::cout << "Should be 3: " << myVector.At(0) << std::endl;
std::cout << " " << std::endl;
std::cout << "myVector.Reserve():" << std::endl;
//myVector.Reserve
std::cout << "Capacity: " << myVector.capacity << std::endl;
myVector.Reserve(15);
std::cout << "Should allocate 5 slots in the array: " << std::endl;
std::cout << "New Capacity: " << myVector.capacity << std::endl;
//myVector.At
std::cout << " " << std::endl;
std::cout << "myVector.At():" << std::endl;
std::cout << "Testing myVector.At(#) with value of 0... : " << myVector.At(0) << std::endl;
//myVector GetCapacity
std::cout << " " << std::endl;
std::cout << "myVector.GetCapacity():" << std::endl;
myVector.GetCapacity();
std::cout << "Capacity of Array: " << myVector.capacity << std::endl;
//myVector.Resize() -not working-
std::cout << " " << std::endl;
std::cout << "myVector.Resize():" << std::endl;
std::cout << "Orignal Vector Size: " << myVector.size << std::endl;
myVector.Resize(12);
//myVector Clear() + myVector Size()
std::cout << " " << std::endl;
std::cout << "myVector Clear() + myVector Size():" << std::endl;
myVector.Clear();
std::cout << "clearing myVector... Current Size:" << myVector.Size() << std::endl;
//myVector IsEmpty()
std::cout << " " << std::endl;
std::cout << "myVector.IsEmpty();:" << std::endl;
myVector.IsEmpty();
std::cout << " " << std::endl;
std::cout << "myVector.Operator[]:" << std::endl;
//myVector.operator[](int index)
myVector.operator[](3);
std::cout << myVector.Size() << std::endl;
std::cout << "NEEDS DEBUGGING:" << std::endl;
//-not working - :
//myVector Erase
std::cout << " " << std::endl;
std::cout << "myVector.Erase:" << std::endl;
myVector.Erase(3);
std::cout << myVector.Size() << std::endl;
std::cout << myVector.GetCapacity() << std::endl;
std::cout << " " << std::endl;
std::cout << "myVector.EraseAt:" << std::endl;
//myVector EraseAt
myVector.EraseAt(3);
std::cout << " " << std::endl;
std::cout << "myVector.Contains:" << std::endl;
//myVector.Contains()
myVector.Contains(0);
std::cout << " " << std::endl;
std::cout << "myVector.Find:" << std::endl;
//myVector.Find()
myVector.Find(0);
std::cout << " " << std::endl;
std::cout << "myVector.PushFront():" << std::endl;
//myVector.PushFront(3);
//myVector.PushFront(3);
std::cout << " " << std::endl;
std::cout << "myVector.Insert:" << std::endl;
//myVector.Insert()
//myVector.~Vector(); THIS FUNCTIONS!
std::cout << " " << std::endl;
std::cout << "myVector.~Vector()" << std::endl;
myVector.~Vector();
//std::cout << "Memory DeAllocated." << std::endl;
std::cin.get();
}
These parts are just me testing them out in the main file. A few things are marked as broken, because they don't work. I'm more focused on fixing PushFront and Insert if anyone could help me. I tried looking online but I can't seem to find something I understand.
Just PushBack the element, and then rotate it into place
void Vector::Insert(int value, int index) // Insert the given element at the given position. Position 0 should insert the element at the beginning of the container
{
PushBack(value);
std::rotate(contents + index, contents + size - 1, contents + size);
}

Having trouble getting my overloaded insertion operator to work

This is my main function
int main()
{
const string filename = "ass10data.txt"; // use your filename here
ifstream fin(filename.c_str());
if (!fin)
{
cerr << "Unable to open " << filename << endl;
exit(1);
}
string buffer;
Quadrilateral* ptrQuad;
while (getline(fin,buffer))
{
// Process only valid input
if (buffer.size() > 1)
{
ptrQuad = createQuadrilateralFromString(buffer);
cout << *ptrQuad << endl;
delete ptrQuad;
}
}
fin.close();
}
This is the overloaded insertion operator
ostream& operator<<(ostream&out, Quadrilateral *pointerQuad)
{
if (pointerQuad->getType() == "rectangle")
{
out << "Rectangle: sides " << pointerQuad->getFirst() << " and " << pointerQuad->getSecond() << " area=" << pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "square")
{
out << "Square: side "<< pointerQuad->getFirst() << " area="<< pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "parallelogram")
{
out << "Parallelogram: sides " << pointerQuad->getFirst() << " and " << pointerQuad->getSecond() << " area=" << pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "rhombus")
{
out << "Rhombus: side "<< pointerQuad->getFirst() << " area="<< pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else
return out;
}
I'm getting an error message saying "no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'Quadrilateral')" and I can't figure out why.
The insertion operator should take a const reference to the Quadrilateral, not a pointer to it:
ostream& operator<<(ostream&out, Quadrilateral const &pointerQuad)
Of course, that means your function should use the value syntax, not the pointer one too.
if (pointerQuad.getType() == "rectangle")
{
out << "Rectangle: sides " << pointerQuad.getFirst() << " and " << pointerQuad.getSecond() << " area=" << pointerQuad.area();
out << " perimeter=" << pointerQuad.perimeter();
return out;
}
[...]

Empty string position to return as *

Very new to programming.
This bit of my program accepts two strand of DNA as input and output them in a double helix drawing. The problem is, if one of the two input strand is longer than the other, i will receive error.
So I thought, is it possible that if strand[add] is non-existent anymore, replace it with *?
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
void helix(string &strand1, string &strand2)
{
int nucleo;
int length;
if (strand1.length() >= strand2.length())
{
length = strand1.length();
}
else
{
length = strand2.length();
}
int add;
for (int add = 0; add <= length - 1; add++)
{
if (add > 7)
{
nucleo = add % 8;
}
else
{
nucleo = add;
}
if (nucleo == 0)
{
cout << " " << strand1[add] << "---"<<strand2[add] << endl;
}
else if (nucleo == 1)
{
cout << " " << strand1[add] << "------" << strand2[add] << endl;
}
else if (nucleo == 2)
{
cout << " " << strand1[add] << "------" << strand2[add] << endl;
}
else if (nucleo == 3)
{
cout << " " << strand1[add] << "---" << strand2[add] << endl;
cout << " *" << endl;
}
else if (nucleo == 4)
{
cout << " " << strand2[add]<<"---" << strand1[add] << endl;
}
else if (nucleo == 5)
{
cout << " " << strand2[add]<<"------" << strand1[add] << endl;
}
else if (nucleo == 6)
{
cout << " " << strand2[add]<<"------" << strand1[add] << endl;
}
else if (nucleo == 7)
{
cout << " " << strand2[add]<<"-----" << strand1[add] << endl;
cout << " *" << endl;
}
}
}
int main()
{
string strand1,strand2;
cout << "ENTER STRAND:" << endl;
cin >> strand1;
cout << "ENTER STRAND:" << endl;
cin >> strand2;
helix(strand1,strand2);
_getch();
return 0;
}
I was hoping I could still show the longer strand even if the other side of the strand is empty(want to put *) like this :imgur.com/t7riVrS
I think you inverted the legnth test, it should be:
//if (strand1.length() >= strand2.length())
if (strand1.length() < strand2.length())
{
length = strand1.length();
}
else
{
length = strand2.length();
}
Edit:
If you want it fill one the string with '*', replace the code above with:
while (strand1.length() < strand2.length())
{
strand1 += "*";
}
while (strand1.length() > strand2.length())
{
strand2 += "*";
}

vector insert segmentation fault second iteration

I'm actually trying to implement the floyd's warshall algorithm but I met a hard-point. I got a segmentation fault while i'm trying to find the shortest-way in my matrix of sequence. I follow this tutorial:
floyd's warshall algorithm
Everything work well except at the line 124:
chemin.insert(it,sequenceTest[v1-1][temp-1]);
where i get the segfault (You can skip the first part except if you want to know how I implement the algorithm butt the problem is in the second part):
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
int i,j,k;
int sequenceTest [4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
int tempSequenceTest [4][4];
int distanceTest [4][4] = {{0,2,4,100000},{2,0,1,5},{4,1,0,3},{100000,5,3,0}};
int tempDistanceTest[4][4];
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout<<sequenceTest[i][j]<<" ";
}
cout<< endl;
}
cout<< endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout << distanceTest[i][j] << " ";
}
cout<< endl;
}
cout<< endl;
for(k=0;k<3;k++)
{
cout <<endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout << "i: " << i << " j: " << j << endl;
if(i == k)
{
tempSequenceTest[i][j] = sequenceTest[i][j];
tempDistanceTest[i][j] = distanceTest[i][j];
cout << " D " << tempDistanceTest[i][j] << " S " << tempSequenceTest[i][j];
}
if(j == k)
{
tempSequenceTest[i][j] = sequenceTest[i][j];
tempDistanceTest[i][j] = distanceTest[i][j];
cout << " D " << tempDistanceTest[i][j] << " S " << tempSequenceTest[i][j];
}
cout<< endl;
}
}
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
//cout<< "i: " << i << " j: " << j << " k:" << k << endl;
if(i!=k && j!=k)
{
if(distanceTest[i][j]> distanceTest[i][k] + distanceTest[k][j])
{
tempDistanceTest[i][j] = distanceTest[i][k] + distanceTest[k][j];
cout << distanceTest[i][j] << " > " << distanceTest[i][k] << " + " << distanceTest[k][j] << " = " << tempDistanceTest[i][j] << " " << i << j << endl;
tempSequenceTest[i][j] = k+1;
}
else
{
tempDistanceTest[i][j] = distanceTest[i][j];
tempSequenceTest[i][j] = sequenceTest[i][j];
}
}
}
}
cout<< endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
distanceTest[i][j] = tempDistanceTest[i][j];
sequenceTest[i][j] = tempSequenceTest[i][j];
}
}
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout<<tempSequenceTest[i][j]<<" ";
}
cout<< endl;
}
cout<< endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout << tempDistanceTest[i][j] << " ";
}
cout<< endl;
}
}
int v1, v2;
v1 = 1;
v2 = 4;
vector <int> chemin;
vector <int>::iterator it;
chemin.push_back(v1);
chemin.push_back(v2);
int temp = v2;
cout << sequenceTest[0][2];
while(sequenceTest[v1-1][temp-1] != v2)
{
it = chemin.begin() + 1;
cout << "V1: " << v1 << " V2: " << v2 << " Temp: " << temp << endl;
chemin.insert(it,sequenceTest[v1-1][temp-1]);
for(i=0;i<chemin.size();i++)
{
cout << chemin[i];
}
cout << endl;
temp = sequenceTest[v1-1][temp-1];
}
}
Thanks for your attention and for taking the time to help me!
chemin.insert(it,sequenceTest[v1-1][temp-1]);
This invalidates the iterator it, but you keep reusing it in the iterations that follow. If you want to continue inserting at the same position, capture the return value.
it = chemin.insert(it,sequenceTest[v1-1][temp-1]);