C++ QuickSort not sorting - c++

void quickSort(vector<double> unsortedData, int leftBound, int rightBound) {
if (leftBound < rightBound) {
double i = partitionStep(unsortedData, leftBound, rightBound);
quickSort(unsortedData, leftBound, i-1);
quickSort(unsortedData, i + 1, rightBound);
}
}
double partitionStep(vector<double> unsortedData, int leftBound, int rightBound) {
double pivot = unsortedData[rightBound];
while (leftBound <= rightBound) {
while ((unsortedData[leftBound] < pivot)) {
leftBound++;
}
while ((unsortedData[rightBound] > pivot)) {
rightBound--;
}
if (unsortedData[leftBound] == unsortedData[rightBound]) {
leftBound++;
} else if (leftBound < rightBound) {
double temp = unsortedData[leftBound];
unsortedData[leftBound] = unsortedData[rightBound];
unsortedData[rightBound] = temp;
}
}
return rightBound;
}
I need to sort a vector of doubles. This code runs but the vector is not sorted at the end. It's probably something that I am overlooking. Thoughts?

A high level description of your quickSort routine is:
Take as input a copy of the original vector and the endpoints of a range
Do stuff with the copy
Discard the copy
which isn't particularly useful. Change the input argument to vector<double>& so that you're doing stuff with a reference to the original vector rather than a copy.

Related

Arrays with unknown size on Arduino

I'm doing an Arduino project and I need to pass arrays with different sizes as parameter to my function.
The problem is that std::vector is not an option.
How can I do that?
The fallback is to pass a pointer to the first element in the array and the size:
void foo(int* arr, size_t size);
The reason for std::vector not being available on some platforms is that on some platforms dynamic allocations is a bad idea. However, once you are dynamically allocating arrays:
int* x = new int[42];
foo(arr,42); // array decays to pointer
delete[] x;
then you could as well use std::vector.
If std::vector is not available to you, then either search for an alternative (maybe this?) or write your own. The pointer + size approach is fragile and not recommended unless absolutely necessary. The power of std::vector is from the abstract concept to encapsulate the array, its size and capacity. Nobody can prevent you to apply that concept even if you cannot use std::vector.
In case you are talking about statically sized arrays, then thats not quite the use case for std::vector. You do not need dynamic allocation, and you can pass arrays by reference. I won't repeat here what you can find in this answer (std::array) or here (c-arrays).
Something like this should work
template<size_t N>
void DaFunction(std::array<int, N>& daArray)
you can do it without having to deal with memory allocation or pointers just by creating a string variable and a limited size array and then you start shifting
#include <Arduino.h>
class ArrayShifter
{
private:
// String Reservoire Tank
String _text;
// a fixed size array of 5 in my case (depending on the amount of data you expect)
String _viewPortArray[5];
int _size = 0;
// Methode to fill the array
bool shiftArray(int position);
public:
ArrayShifter(/* args */);
// Method that gets the text from Serial
String getSerialText();
// get data from the array
String getArrayData(int index);
// array size getter
int getSize();
//clear the array
void clearArray();
//remove item
void removeArrayItem(int index);
};
ArrayShifter::ArrayShifter(/* args */)
{
}
String ArrayShifter::getSerialText()
{
// lesteing to the serial and returning the value
_text = Serial.readString();
return _text;
}
bool ArrayShifter::shiftArray(int position)
{
/*Assuming that the data is comming separated with ";" for each row and ":" for each value
to optimize the size of array in this way :
name:value;age:value;gender:value;
*/
String text = getSerialText();
int index = 0;
_size = 0;
if (text.length() > 0) // text isn't empty
{
if (position <= 5) // if the data belongs to the first 5 range
{
for (int i = 0; i < 5; i++)
{
// get the index of our separator that we've chosed to be ";"
index = text.indexOf(";");
if (index > 0)
{
// index found
_size++;
// putting the value before ";" in the array
_viewPortArray[i] = text.substring(0, index);
// deleting the value from the tank
text = text.substring(index + 1);
}
}
}
else
{
_size = 0;
// to wich range the desired index belongs
unsigned int dataRange = ((position - position % 5));
int ghostIndex = 0;
// looping throught all ";" to get indexes
for (int i = 0; i < dataRange; i++)
{
ghostIndex = text.indexOf(";");
if (ghostIndex > 0)
{
_size++;
text = text.substring(ghostIndex + 1);
}
}
// grabing just 5 of the data
for (int i = 0; i < 5; i++)
{
if (ghostIndex > 0)
{
_size++;
_viewPortArray[i] = text.substring(0, ghostIndex);
text = text.substring(ghostIndex + 1);
}
// updating ghost index
ghostIndex = text.indexOf(';');
}
}
return true;
}
return false;
}
String ArrayShifter::getArrayData(int index)
{
// turn the roulette
if (shiftArray(index))
{
if (index <= 5)
{
// yes we have this
return _viewPortArray[index];
}
else
{
// but we have to put it in the range of 5
index = index - 5;
return _viewPortArray[index];
}
}
}
int ArrayShifter::getSize()
{
return _size;
}
void ArrayShifter::clearArray()
{
for(int i = 0 ; i <5 ; i ++)
{
_viewPortArray->remove(i);
_size = 0;
}
}
void ArrayShifter::removeArrayItem(int index)
{
_viewPortArray->remove(index);
_size--;
}
main class :
#include <Arduino.h>
#include <ArrayShifter.h>
ArrayShifter array;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial){}
}
void loop() {
if(Serial.available()>0)
{
Serial.println(array.getArrayData(7));
int sizeOption2 = array.getSize();
Serial.println(sizeOption2);
array.removeArrayItem(7);
Serial.println(array.getArrayData(7));
}
}
please check my github repository
https://github.com/Riadam/ViewPort-Array-Shifter-for-Arduino-Uno.git

