So, I was asked by my instructor to make a node containing a few variables and sort it by taking the hourlySalary variable as reference for each code. However, there seems to be a problem with the outputs. It isn't sorting the nodes at all. I tried to fix it for a while and gave up. Looked up some sources on the internet but still no luck. I am guessing that the problem is somewhere in the swapping function or the bubble sort function.
Here is my code.
#include <iostream>
using namespace std;
class myNumberIsEleven{
private:
struct linkedlist{
string firstName;
string lastName;
unsigned int age;
char gender;
int hourlySalary;
linkedlist *linker;
}*Ptr,*curPtr;
public:
int counter=0;
myNumberIsEleven(){
Ptr=NULL;
}
void printList(){
curPtr=Ptr;
while(curPtr!=NULL){
cout << curPtr->firstName << " " << curPtr->lastName << endl << curPtr->age << endl << curPtr->gender << endl << curPtr->hourlySalary << endl << "=====" << endl;
curPtr=curPtr->linker;
}
}
void add(int salary,string name,string lastname,int ageisjustanumber,char Gender){
linkedlist *newPtr = new linkedlist;
newPtr->hourlySalary = salary;
newPtr->firstName = name;
newPtr->lastName = lastname;
newPtr->gender = Gender;
newPtr->age = ageisjustanumber;
newPtr->hourlySalary = salary;
newPtr->linker = Ptr;
Ptr = newPtr;
counter++;
}
void Swap(linkedlist* a,linkedlist* b){
string temp_firstName;
string temp_LastName;
unsigned int temp_Age;
char temp_Gender;
int temp_hourlySalray;
temp_firstName = a->firstName;
temp_LastName = a->lastName;
temp_Age = a->age;
temp_Gender = a->gender;
temp_hourlySalray = a->hourlySalary;
a->firstName = b->firstName;
a->lastName = b->lastName;
a->age = b->age;
a->gender = b->gender;
a->hourlySalary = b->hourlySalary;
b->firstName = temp_firstName;
b->lastName = temp_LastName;
b->age = temp_Age;
b->gender = temp_Gender;
b->hourlySalary = temp_hourlySalray;
}
void bubbleSort(){
for(linkedlist* i=Ptr;i->linker != NULL;i=i->linker){
for(linkedlist* j = i->linker;j!=NULL;j=j->linker){
if(i->hourlySalary > i->hourlySalary){
Swap(i,j);
}
}
}
printList();
}
/*
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
*/
};
int main()
{
myNumberIsEleven myNameIsBerkan;
myNameIsBerkan.add(1000,"berkan","iwontgivemysurname",21,'M');
myNameIsBerkan.add(2100,"ah","be",31,'F');
myNameIsBerkan.add(50,"uhmmm","something",10,'M');
myNameIsBerkan.add(69000,"elon","musk",44,'M');
myNameIsBerkan.bubbleSort();
return 0;
}
-I wrote a program to find the shortest path from a source node to a target node. Everything is fine, the program found the shortest path. But i have a problem, that is not able to print or get each node in the path. I tried many ways but no result. Hope anyone can help me, thanks everyone.
///////////////////////////////
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
typedef struct Node
{
int vertex;
int g;
int h;
int f;
Node* parent;
Node(int vertex)
{
this->vertex = vertex;
this->g = 0;
this->h = 0;
this->f = 0;
this->parent=NULL;
}
Node(int vertex,int g, int h, int f,Node*parent)
{
this->vertex = vertex;
this->g = g;
this->h = h;
this->f = f;
this->parent = parent;
}
}Node;
struct Edge
{
int source;
int dest;
int g;
int h;
};
struct comp
{
bool operator()(const Node* lhs, const Node* rhs) const {
return lhs->f < rhs->f;
}
};
std::vector<Node*>openList;
std::vector<Node*>closeList;
Node* startPos;
Node* endPos;
static const int WeightW = 10;
class Graph
{
public:
std::vector<std::vector<Edge>>adjlist;
Graph(const std::vector<Edge>& edges, int N)
{
adjlist.resize(N);
for (auto &edge:edges)
{
adjlist[edge.source].push_back(edge);
}
}
};
int isContains(std::vector<Node*>* Nodelist, int vertex);
void printPath(Node*node);
void findShortestPath(const Graph& grap,Node* start,Node* end, int N)
{
Node* node;
openList.push_back(start);
while (openList.size()>0)
{
node = openList[0];
closeList.push_back(node);
openList.erase(openList.begin());
std::cout << "start" << std::endl;
int u = node->vertex;
std::cout << "V: " << u << " g :" << node->g << std::endl;
std::cout << "continous" << std::endl;
for (auto v : grap.adjlist[u])
{
if (v.dest == end->vertex)
{
std::cout << "FindNode " << v.dest << std::endl;
printPath(node);
return;
}
if (isContains(&closeList, v.dest) == -1)
{
if (isContains(&openList, v.dest) == -1)
{
int vertex = v.dest;
std::cout <<"V: "<< vertex << std::endl;
int h = v.h;
int currentg = node->g + v.g;
int f = currentg + h;
std::cout <<"vertext: "<<vertex<< " h: " << h << " g: " << currentg << " f: " << f << std::endl;
Node* newNode = new Node(vertex, currentg, h, f,node->parent);
openList.push_back(newNode);
}
}
}
std::cout<<"Close: ";
for (size_t i = 0; i < closeList.size(); i++)
{
std::cout << closeList[i]->vertex << " ";
}
std::cout << std::endl;
sort(openList.begin(), openList.end(),comp());
std::cout << "Open: ";
for (size_t i = 0; i < openList.size(); i++)
{
std::cout << openList[i]->vertex << " ";
}
std::cout << std::endl;
std::cout << "end" << std::endl;
std::cout << std::endl;
}
}
void printPath(Node* node)
{
std::cout << std::endl;
if (node->parent != NULL)
printPath(node->parent);
std::cout << node->vertex << " ";
}
int isContains(std::vector<Node*>* Nodelist,int vertex)
{
for (int i = 0; i < Nodelist->size(); i++)
{
if (Nodelist->at(i)->vertex== vertex)
{
return i;
}
}
return -1;
}
int main()
{
//{Node,Node,G,H}
//Firt Node
//second Node
//G is the movement cost to move from the starting point to a given square on the grid
// following the path generated to get there
//H is the estimated movement cost to move from that given square on the grid to the final destination
std::vector<Edge>edges =
{
{0,1,5,17},
{0,2,5,13},
{1,0,5,16},
{1,3,3,16},
{1,2,4,13},
{2,0,5,16},
{2,1,4,17},
{2,3,7,16},
{2,4,7,16},
{2,7,8,11},
{3,2,7,13},
{3,7,11,11},
{3,10,16,4},
{3,11,13,7},
{3,12,14,10},
{4,2,7,13},
{4,5,4,20},
{4,7,5,11},
{5,4,4,16},
{5,6,9,17},
{6,5,9,20},
{6,13,12,7},
{7,3,11,16},
{7,4,5,16},
{7,8,3,10},
{8,7,3,11},
{8,9,4,8},
{9,8,4,10},
{9,13,3,7},
{9,15,8,0},
{10,3,16,16},
{10,11,5,7},
{10,13,7,7},
{10,15,4,0},
{11,3,13,16},
{11,10,5,4},
{11,12,9,10},
{11,14,4,5},
{12,3,14,16},
{12,11,9,7},
{12,14,5,5},
{13,9,3,8},
{13,10,7,4},
{13,15,7,0},
{14,11,4,7},
{14,12,5,10},
{15,9,8,8},
{15,10,4,4},
{15,13,7,7},
};
int n = edges.size();
Graph grap(edges, n);
//std::cout << h << std::endl;
Node* start = new Node(0);
Node* end = new Node(15);
findShortestPath(grap, start, end, n);
//Astar astar;
//Node* startPos = new Node(5, 1);
//Node* endPos = new Node(1, 8);
//astar.printMap();
//astar.search(startPos, endPos);
//cout << endl;
//astar.printMap();
system("pause");
return 0;
}
Your program doesn't find the shortest path. It gives the wrong output. (you're on the right track though)
I will assume you are trying to find the shortest path by using BFS. Let's take a look at line 113:
sort(openList.begin(), openList.end(),comp());
Here you're sorting your BFS queue (vector in your case) and thus destroying the right order.
Delete that line.
Congrats, now your program finds the shortest path!
Next, as I understand, for each node you branch into, you remember which node you came from in order to backtrack the path once you reach the destination or final node.
In line 102:
Node* newNode = new Node(vertex, currentg, h, f,node->parent);
you are assigning the new node's grandparent instead of parent. Change that line to
Node* newNode = new Node(vertex, currentg, h, f,node);
Now your printPath function works properly and prints the right path. (just add the target node)
Anyways, your code has a lot of space for improvements. Check out other implementations online and try to see if you can code it as short and clean for practice. Good luck!
I am using VS code for coding in C++. The problem arises when I try to debug a code and set a breakpoint. The local variables pane doesn't show any variables at all. Sometimes it does show some variables but not all of them.
Also when I try to close the debugger and click on the stop button, it does not stop. It requires me to click on it multiple times, which I think means, that multiple debuggers are opened or something like that.
To reproduce this problem, save this text as input_static.txt.
T1 1 2 5
T2 2 4
T3 2 3
T4 1 2 4
T5 1 3
T6 2 3
T7 1 3
T8 1 2 3 5
T9 1 2 3
And debug the following code by setting a breakpoint at line number 201.
#include <bits/stdc++.h>
using namespace std;
ifstream fin;
ofstream fout;
typedef struct fptnode
{
int item, count;
fptnode *next;
map<int, fptnode *> children;
fptnode *parent;
fptnode(int item, int count, fptnode *parent)
{
this->item = item;
this->count = count;
this->parent = parent;
}
} * FPTPTR;
map<int, int> frequency;
bool isMoreFrequent(int a, int b)
{
if (frequency[a] == frequency[b])
return a < b;
return frequency[a] > frequency[b];
}
class FPTREE
{
public:
FPTPTR root;
map<int, list<FPTPTR>> headers;
// map<int, int> frequency;
FPTREE()
{
this->root = new fptnode(-1, 0, NULL);
}
// class isMoreFrequent
// {
// public:
// FPTREE *T;
// isMoreFrequent(FPTREE *T)
// {
// this->T = T;
// }
// bool operator()(int item1, int item2)
// {
// return T->frequency[item1] > T->frequency[item2];
// }
// };
FPTPTR getNewNode(int item, int count, fptnode *parent)
{
FPTPTR T = new fptnode(item, count, parent);
this->headers[item].push_back(T);
return T;
}
void add(vector<int> &transaction)
{
stack<int> S;
std::sort(transaction.begin(), transaction.end(), isMoreFrequent);
for (int i = transaction.size() - 1; i >= 0; i--)
{
S.push(transaction[i]);
}
insert(root, S);
}
int insert(FPTPTR T, stack<int> &S)
{
T->count++;
if (S.empty())
return 0;
int top = S.top();
S.pop();
if (T->children[top] == NULL)
{
T->children[top] = getNewNode(top, 0, T);
}
insert(T->children[top], S);
return 0;
}
void printPreOrder(ofstream &fout)
{
printPreOrder(fout, this->root);
}
void printPreOrder(ofstream &fout, FPTPTR T)
{
if (T)
{
fout << "[" << T->item << ", " << T->count << "]" << ' ';
for (auto p : T->children)
{
printPreOrder(fout, p.second);
}
}
}
void printTree(ofstream &fout)
{
printTree(fout, this->root);
}
void printTree(ofstream &fout, FPTPTR T, int level = 0)
{
if (T)
{
for (int i = 0; i < level; i++)
fout << "\t";
fout << "[" << T->item << ", " << T->count << "]" << endl;
for (auto p : T->children)
{
printTree(fout, p.second, level + 1);
}
}
}
void generatePath(FPTPTR node, vector<int> &path)
{
if (node && node->item >= 0)
{
path.push_back(node->item);
generatePath(node->parent, path);
}
}
FPTREE newTree(int item)
{
list<FPTPTR> &nodes = this->headers[item];
vector<int> patternBase;
FPTREE f;
for (auto node : nodes)
{
patternBase.clear();
generatePath(node->parent, patternBase);
for (int j = 0; j < node->count; ++j)
f.add(patternBase);
}
return f;
}
int clear()
{
return this->clear(this->root);
}
int clear(FPTPTR T)
{
for (auto p : T->children)
{
clear(p.second);
}
return 0;
}
bool isEmpty()
{
// return this->root->count == 0;
return this->root->children.empty();
}
} F;
ofstream tempout;
map<set<int>, int> mine(FPTREE f, int r = -1)
{
map<set<int>, int> M;
if (!f.isEmpty())
{
// if (f.root->children.empty())
// M[{}] += f.root->count;
tempout << "\nOn removing " << r << ":\n";
f.printTree(tempout);
for (auto p : frequency)
{
FPTREE subF = f.newTree(p.first);
map<set<int>, int> m = mine(subF, p.first);
for (auto q : m)
{
auto itemset = q.first;
itemset.insert(p.first);
M[itemset] += q.second;
}
subF.clear();
}
return M;
}
// tempout << "\nTerminated.\n";
return {};
}
int main(int argc, char const *argv[])
{
fin.open("input_static.txt");
fout.open("output_static.txt");
tempout.open("temp");
string str, s;
while (fin >> s)
{
if (s.front() != 'T')
{
frequency[stoi(s)]++;
}
}
vector<int> transaction;
stringstream st;
fin.clear();
fin.seekg(0);
while (std::getline(fin, str))
{
st.clear();
st.str(str);
transaction.clear();
while (st >> s)
{
if (s.front() != 'T')
{
transaction.push_back(stoi(s));
}
}
F.add(transaction);
}
fout << "Preorder:\n";
F.printPreOrder(fout);
fout << endl
<< endl;
fout << "Tree in directory form:\n";
F.printTree(fout);
// printPrefixes(5);
map<set<int>, int> frequentItemsets = mine(F);
fout << endl;
for (auto p : frequentItemsets)
{
fout << "Frequency=" << p.second << "\t";
for (int item : p.first)
{
fout << item << ' ';
}
fout << endl;
}
// for (int i = 1; i <= 5; ++i)
// {
// fout << i << ":\n";
// FPTREE f = F.newTree(i);
// f.printTree();
// }
// F.newTree(1).newTree(2).printTree(fout);
return 0;
}
If it helps this is a program to generate and mine an FP-tree to find frequent itemsets in a transactional database.
I'm receiving a BadPtr error whenever I reach this point into the code: Why?
for(int i = 0; i < processTable.size(); i++)
{
data_entry test = *processTable.at(i).dataCurrent; //ERROR
cout << test.text << "\n";
}
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
enum process_state { READY, RUNNING, WAITING };
struct data_entry {
const char * text;
int time;
};
struct process_entry
{
int process;
const data_entry * dataStart;
const data_entry * dataEnd;
const data_entry * dataCurrent;
process_state state;
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<data_entry> dataTable;
vector<process_entry> processTable;
string line;
ifstream myfile ("C:\\Users\\1162852\\Documents\\visual studio 2010\\Projects\\Project 1 (OS)\\Debug\\input.txt");
if (myfile.is_open())
{
int processAmount = 0;
while ( getline (myfile,line) )
{
if(line.find("START") != string::npos)
{
data_entry newEntry;
newEntry.text = "START";
newEntry.time = atoi(line.substr(6, 6).c_str());
dataTable.push_back(newEntry);
process_entry newProcessEntry;
newProcessEntry.dataStart = &dataTable.at(dataTable.size() - 1);
newProcessEntry.dataCurrent = &dataTable.at(dataTable.size() - 1);
newProcessEntry.process = processAmount;
processTable.push_back(newProcessEntry);
processAmount += 1;
}
else if(line.find("END") != string::npos)
{
data_entry newEntry;
newEntry.text = "END";
newEntry.time = NULL;
dataTable.push_back(newEntry);
processTable.at(processTable.size() - 1).dataEnd = &dataTable.at(dataTable.size() - 1);
}
else if(line.find("RUN") != string::npos)
{
data_entry newEntry;
newEntry.text = "RUN";
newEntry.time = atoi(line.substr(4, 4).c_str());
dataTable.push_back(newEntry);
}
else if(line.find("INPUT") != string::npos)
{
data_entry newEntry;
newEntry.text = "INPUT";
newEntry.time = atoi(line.substr(6, 6).c_str());
dataTable.push_back(newEntry);
}
else if(line.find("SSD") != string::npos)
{
data_entry newEntry;
newEntry.text = "SSD";
newEntry.time = atoi(line.substr(4, 4).c_str());
dataTable.push_back(newEntry);
}
}
//reverse(dataTable.begin(),dataTable.end());
/*for(int i = 0; i < dataTable.size(); i++)
{
cout << dataTable.at(i).text << "\n";
}*/
for(int i = 0; i < processTable.size(); i++)
{
data_entry test = *processTable.at(i).dataCurrent;
cout << test.text << "\n";
}
myfile.close();
}
int test;
cin >> test;
return 0;
}
This assignment should return a data entry type.
Use ->dataCurrent to obtain the pointer to data_entry, and then dereference.
You perhaps also want to specify data_entry as const depending on what it is used for.
const data_entry test = *(processTable.at(i)->dataCurrent);
The problem is that you are saving a pointer to elements of dataTable but push_back will invalidate those pointers if the vector is resized. Consider making dataTable and processTable a vector of shared pointers so they don't get moved.
vector<shared_ptr<data_entry>> dataTable;
vector<shared_ptr<process_entry>> processTable;
I would also change the members of process_entry to shared pointers while your at it. With these changes your START section will now look something like this:
auto newEntry = make_shared<data_entry>();
newEntry->text = "START";
newEntry->time = atoi(line.substr(6, 6).c_str());
dataTable.push_back(newEntry);
auto newProcessEntry = make_shared<process_entry>();
newProcessEntry->dataStart = dataTable.back();
newProcessEntry->dataCurrent = dataTable.back();
newProcessEntry->process = processAmount;
processTable.push_back(newProcessEntry);
Another option you have is to use a std::list which won't copy the elements around when it grows.
replace
*processTable.at(i).dataCurrent;
by
*(processTable.at(i).dataCurrent);
Moreover you do not have copy ctor and thus a shallow copy is made.
Make sure this is what u want.
You populated your vectors with local variables that are created inside the while loop, and they are not accessible out of the enclosing if block.
So once we exit the while block all the local variables are destroyed, and the vector is pointing to bunch of bad_ptrs.