I was learning to do a program online and found this solution and I wanted to execute and learn from it.
I am keep getting syntax error, can someone help with formatting it? I tried but couldn't understand the code that much to see where we need to provide indentation etc.,
I couldn't find a python example online for that question, I could only find c++ answer.
class Node {
public:
virtual int Compute() = 0;
inline void SetLeft(Node* left) {
left_ = left;
}
inline void SetRight(Node* right) {
right_ = right;
}
protected:
Node* left_ = nullptr;
Node* right_ = nullptr;
};
class SumNode : public Node {
public:
inline int Compute() override {
return left_->Compute() + right_->Compute();
}
};
class SubNode : public Node {
public:
inline int Compute() override {
return left_->Compute() - right_->Compute();
}
};
class MulNode : public Node {
public:
inline int Compute() override {
return left_->Compute() * right_->Compute();
}
};
class NumNode : public Node {
public:
NumNode(int num) : num_(num) {}
inline int Compute() override {
return num_;
}
private:
int num_;
};
class Solution {
public:
vector<int> diffWaysToCompute(string expression) {
vector<Node*> nodes;
// parse the expression
for(int i = 0; i < expression.size(); ++i) {
switch(expression[i]) {
case '+':
nodes.emplace_back(new SumNode());
break;
case '-':
nodes.emplace_back(new SubNode());
break;
case '*':
nodes.emplace_back(new MulNode());
break;
default:
int num = 0;
while(expression[i] >= '0' && expression[i] <= '9') {
num = num * 10 + expression[i] - '0';
++i;
}
--i;
nodes.emplace_back(new NumNode(num));
break;
}
}
vector<Node*> trees = GenerateAllTrees(nodes, 0, nodes.size() - 1);
for(Node* node : nodes) {
delete node;
}
vector<int> results;
for(Node* tree : trees) {
results.emplace_back(tree->Compute());
delete tree;
}
return results;
}
vector<Node*> GenerateAllTrees(const vector<Node*> nodes, int beg, int end) {
if(beg == end) {
return {new NumNode(nodes[beg]->Compute())};
}
vector<Node*> results;
for(int i = beg; i <= end; i++) {
// assuming the expression is well formed, operators will be in odd positions
if((i & 1) == 0) continue;
vector<Node*> left_trees = GenerateAllTrees(nodes, beg, i - 1);
vector<Node*> right_trees = GenerateAllTrees(nodes, i + 1, end);
for(Node* left : left_trees) {
for(Node* right : right_trees) {
nodes[i]->SetLeft(left);
nodes[i]->SetRight(right);
Node* result = new NumNode(nodes[i]->Compute());
results.emplace_back(result);
}
}
for(Node* t : left_trees) {
delete t;
}
for(Node* t : right_trees) {
delete t;
}
}
return results;
}
};
You just need to import the modules you are using, exactly like Python, except the syntax is different:
#include <vector>
#include <string>
using namespace std;
class Node {
public:
...
And because it is using emplace_back, if you are using g++, you'll need to specify -std=c++11 on the command line.
Also, you need to understand this is not a runnable example. These are just classes you could use in your own code. To run this, you'll need to supply a main() function. Maybe:
#include <iostream>
int main()
{
Solution s;
vector<int> result = s.diffWaysToCompute( "3+9*7-16" );
for( auto i : result )
cout << i << "\n";
}
Related
I'm trying to do the Maximum Sort of a Simple One-way List. However my program has some bugs in it, which I can't figure out what it is.
It behaves strange because sometimes it works well to a point where it just stop working but i see return 0 (for example: I give the list of 1234 and I get back 3412), sometimes it working to a point, then goes to an infinte loop. (for example: case of 12345 it put 5, 4 and 3 the the 1st place and then infinite loop).
The problem is probably in the list::remMax() or in the maxRend().
My code:
struct chain
{
char key;
chain *next;
};
/////////////////////////////////////////////
class list
{
private:
chain *L, **act;
public:
list() {
L=NULL;
act=&L;
}
~list() {
chain *p;
while(L) {
p=L;
L=L->next;
delete []p;
}
}
enum ERROR {endErr, memErr};
void first() {act=&L;};
void next() {
if(*act!=NULL) {
act=&(*act)->next;
} else throw endErr;
}
bool end() {return *act==NULL;}
bool oneEIn() {return L->next==NULL;} //list contains only 1 element
bool twoEIn() {return L->next->next==NULL;} //list contains 2 elements
void addE(char x) {
chain *p=new(nothrow) chain;
if(p == NULL) throw memErr;
p->key=x;
p->next=*act;
*act=p;
}
chain* remMax(chain *H) {
if(!oneEIn()) {
chain *qe, *q, *Mpe, *Mp;
if(twoEIn()) {
Mp = H;
q = Mp->next;
if(q->key > Mp->key) {
Mp->next=q->next;
return q;
} else {
H=q;
Mp->next=NULL;
return Mp;
}
} else {
Mp=H;
q=Mp->next;
Mpe = H;
qe = Mp;
while(q != NULL) {
if(Mpe->key > Mp->key) Mp = Mpe;
if(q->key > Mp->key) {
Mp=q;
Mpe=qe;
}
qe=q;
q=q->next;
}
if(Mpe == Mp) H=Mp->next;
else {
Mpe->next = Mp->next;
}
Mp->next=NULL;
return Mp;
}
} else {
chain *Mp;
Mp = H;
H = NULL;
return Mp;
}
}
void inE(chain *Mp) {
first();
Mp->next = *act;
addE(Mp->key);
}
chain* getFirst() {return L;}
void printList() {
chain *p=L;
while(p != NULL) {
putchar(p->key);
p=p->next;
}
}
};
///////////////////////////////////
void makeList(list& L) {
char c;
while((c=getchar())!='\n') {
L.addE(c);
L.next();
}
}
void maxRend(list& L) {
if(!L.oneEIn()) {
chain *H, *Mp;
H=L.getFirst();
while(H != NULL) {
cout<<"1.while\n";
Mp = L.remMax(H);
L.inE(Mp);
cout<<"putIn: "<<Mp->key<<endl;
H=H->next;
L.printList();
cout<<endl;
}
cout<<"\nSorted list: ";
L.printList();
} else L.printList();
}
//////////////////////////////////////////////
int main()
{
list L;
makeList(L);
maxRend(L);
return 0;
}
As the title says I am trying to implement Set ADT on a Hashtable with independent lists. The thing is I don't know where I'm wrong.
The code I am about to post is taken from a bigger project and I took just the esential parts of it to show you.
SetADT.h:
#pragma once
#pragma once
#include <stdio.h>
#define CAPACITY 10
using namespace std;
template <typename TElement>
class IteratorSet;
template<typename TElement>
class Set {
class Nod {
public:
TElement element;
Nod* next;
};
public:
Set();
void add(TElement element);
int size();
void sterge(TElement element);
bool cauta(TElement element);
friend class IteratorSet<TElement>;
IteratorSet<TElement> iterator() { return IteratorSet<TElement>(this); }
private:
int dimensiune;
typename Set<TElement>::Nod* prim;
int max;
Nod** table;
int hashFunction(TElement element) { return element.hashCode() % max; }
Nod* set;
};
template<typename TElement>
Set<TElement>::Set()
{
max = CAPACITATE;
table = new Nod*[max];
for (int i = 0; i < max; i++)
table[i] = NULL;
}
template <typename TElement>
void Set<TElement>::add(TElement element)
{
int pozitie = hashFunction(element);
Nod* curent = table[pozitie];
while (curent != NULL && !(element == curent->element))
curent = curent->next;
if (curent != NULL)
return;
else
{
Nod* n = new Nod;
n->element = element;
n->next = table[pozitie];
table[pozitie] = n;
}
dimensiune++;
}
template <typename TElement>
int Set<TElement>::size()
{
return dimensiune;
}
template <typename TElement>
void Set<TElement>::sterge(TElement element)
{
int pozitie = hashFunction(element);
Nod* curent = table[pozitie];
if (table[pozitie] == NULL)
return;
if (table[pozitie]->element == element)
{
Nod* deSters = table[pozitie];
table[pozitie] = table[pozitie]->next;
delete deSters;
dimensiune--;
return;
}
Nod* elem = table[pozitie];
while (elem->next != NULL && (elem->next->element) == element)
elem = elem->next;
if (elem->next != NULL)
{
Nod* deSters = elem->next;
elem->next = elem->next->next;
delete deSters;
dimensiune--;
}
}
template <typename TElement>
bool Set<TElement>::cauta(TElement element)
{
int pozitie = hashFunction(element);
Nod* curent = table[pozitie];
while (curent != NULL && !(element == curent->element))
curent = curent->next;
if (curent != NULL)
{
return true;
}
return false;
}
template<typename TElement>
class IteratorSet {
public:
IteratorSet(Set<TElement>* m);
void next();
bool valid();
TElement element();
private:
Set<TElement>* Set;
typename Set<TElement>::Nod* crt;
};
template<typename TElement>
IteratorSet<TElement>::IteratorSet(Set<TElement>* mul) {
Set = mul;
crt = mul->prim;
}
template<typename TElement>
bool IteratorSet<TElement>::valid() {
return crt != NULL;
}
template<typename TElement>
TElement IteratorSet<TElement>::element() {
return crt->element;
}
template<typename TElement>
void IteratorSet<TElement>::next() {
crt = crt->next;
}
=======================================================
domain.h (names of Pizzas)
#include <string>
using namespace std;
class Pizza {
public:
Pizza(string namePizza) : namePizza(namePizza) {}
Pizza() : namePizza("") {}
string getName() const {
return namePizza;
}
int hashCode()
{
int sum = 0;
for (unsigned i = 0; i < str.length(); i++)
sum += str[i];
return sum;
}
bool operator == (Pizza& other) {
return namePizza == other.getName();
}
private:
string namePizza;
string str;
};
====================================================
main.cpp:
#include "SetADT.h"
#include <string>
#include <iostream>
#include "domain.h"
void show(Set<Pizza>* set) {
IteratorSet<string> it = set->iterator();
while (it.valid()) {
cout << "\t" << it.element().getName() << endl;
it.next();
}
}
int main()
{
Set<Pizza> set;
Pizza pizza1{ "diavola" };
Pizza pizza2{ "prosciuto" };
set.add(pizza1);
set.add(pizza2);
show(set);
return 0;
}
When I try to print the objects added to the Set it pops and error and the program stops.
I don't know anywhere else to look to find the problem.
Anyway, if the code sample isn't enough, here the complete project ( has parts of romanian in it )
http://www20.zippyshare.com/v/qKpEcZhr/file.html
The reason might be, for example, prim variable that you use in the iterator, that is initialized to an undefined value. However, code you posted is not compilable, i.e. there are other problems why your code is not working. Did not download your zip file.
I'm attempting to make some sort of autocomplete feature in c++. First by using a Trie and once that works (and most importantly, I know HOW it all works) I'll try it using a Ternary tree. But as for now I get a segmentation fault when ever I add words starting with a different characte than those already in the Trie.
Eg. we add "abc", "abcd" and "abcde" this is no problem. Later when I want to add (while the "abc" etc are still in the Trie) "xfce", "xfced" a segmentation fault occurs.
I've been debugging this for some while now and can't seem to find the problem.
I think the problem resides somewhere in Trie.cpp so that's the file I'll provide here. However it might be in the main function aswell but I don't wanna get yelled at for posting to much code...
#include "Trie.h"
#include <iostream>
Trie::Trie()
{
this->root = new Node(false);
}
Trie::~Trie()
{
}
Trie::Node::Node(bool isLeaf)
{
this->isLeaf = isLeaf;
}
void Trie::insert(const std::string& word)
{
Node* crawler = this->root;
int index;
for(int i = 0; i < word.length(); ++i)
{
index = CHAR_TO_INDEX(word.at(i));
if(!crawler->children[index])
{
crawler->children[index] = new Node(false);
}
crawler = crawler->children[index];
}
crawler->isLeaf = true;
}
int Trie::contains(const std::string& word)
{
int index;
Node* crawler = this->root;
for(int i = 0; i < word.length(); ++i)
{
index = CHAR_TO_INDEX(word.at(i));
if(!crawler->children[index])
{
return -1;
}
crawler = crawler->children[index];
}
return (crawler != NULL && crawler->isLeaf);
}
std::vector<std::string> Trie::possibleSuffixes(std::string& prefix)
{
Node* crawler = this->root;
int index;
std::vector<std::string> result;
for(int i = 0; i < prefix.length(); ++i)
{
index = CHAR_TO_INDEX(prefix.at(i));
crawler = crawler->children[index];
}
traverse(prefix, crawler, result);
return result;
}
void Trie::traverse(std::string prefix, Node* node, std::vector<std::string>& v)
{
if(node->isLeaf)
{
v.push_back(prefix);
}
for(int i = 0; i < ALPHABET; ++i)
{
if(node->children[i])
{
traverse(prefix + (char)('a' + i), node->children[i], v);
}
}
}
Entire Trie class:
#ifndef TRIE_H
#define TRIE_H
#include <string>
#include <vector>
#define ARRAYSIZE(a) sizeof(a / sizeof(a[0]))
#define ALPHABET 26
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
class Trie
{
private:
struct Node
{
Node(bool isLeaf);
struct Node *children[ALPHABET];
bool isLeaf;
};
Node *root;
void traverse(std::string prefix, Node* node, std::vector<std::string>& v);
public:
Trie();
~Trie();
int contains(const std::string& word); //Checks the existance of a specific word in the trie
void insert(const std::string& word); //Inserts new word in the trie if not already there
std::vector<std::string> possibleSuffixes(std::string& prefix);
};
Though you didn't mention about your Node class, I am assuming this -
class Node {
public:
bool isLeaf;
// must be >= 25 as you're inserting lowercase letters
// assuming your CHAR_TO_INDEX(ch) returns 0 based index
// e.g. 'a' => 0, 'b' => 1 ... 'z' => 25
Node* children[30];
// default constructor should be like this
Node(): isLeaf(false) {
for(int i = 0; i < 26; i++) {
children[i] = NULL;
}
}
~Node() {
for(int i = 0; i < 26; i++) {
if(children[i]) {
delete children[i];
children[i] = NULL;
}
}
delete this;
}
};
Please compare your Node class/struct whether its something like this.
Below is my implementation to keep track of the size of each tree in the disjoint set forest.
Can you please tell me what is wrong with it ? I am trying to solve UVa problem https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3638
#include <iostream>
#include <cstdio>
#include <unordered_map>
using namespace std;
class Node {
public :
int id;
Node *parent;
unsigned long long rank;
Node(int id) {
this->id = id;
// this->data = data;
this->rank =1; //size here
this->parent = this;
}
friend class DisjointSet;
};
class DisjointSet {
unordered_map<int,Node*> nodesMap;
Node *find_set_helper(Node *aNode) {
if (aNode == aNode->parent) {
return aNode->parent;
}
return find_set_helper(aNode->parent);
}
void link(Node *xNode,Node *yNode) {
if( xNode->rank > yNode->rank) {
yNode->parent = xNode;
xNode->rank += yNode->rank;
}
// else if(xNode-> rank < yNode->rank){
// xNode->parent = yNode;
// yNode->rank += xNode->rank;
// }
else {
xNode->parent = yNode;
yNode->rank += xNode->rank;
}
}
public:
DisjointSet() {
}
void AddElements(int sz) {
for(int i=0;i<sz;i++)
this->make_set(i);
}
void make_set(int id) {
Node *aNode = new Node(id);
this->nodesMap.insert(make_pair(id,aNode));
}
void Union(int xId, int yId) {
Node *xNode = find_set(xId);
Node *yNode = find_set(yId);
if(xNode && yNode)
link(xNode,yNode);
}
Node* find_set(int id) {
unordered_map<int,Node*> :: iterator itr = this->nodesMap.find(id);
if(itr == this->nodesMap.end())
return NULL;
return this->find_set_helper(itr->second);
}
~DisjointSet(){
unordered_map<int,Node*>::iterator itr;
for(itr = nodesMap.begin(); itr != nodesMap.end(); itr++) {
delete (itr->second);
}
}
};
int main() {
int n,m,k,first,cur;
//freopen("in.in","r",stdin);
scanf("%d %d",&n,&m);
while(n != 0 || m != 0) {
DisjointSet *ds = new DisjointSet();
ds->AddElements(n); // 0 to n-1
//printf("\n n = %d m = %d",n,m);
for(int i=1;i<=m;i++) {
scanf("%d",&k);
//printf("\nk=%d",k);
if ( k > 0 ) {
scanf("%d",&first);
for(int j=2;j<=k;j++) {
scanf("%d",&cur);
ds->Union(first,cur);
}
}
}
Node *zeroSet = ds->find_set(0);
// unsigned long long count = ds->getCount(zeroSet->id);
printf("%llu\n",zeroSet->rank);
delete ds;
scanf("%d %d",&n,&m);
}
return 0;
}
The link function in the above code does the job of updating the tree size.
The solution to the problem is to find the set which elements 0 belongs to and get the size of the representative element of the set.
But I am getting wrong answer with this code.
Can you please help me
In your Union function, check if both nodes are already in the same set.
if(xNode && yNode && xNode != yNode)
link(xNode,yNode);
I realized I can't post answers to my own questions because of my low rep or whatever so i deleted my old question and am reasking it. i changed some things and still can't get what i'm looking for.
Here is most of the code
I left out some of the simpler implementations such as parts of the pathFinder class because I know for sure they work, which is why you'll see playerVertex and time just randomly there.
In the example they used a decreaseKey function, I'm not sure if THAT'S what I'm missing? I'm a beginner here, so constructive criticism is welcome. (hopefully as polite as possible) lol. My problem is printing the path, I get a looop of the same two values over and over again.
class Heap
{
public: Heap();
~Heap();
void insert(double element);
double deletemin();
void print();
int size(){return heap.size();}
private:
int currentIndex;
int left(int parent);
int right(int parent);
int parent(int child);
void heapifyup(int index);
void heapifydown(int index);
private:
vector<double> heap;
};
Heap::Heap()
{
currentIndex = 0;
}
Heap::~Heap()
{}
void Heap::insert(double element)
{
heap.push_back(element);
currentIndex++;
heapifyup(heap.size() - 1);
}
double Heap::deletemin()
{
double min = heap.front();
heap[0] = heap.at(heap.size()-1);
heap.pop_back();
heapifydown(0);
currentIndex--;
return min;
}
void Heap::print()
{
vector<double>::iterator pos = heap.begin();
cout << "Heap = ";
while ( pos != heap.end() )
{
cout << *pos;
++pos;
cout << endl;
}
}
void Heap::heapifyup(int index)
{
while((index>0) && (parent(index) >=0) && (heap[parent(index)] > heap[index]))
{
double tmp = heap[parent(index)];
heap[parent(index)] = heap[index];
heap[index] = tmp;
index = parent(index);
}
}
void Heap::heapifydown(int index)
{
int child = left(index);
if((child > 0) && (right(index) > 0) && (heap[child]>heap[right(index)]))
{
child = right(index);
}
if(child > 0)
{
double tmp = heap[index];
heap[index] = heap[child];
heap[child] = tmp;
heapifydown(child);
}
}
int Heap::left(int parent)
{
int i = ( parent <<1) + 1;
return(i<heap.size()) ? i : - 1;
}
int Heap::right(int parent)
{
int i = ( parent <<1) + 2;
return(i<heap.size()) ? i : - 1;
}
int Heap::parent(int child)
{
if(child != 0)
{
int i = (child - 1) >>1;
return i;
}
return -1;
}
class pathFinder : public weightedGraph
{
private:
vertex* playerVertex;
double time;
public:
string source;
pathFinder()
{
playerVertex = NULL;
time = 0;
}
void Dijkstra(int s,int t)
{
vertex *verts = findVertex(grid[s][t]);
Heap H;
for each(vertex *v in vertexList)
{
if(v->data == verts->data)
{
verts->distance = 0;
verts->pred = NULL;
}
v->distance = INFINITY;
v->pred = NULL;
H.insert(v->data);
}
while(H.size() != 0)
{
vertex *x = findVertex(H.deletemin());
for each(edge *v in x->adjacencyList)
{
if(v->end->visited != true)
{
relax(x,v->end);
v->end->visited = true;
}
else
break;
}
}
}
void relax(vertex *a, vertex *b)
{
if(a->distance + weightFrom(a,b) > b->distance)
{
b->distance = a->distance + weightFrom(a,b);
b->pred = a;
}
}
void printPath(double dest,double dest1)
{
vertex *verta = findVertex(dest);
while(verta->pred->data != dest1)
{
cout<<verta->data<<endl;
verta = verta->pred;
}
}
and i'm not sure about the print path being that. i just used the print path from the BFS algorithm i've implemented before.
Where in your printPath function are you looking for the end of the list?
You keep going verta = verta->pred until the data is not equal to some value.
By the way, don't compare doubles for equality, as it ain't going to happen. See What Every Computer Scientist Should Know About Floating Point.
What happens when you single step with your debugger?
(Try drawing the links and how you traverse them.)