The program I have below finds all the permutations of a given string using a stack without recursion. I am having some trouble understanding what the place in the struct is for and how it plays into the logic for the algorithm. Could anyone help me understand this code? I have a struct that only has two entities:
class Node
{
public:
string word; // stores the word in the node
Node *next;
};
I would just like to understand why the place entity is needed.
Here is the code that finds all the permutations of a given string:
struct State
{
State (std::string topermute_, int place_, int nextchar_, State* next_ = 0)
: topermute (topermute_)
, place (place_)
, nextchar (nextchar_)
, next (next_)
{
}
std::string topermute;
int place;
int nextchar;
State* next;
};
std::string swtch (std::string topermute, int x, int y)
{
std::string newstring = topermute;
newstring[x] = newstring[y];
newstring[y] = topermute[x]; //avoids temp variable
return newstring;
}
void permute (std::string topermute, int place = 0)
{
// Linked list stack.
State* top = new State (topermute, place, place);
while (top != 0)
{
State* pop = top;
top = pop->next;
if (pop->place == pop->topermute.length () - 1)
{
std::cout << pop->topermute << std::endl;
}
for (int i = pop->place; i < pop->topermute.length (); ++i)
{
top = new State (swtch (pop->topermute, pop->place, i), pop->place + 1, i, top);
}
delete pop;
}
}
int main (int argc, char* argv[])
{
if (argc!=2)
{
std::cout<<"Proper input is 'permute string'";
return 1;
}
else
{
permute (argv[1]);
}
return 0;
}
Place helps you to know where is going to be the next character "swap". As you can see, it increments inside the for loop. As you can see, inside that for loop, it behaves like a pivot and i increments in order to behave like a permutator (by swapping characters)
Related
I'm trying to implement a Trie data structure on my own, without looking at other implementations, so simply based on my conceptual knowledge of the structure. I would like to avoid using vectors, simply because they are easy to use... I prefer to use pointers for dynamically allocating memory for arrays when I'm programming as practice. That said, with the structure that I currently have, I have a Node class that contains a pointer to a Node array, a letter (bool), and a marker (bool). My Trie class has a pointer to the starting Node array. Each node array has 26 elements to refer to each letter of the English alphabet from 'a' to 'z' lowercase (I convert each word inserted to lowercase). When a letter is set to 'true' then its letterArray is allocated new memory. Node has a constructor to set letter and marker to false and letterArray to nullptr. I can insert the first letter no problem and go to the next letterArray (which is nullptr at this point) after which memory is allocated to the new array. The problem is, the next letterArray of each Node is also allocated memory, but the constructor is not called on them, resulting in their letter and marker containing garbage, and I'm wondering what is the reason the constructor is not called? Hopefully the code will make this more clear:
class Node {
private:
bool letter;
bool marker;
Node* letterArray;
void initNode();
public:
Node();
bool setLetter(bool set);
bool setMarker(bool set);
bool checkLetter();
bool checkMarker();
char getLetter();
Node*& getNextLetterArray();
};
class Trie {
private:
Node* start;
int wordCount;
int letterCount;
const int totalLetters = 26;
void destroyTrie();
bool initBranch(Node*& nextBranch);
void insertCharAndMove(Node*& ptr, int, int, int);
public:
Trie();
Trie(string firstWord);
~Trie();
bool insertWord(string word);
bool deleteWord(string word);
bool getToLetter(char letter);
string getLowerCase(string word);
bool wordExists(string word);
};
insertWord:
bool Trie::insertWord(string word) {
Node* ptr = start;
string wordLower = getLowerCase(word);
int wordLength = word.length();
if (wordLength <= 0) return false;
for (int i = 0; i < wordLength; i++) {
int charIndex = (word[i] - 'a');
insertCharAndMove(ptr, charIndex, wordLength, i);
}
wordCount++;
return true;
}
void Trie::insertCharAndMove(Node*& ptr, int charIndex, int wordLength, int i) {
if (ptr[charIndex].setLetter(true)) letterCount++;
if (i < wordLength) {
ptr = ptr[i].getNextLetterArray();
initBranch(ptr);
}
else ptr[i].setMarker(true);
}
initBranch:
bool Trie::initBranch(Node*& nextBranch) {
if (nextBranch != nullptr) return false;
nextBranch = new Node[letterCount];
return true;
}
Trie Constructor:
Trie::Trie() {
start = new Node[totalLetters];
wordCount = 0;
letterCount = 0;
}
Node Constructor:
Node::Node() {
initNode();
}
void Node::initNode() {
letter = false;
marker = false;
letterArray = nullptr;
}
getNextLetterArray:
Node*& Node::getNextLetterArray() {
return letterArray;
}
I am trying the following code for Hash table implementation in C++. The program compiles and accepts input and then a popup appears saying " the project has stopped working and windows is checking for a solution to the problem. I feel the program is going in the infinite loop somewhere. Can anyone spot the mistake?? Please help!
#include <iostream>
#include <stdlib.h>
#include <string>
#include <sstream>
using namespace std;
/* Definitions as shown */
typedef struct CellType* Position;
typedef int ElementType;
struct CellType{
ElementType value;
Position next;
};
/* *** Implements a List ADT with necessary functions.
You may make use of these functions (need not use all) to implement your HashTable ADT */
class List{
private:
Position listHead;
int count;
public:
//Initializes the number of nodes in the list
void setCount(int num){
count = num;
}
//Creates an empty list
void makeEmptyList(){
listHead = new CellType;
listHead->next = NULL;
}
//Inserts an element after Position p
int insertList(ElementType data, Position p){
Position temp;
temp = p->next;
p->next = new CellType;
p->next->next = temp;
p->next->value = data;
return ++count;
}
//Returns pointer to the last node
Position end(){
Position p;
p = listHead;
while (p->next != NULL){
p = p->next;
}
return p;
}
//Returns number of elements in the list
int getCount(){
return count;
}
};
class HashTable{
private:
List bucket[10];
int bucketIndex;
int numElemBucket;
Position posInsert;
string collision;
bool reportCol; //Helps to print a NO for no collisions
public:
HashTable(){ //constructor
int i;
for (i=0;i<10;i++){
bucket[i].setCount(0);
}
collision = "";
reportCol = false;
}
int insert(int data){
bucketIndex=data%10;
int col;
if(posInsert->next==NULL)
bucket[bucketIndex].insertList(data,posInsert);
else { while(posInsert->next != NULL){
posInsert=posInsert->next;
}
bucket[bucketIndex].insertList(data,posInsert);
reportCol=true;}
if (reportCol==true) col=1;
else col=0;
numElemBucket++;
return col ;
/*code to insert data into
hash table and report collision*/
}
void listCollision(int pos){
cout<< "("<< pos<< "," << bucketIndex << "," << numElemBucket << ")"; /*codeto generate a properly formatted
string to report multiple collisions*/
}
void printCollision();
};
int main(){
HashTable ht;
int i, data;
for (i=0;i<10;i++){
cin>>data;
int abc= ht.insert(data);
if(abc==1){
ht.listCollision(i);/* code to call insert function of HashTable ADT and if there is a collision, use listCollision to generate the list of collisions*/
}
//Prints the concatenated collision list
ht.printCollision();
}}
void HashTable::printCollision(){
if (reportCol == false)
cout <<"NO";
else
cout<<collision;
}
The output of the program is the point where there is a collision in the hash table, thecorresponding bucket number and the number of elements in that bucket.
After trying dubbuging, I come to know that, while calling a constructor you are not emptying the bucket[bucketIndex].
So your Hash Table constructor should be as follow:
HashTable(){ //constructor
int i;
for (i=0;i<10;i++){
bucket[i].setCount(0);
bucket[i].makeEmptyList(); //here we clear for first use
}
collision = "";
reportCol = false;
}
//Creates an empty list
void makeEmptyList(){
listHead = new CellType;
listHead->next = NULL;
}
what you can do is you can get posInsert using
bucket[bucketIndex].end()
so that posInsert-> is defined
and there is no need to
while(posInsert->next != NULL){
posInsert=posInsert->next;
because end() function is doing just that so use end() function
i want to generate a tree of siblings as under
ABCD
/ | \ \
A B C D
ABCD has four nodes i have taken a array for this *next[]. but this code does not run successfully but it produces the sequence. i have written code in main() which provide characters to the enque function. e.g. str.at(x) where x is variable in for loop.
struct node
{
string info;
struct node *next[];
}*root,*child;
string str, goal;
int dept=0,bnod=0,cl,z=0;
void enqueue(string n);
void enqueue(string n)
{
node *p, *temp;
p=new node[sizeof(str.length())];
p->info=n;
for (int x=0;x<str.length();x++)
p->next[x]=NULL;
if(root==NULL)
{
root=p;
child=p;
}
else
{
cout<<" cl="<<cl<<endl;
if(cl<str.length())
{
child->next[cl]=p;
temp=child->next[cl];
cout<<"chile-info "<<temp->info<<endl;
}
else
cout<<" clif="<<cl<<endl;
}
}
OUTPUT
Enter String: sham
cl=0
chile-info s
cl=1
chile-info h
cl=2
chile-info a
cl=3
chile-info m
RUN FAILED (exit value 1, total time: 2s)
Firstly, where does "RUN FAILED" come from? Is that specific to your compiler?
Secondly, about the line p=new node[sizeof(str.length())];, it probably won't give you what you wanted because you're taking the sizeof of an unsigned integer ( which, depending on your platform is likely to give you 4 regardless of the string length. Which is not what you're after - you want the actual length of the string ).
So - since you're already using std::string, why not use std::vector? Your code would look a lot friendlier :-)
If I take the first couple of lines as your desired output ( sorry, the code you posted is very hard to decipher, and I don't think it compiles either, so I'm ignoring it ;-) )
Would something like this work better for you?
#include <iostream>
#include <vector>
#include <string>
typedef struct node
{
std::string info;
std::vector<struct node*> children;
}Node;
Node * enqueue(std::string str)
{
Node * root;
root = new Node();
root->info = str;
for (int x = 0; x < str.length(); x++)
{
Node * temp = new Node();
temp->info = str[x];
root->children.push_back(temp);
}
return root;
}
int main()
{
Node * myRoot = enqueue("ABCD");
std::cout << myRoot->info << "\n";
for( int i = 0; i < myRoot->children.size(); i++)
{
std::cout << myRoot->children[i]->info << ", ";
}
char c;
std::cin >> c;
return 0;
}
Your code seems not full.
At least the line
p=new node[sizeof(str.length())];
seems wrong.
I guess enqueue should be something similar to the following:
struct node
{
string info;
struct node *next; // [] - is not necessary here
}*root,*child;
string str, goal;
int dept=0,bnod=0,cl,z=0;
void enqueue(string n)
{
node *p, *temp;
p = new node;
p->next = new node[str.length()];
p->info=n;
for (int x=0;x<str.length();x++)
{
p->next[x] = new node;
p->next[x]->next = 0;
p->next[x]->info = str[x];
}
if(root==NULL)
{
root=p;
child=p;
}
}
Please provide more info to give a more correct answer
I am trying to implement the trie as shown on the TopCoder page. I am modifying it a bit to store the phone numbers of the users. I am getting segmentation fault. Can some one please point out the error.
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
int words;
int prefix;
long phone;
struct node* children[26];
};
struct node* initialize(struct node* root) {
root = new (struct node);
for(int i=0;i<26;i++){
root->children[i] = NULL;
}
root->word = 0;
root->prefix = 0;
return root;
}
int getIndex(char l) {
if(l>='A' && l<='Z'){
return l-'A';
}else if(l>='a' && l<='z'){
return l-'a';
}
}
void add(struct node* root, char * name, int data) {
if(*(name)== '\0') {
root->words = root->words+1;
root->phone = data;
} else {
root->prefix = root->prefix + 1;
char ch = *name;
int index = getIndex(ch);
if(root->children[ch]==NULL) {
struct node* temp = NULL;
root->children[ch] = initialize(temp);
}
add(root->children[ch],name++, data);
}
}
int main(){
struct node* root = NULL;
root = initialize(root);
add(root,(char *)"test",1111111111);
add(root,(char *)"teser",2222222222);
cout<<root->prefix<<endl;
return 0;
}
Added a new function after making suggested changes:
void getPhone(struct node* root, char* name){
while(*(name) != '\0' || root!=NULL) {
char ch = *name;
int index = getIndex(ch);
root = root->children[ch];
++name;
}
if(*(name) == '\0'){
cout<<root->phone<<endl;
}
}
Change this:
add(root->children[ch], name++, data);
// ---------------------^^^^^^
To this:
add(root->children[ch], ++name, data);
// ---------------------^^^^^^
The remainder of the issues in this code I leave to you, but that is the cause of your run up call-stack.
EDIT OP ask for further analysis, and while I normally don't do so, this was a fairly simple application on which to expand.
This is done in several places:
int index = getIndex(ch);
root = root->children[ch];
... etc. continue using ch instead of index
It begs the question: "Why did we just ask for an index that we promptly ignore and use the char anyway?" This is done in add() and getPhone(). You should use index after computing it for all peeks inside children[] arrays.
Also, the initialize() function needs to be either revamped or outright thrown out in favor of a constructor-based solution, where that code truly belongs. Finally, if this trie is supposed to be tracking usage counts of words generated and prefixes each level is participating in, I'm not clear why you need both words and prefix counters, but in either case to update the counters your recursive decent in add() should bump them up on the back-recurse.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c++ sort with structs
#include <iostream>
using namespace std;
class fish{
private:
int size;
int price;
public:
fish()
{
size=0;
price=0;
}
void set_price(int x)
{
price=x;
}
void set_size(int g)
{
size=g;
}
int get_size()
{
return size;
}
int get_price()
{
return price;
}
void display()
{
cout<<" Fish price is "<<price<<" Fish size is "<<size<<endl;
}
void sort(fish h[5])
{
for (int o=0;o<=5;o++)
{
fish temp;
temp.set_price(0);
if (h[o].get_price()>h[o+1].get_price())
{
temp.get_price()=h[o].get_price();
h[o].get_price()=h[o+1].get_price();
h[o+1].get_price()=temp.get_price();
}
}
}
};
void main()
{
fish a;
fish b[5];
a.set_size(500);
a.set_price(2);
a.display();
for (int i=0;i<=5;i++)
{
b[i].set_size(i*2);
b[i].set_price(i*100);
}
for (i=0;i<=5;i++)
b[i].display();
}
I want to to find out how I send array b, and sorting it. Also I was going to ask about the destructors and where I can put them into my code.
To swap fish around when you are sorting you should write this
fish tmp = h[o];
h[o] = h[o+1];
h[o+1] = tmp;
You are sorting based on the fish price, but it's the whole fish that should be sorted.
On your other question, there is no need for destructor in this code. Your fish class doesn't need to do any 'clean up' so it doesn't need a destructor.
if you're looking to sort your array by a given element the STL container should be just fine, if not i would use this method
template<class T>
void quickSort(T * elements, unsigned int first, unsigned int last)
{
if(first < last) //make sure params are in bounds
{
T t = elements[first]; //t is PIVOT
unsigned lastLow = first; //create last low item
unsigned i; //used for loop/swapping
for(i = first + 1; i <= last; i++) //run through entire bounds
if(elements[i] < t) //if elements is less than Low
{
<< " adding one onto lastLow...\n";
lastLow++; //move lastLow up one
swap(elements,lastLow, i); //swap lastlow and i
}
swap(elements,first, lastLow); //swap first and lastlow
if(lastLow != first) //if lastlow is not first element
quickSort(elements, first, lastLow - 1);
if(lastLow != last) //if lastlow is not last element
quickSort(elements, lastLow + 1, last);
}
}
this is a common quicksort function used to sort an array. Just replace the right variables to represent your data E.g. T * elements becomes Fish * stuff, T t = Elements[first] becomes double price = stuff[first] and so on.