Heap block modified past request error in C++

I have and QT application with class Solver that solve some numeric problem (Bairstow method for finding roots of the polynomial by finding its distribution to trinomials) but while for smaller instances (5 parameters, in array tabA) it work fine, but when I tried this for larger instances (7 parameters) application crashed.
After I run the debugger I get the following message:
Heap block at 02989F58 modified at 02989F80 past request 20
I'm not exactly sure what is about (well I suppose I get stack overflow but I'm not sure where and how) but it points to line delete[] Q; delete[] W; here is how debugger pointed it:
And here is code of that class methods (the error occurs in main method int Bairstow(*parameters*), which work on class fields and returns number which indicate is solution was found, is not existing or can't be found in given number of iteration)
Here's the main method:
int solver::Bairstow(int stopien,double const *tabA, double *tabP,double *tabR, double eps, int N, double p_,double r_)
{
int i,q, Iter, indpziel=0;
i=stopien;
while(i>=0 && tabA[i]==0)
{
i--;
}
if (i<2) { return 1; }
double *A=new double[stopien +1]
for (i=0;i<=stopien;i++)
{
A[i]=tabA[i];
}
double *Q=new double[stopien-1 +1];
double *w=new double[stopien-3 +1];
double Reszta[2];
double dqdp[2], dqdr[2];
double p,r, a,b,c,d;
while (stopien>=2)
{
p=p_, r=r_;
Iter=O;
do
{
PodzielWiel(stopien,A,p,r,Q,Reszta);
if (fabs(Reszta[1])<eps && fabs(Reszta[0])<eps)
{
break;
}
PodzielWiel(Stopien-2,Q,p,r,W,dqdr);
for (i=Stopien-2;i>=0;i--)
{
Q[i+1]=Q[i];
}
Q[0]=0;
PodzielWiel(Stopien-1,Q,p,r,W,dqdp);
q=LiczMOdwrotna(dqdp[0],dqdr[0],dqdp[1],dqdr[1],a,b,c,d);
if (q==1)
{
delete[] Q;
delete[] W;
return 2;
}
p = p-(a*Reszta[0]+b*Reszta[1]);
r = r-(c*Reszta[0]+d*Reszta[1]);
} while (++Iter<N);
if (Iter==N) return 3;
tabP[IndDziel]=p;
tabR[IndDziel]=r;
IndDziel++;
Stopien-=2;
for (i=0;i<=Stopien;i++)
{
A[i]=Q[i];
}
}
delete[] Q; delete[] W; //that's the line debugger pointed to
return 0;
}
And two helper methods:
for polynomial division (by trinomial x^2-px-r)
int solver::PodzielWiel(int stopien,double const *tabA, double p,double r, double *Q,double *R)
{
if (Stopien<O) return 1;
int i;
for (i=0;i<=stopien-2;i++)
{
Q[i]=0;
}
while (stopien>=0 && tabA[stopien]==0)
{
stopien--;
}
if (stopien<2)
{
R[0]=tabA[0];
R[1]=tabA[1];
return 0;
}
double *A=new double[Stopien +1];
for (i=0;i<=stopien;i++)
{
A[i]=tabA[i];
}
Q[stopien-2]=A[stopien];
if (stopien>2)
{
for(i=stopien; i>1; i--)
{
Q[i-2]=A[i];
A[i-1]+=Q[i-2]*p;
A[i-2]+=Q[i-2]*r;
}
R[1]=A[1];
R[0]=A[0] ;
}
else
{
R[1]=A[1]+p*Q[0] ;
R[0]=A[0]+r*Q[0] ;
}
delete [] A;
return 0;
}
for inversing the 2x2 matrix(first 4 parameters are inputs and next 4 outputs as it):
int Solver::LiczMOdwrotna(double x,double y,double w,double z, double &a,double &b,double &c,double &d)
{
if (x*z==y*w)
{
return 1;
}
if (x*w!=0)
{
c=1/(y-z*x/w);
a=-z*c/w;
d=1/(z-y*w/x);
b=-y*d/x;
}
else if (y*z!=0)
{
a=1/(x-w*y/z);
c=-w*a/z;
b=1/(w-z*x/y);
d=-x*b/y;
}
else if (x==0 && z==0)
{
c=1/y;
d=0;
a=0;
b=1/w;
}
else if (y==0 && w==0)
{
a=1/x;
b=0;
c=0;
d=1/z;
}
return 0;
}
And sory for maybe poor formatting but I have to use OCR software as copying from QT creator was impossible... even after using show in explorer, save file as txt in new localization (to make it visible outside QT Creator) and then doing it again... I still couldn't copy anything...

A star algorithm finding shortest path but not computing it correctly

Using the following A star visualization as a way to compare path accuracy, I found a large variation between my implementation and this one.
https://qiao.github.io/PathFinding.js/visual/
Path I'm comparing to:
(source: imgsafe.org)
My test paths:
(source: imgsafe.org)
There are times when it seems like the algorithm is checking too few nodes (i.e Test#6). Is this to be expected, or is it not correct?
Important variables in algorithm:
TileMap* m_tileMap;
vector<Tile*> m_openList;
vector<Tile*> m_path;
// Direct mapping of 2D tile map.
// Stores the list type for the same-indexed tile
vector<vector<int>> m_listMap;
Comparator for sorting open list:
struct CompareNodes
{
// sorts lowest F cost to end of vector
bool operator() (Tile* lhs, Tile* rhs)
{
return lhs->getFCost() > rhs->getFCost();
}
};
High level implementation:
vector<Tile*> PathGenerator::generatePath(Tile* startNode, Tile* endNode)
{
setUpListMap();
startNode->setGCost(0);
startNode->setHCost(calculateHCost(startNode, endNode)); // Manhattan (no diagonal). { abs(y2 - y1) + abs(x2 - x1) }
startNode->calculateFCost(); // calculates G+H internally
m_openList.push_back(startNode);
Vector2D startNodePos = startNode->getMapPos();
m_listMap[startNodePos.x][startNodePos.y] = LIST_TYPES::OPEN;
Tile* currentNode;
while (m_openList.empty() == false)
{
currNode = m_openList[m_openList.size() - 1];
m_openList.pop_back();
Vector2D currNodePos = currNode->getMapPos();
m_listMap[currNodePos.x][currNodePos.y] = LIST_TYPES::CLOSED;
if (currNode != endNode)
{
vector<Tile*> neighbours = findNeighbours(currNode);
removeUnnecessaryNodes(&neighbours); // remove walls and closed nodes
computeCosts(&neighbours, currNode, endNode);
addUniqueNodesToOpenList(&neighbours); // ignores duplicates and then sorts open list
}
else
{
m_path = getPath(currNode);
resetLists(); // erases all vectors
}
}
return m_path;
}
void PathGenerator::computeCosts(vector<Tile*>* nodes, Tile* current, Tile* end)
{
int newGCost = current->getGCost() + 1;
for (int i = 0; i < nodes->size(); i++)
{
Tile* node = nodes->at(i);
unsigned int nodeGCost = node->getGCost(); // G cost defaults to max int limit
if (newG < nodeGCost)
{
// set up node costs like above
node->setParentNode(current);
}
}
}
I've added the most important code. If the high level functions don't help to find the source of the issue, let me know and I'll add the implementation for them also.
Help appreciated.
The sorting part seems correct, but since it's a vector this should be very easy for you to verify.
Instead, try using a for-loop as a test-case to make sure you're really get the lowest f-cost node:
Tile* currnode = m_openlist[0];
for (int i = 0; i < m_openList.size() i++)
{
if (m_openList[i]->getFCost() < currnode->getFCost())
currnode = m_openList[i];
}
See if that fixes it. If it does, there's an issue in your sort, but i'm not sure what the issue would be.
Also, in your computeCosts function, you do:
for (int i = 0; i < nodes->size(); i++)
{
Tile* node = nodes->at(i);
//.. other code
}
Since you're using an std::vector, why not make use of its functionality, and use iterators or a range based loop:
// Iterators
for (auto it = nodes->begin(); it != nodes->end(); it++)
{
Tile* node = *it;
//.. other code
}
// Range based loop
for (auto node : *nodes)
{
//.. other code
}

C++ Memory Leak With STL Vector

I am building a templated Max Heap class in C++ for a datastructures class. The implementation demonstrates a Max Heap with a vector under the hood. There is an online submission associated with the assignment and when I submit mine, all the tests (push, pop, top, and size) pass and work (for the online unknown unit tests as well as all the ones I wrote) and I have no memory leaks with any of my tests, however I am failing the memory leak section with the online submission, indicating to me that my Bubble Up (Reheap Up) or Bubble Down (Reheap Down) algorithms are doing something funny with vector indices.
I noticed that I used the bracket operator a lot to mess with the vector, so I went through and changed all the brackets to .at() so I could see any suppressed out of bounds errors. Flying colors again, except for the memory leaks allegedly. I then figured well maybe one of the unit tests is adding sooo many values the vector fails to clear them all for some unknown reason...wasn't the case because I added so many values to a vector in my max heap class in my unit tests it took 90 seconds to finish and after all 52K allocations were made 52K deallocations were made as well and valgrind reported no errors.
Below is some of the main code for the class, if anyone could decide where some code is written that in some situation may warrant a memory leak that would be great!
template <class T>
class MaxHeap {
public:
MaxHeap(){
// TODO: Fill me in
}
~MaxHeap() {
data.clear();
}
void push(T value){
data.push_back(value);
bubbleUp(data.size()-1, value);
}
void pop(){
if(!size()) {
return;
}
T val = data.at(size()-1);
data.pop_back();
if(!size()) {
return;
}
data.at(0) = val;
bubbleDown(0, val);
}
T top(){
if(!data.size()) throw logic_error("Empty Heap");
return data.at(0);
}
unsigned int size(){
return data.size();
}
void print_vec() {
for (int i = 0; i < size(); ++i) {
cout << data.at(i) << " ";
}
cout << endl;
}
vector<T> getVec() {
return data;
}
private:
vector<T> data;
void bubbleUp(int idx, T value) {
int position = idx;
int parent_idx = parent(position);
while (data.at(parent_idx) < value) {
data.at(position) = data.at(parent_idx);
data.at(parent_idx) = value;
position = parent_idx;
parent_idx = parent(position);
}
}
void bubbleDown(int idx, T value) {
int left_child_idx = left_child(idx);
int right_child_idx = right_child(idx);
int max_child_idx;
if(left_child_idx <= size()-1) { // left child (consequently right child) in bounds of vector
if(left_child_idx == size()-1) { // no right child, left is maxchild
max_child_idx = left_child_idx;
} else {
max_child_idx = (data.at(left_child_idx) <= data.at(right_child_idx)) ? right_child_idx : left_child_idx;
}
if(data.at(idx) < data.at(max_child_idx)) {
data.at(idx) = data.at(max_child_idx);
data.at(max_child_idx) = value;
bubbleDown(max_child_idx, value);
}
}
}
int left_child(int idx) {return (idx*2+1);}
int right_child(int idx) {return (idx*2+2);}
int parent(int idx) {return ((idx-1)/2);}
};
Warning: this is only a theory, since it is improbable that the source of leak is in the code shown here.
If T is a malformed type, that does not release it's memory when using the assignment operator, then this might be the part that trigger this bad behvior:
T swap; // initialized to something. perhaps using new
while (data.at(parent_idx) < value) {
swap = data.at(parent_idx); //assume no delete in T.operator=()
data.at(parent_idx) = value;
data.at(position) = swap;
position = parent_idx;
parent_idx = parent(position);
}
This is not a problem in this code. However, you might still be able to patch it here. Why is T defined outside the loop?
while (data.at(parent_idx) < value) {
T swap = data.at(parent_idx); // no assignment here
data.at(parent_idx) = value;
data.at(position) = swap;
position = parent_idx;
parent_idx = parent(position);
}
===
Unrelated but better - don't use the unnecessary intermediate variable, and mix in move semantics:
while (data.at(parent_idx) < value) {
data.at(position) = std::move(data.at(parent_idx));
data.at(parent_idx) = value;
position = parent_idx;
parent_idx = parent(position);
}

Palindrome Partitioning (how to figure out how to use DFS)

My general question is how to figure out how to use DFS. It seems to be a weak part of my knowledge. I have vague idea but often get stuck when the problem changes. It caused a lot of confusion for me.
For this question, I got stuck with how to write DFS with recursion.
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = "aab",
Return
[
["aa","b"],
["a","a","b"]
]
My first attempt was stuck in the loop of the helper function. Then from searching on internet, I found that bool palindrome(string s) can be written as a different signature.
bool palindrome(string &s, int start, int end)
This leads to the correct solution.
Here's the code of my initial attempt:
class Solution {
public:
bool palindrome(string s)
{
int len = s.size();
for (int i=0;i<len/2; i++)
{
if (s[i]!=s[len-i])
return false;
}
return true;
}
void helper( int i, string s, vector<string> &p, vector<vector<string>> &ret)
{
int slen = s.size();
if (i==slen-1&&flag)
{
ret.push_back(p);
}
for (int k=i; k<slen; k++)
{
if (palindrome(s.substr(0,k)))
{
p.push_back(s.substr(0,k)); //Got stuck
}
}
i++;
}
vector<vector<string>> partition(string s) {
vector<vector<string>> ret;
int len=s.size();
if (len==0) return ret;
vector<string> p;
helper(0,s,p,ret);
return ret;
}
};
Correct one:
class Solution {
public:
bool palindrome(string &s, int start, int end)
{
while(start<end)
{
if (s[start]!=s[end])
return false;
start++;
end--;
}
return true;
}
void helper( int start, string &s, vector<string> &p, vector<vector<string>> &ret)
{
int slen = s.size();
if (start==slen)
{
ret.push_back(p);
return;
}
for (int i=start; i<s.size(); i++)
{
if (palindrome(s, start, i))
{
p.push_back(s.substr(start,i-start+1));
helper(i+1,s,p,ret);
p.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
vector<vector<string>> ret;
int len=s.size();
if (len==0) return ret;
vector<string> p;
helper(0,s,p,ret);
return ret;
}
};
Edit Dec. 4, 2014: I saw some approach using dynamical programming but can't understand the code completely.
esp. isPalin[i][j] = (s[i] == s[j]) && ((j - i < 2) || isPalin[i+1][j-1]);
Why j-I<2 instead of j-I<1?
class Solution {
public:
vector<vector<string>> partition(string s) {
int len = s.size();
vector<vector<string>> subPalins[len+1];
subPalins[0] = vector<vector<string>>();
subPalins[0].push_back(vector<string>());
bool isPalin[len][len];
for (int i=len-1; i>=0; i--)
{
for (int j=i; j<len; j++)
{
isPalin[i][j] = (s[i]==s[j])&&((j-i<2)||isPalin[i+1][j-1]);
}
}
for (int i=1; i<=len;i++)
{
subPalins[i]=vector<vector<string>>();
for (int j=0; j<i; j++)
{
string rightStr=s.substr(j,i-j);
if (isPalin[j][i-1])
{
vector<vector<string>> prepar=subPalins[j];
for (int t=0; t<prepar.size(); t++)
{
prepar[t].push_back(rightStr);
subPalins[i].push_back(prepar[t]);
}
}
}
}
return subPalins[len];
}
};
What exactly are you asking? You have correct working code and your non-working code which is not that different.
I guess I can point out several issues with your code - may be it will be helpful to you:
in the palindrome() function you should compare s[i] to s[len-1-i] rather than to just s[len-i] in the if, since in former case you will compare 1st element (having index 0) to the non-existent element (index len). That might be the reason helper() got stuck.
in the helper() function flag is not initialized. In the for cycle, the end condition should be k<slen-1 instead of k<slen, since in latter case you will omit checking the substring that includes the terminal symbol of the string. Also, incrementing i in the end of helper() is pointless. Finally, indentations are messy in the helper() function.
Not sure why you use DFS - what is the meaning of your graph, what are the vertices and edges here? As to how the recursion works here: in the helper() function you start checking substrings of increased length for being palindrome. If the palindrome is found, you place it into p vector (which represent your current partitioning) and try to break the remainder of the string into palindromes by calling helper() recursively. If you succeed in that (i.e. if the whole string is completely partitioned into palindromes) you place the contents of p vector (current partitioning) into ret (set of all found partitionings), and then clear p to prepare it for the analysis of the next partition (purge of p is achieved by pop_back() call that follows recursive call of helper()). If, on the other hand, you fail to completely break string into palindromes, the p is purged as well, but without transferring its content into ret (this is due to the fact that recursive call for the last piece of string - which is not a palindrome - returns without calling helper() for the final symbol and thus pushing p into ret does not occur). Therefore you end up having all possible palindrome partitionings in the ret.
Hi~ this is my code using DFS + backtracking.
class Solution
{
public:
bool isPalindrome (string s) {
int i = 0, j = s.length() - 1;
while(i <= j && s[i] == s[j]) {
i++;
j--;
}
return (j < i);
}
void my_partition(string s, vector<vector<string> > &final_result, vector<string> &every_result ) {
if (s.length() ==0)
final_result.push_back(every_result);
for (int i =1; i <= s.length();++i) {
string left = s.substr(0,i);
string right = s.substr(i);
if (isPalindrome(left)) {
every_result.push_back(left);
my_partition(right, final_result, every_result);
every_result.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
vector<vector<string> > final_result;
vector<string> every_result;
my_partition(s, final_result, every_result);
return final_result;
}
};
I have done Palindrome Partitioning using backtracking. Depth-first search was used here, idea is to split the given string so that the prefix is a palindrome. push prefix in a vector now explore the string leaving that prefix and then finally pop the last inserted element,
Well on spending time on backtracking is of the form, choose the element, explore without it and unchoose it.
enter code here
#include<iostream>
#include<vector>
#include<string>
using namespace std;
bool ispalidrome(string x ,int start ,int end){
while(end>=start){
if(x[end]!=x[start]){
return false;
}
start++;
end--;
}
return true;
}
void sub_palidrome(string A,int size,int start,vector<string>&small, vector < vector < string > >&big ){
if(start==size){
big.push_back(small);
return;
}
for(int i=start;i<size;i++){
if( ispalidrome(A,start,i) ){
small.push_back(A.substr(start,i-start+1));
sub_palidrome(A,size,i+1,small,big);
small.pop_back();
}
}
}
vector<vector<string> > partition(string A) {
int size=A.length();
int start=0;
vector <string>small;
vector < vector < string > >big;
sub_palidrome(A,size,start,small,big);
return big;
}
int main(){
vector<vector<string> > sol= partition("aab");
for(int i=0;i<sol.size();i++){
for(int j=0;j<sol[i].size();j++){
cout<<sol[i][j]<<" ";
}
cout<<endl;
}
}