struct Ternary {
char current;
bool wordend;
Ternary* left;
Ternary* mid;
Ternary* right;
Ternary(char c='#',Ternary* l=NULL, Ternary* m=NULL, Ternary* r=NULL,bool end=false)
{
wordend=end;
current=c;
left=l;
mid=m;
right=r;
}
};
void add(Ternary* t, string s, int i) {
if (t == NULL) {
Ternary* temp = new Ternary(s[i],NULL,NULL,NULL,false);
t=temp;
}
if (s[i] < t->current) {
add(t->left,s,i);
}
else if (s[i] > t->current) {
add(t->right,s,i);
}
else
{
if ( i + 1 == s.length()) {
t->wordend = true;
}
else
{
add(t->mid,s,i+1);
}
}
}
When I add sequence of words using add() the string are getting printed inside
if(t==NULL) segment but tree isn't getting formed i.e nodes are not getting linked.
t=temp;
This line has no effect outside of the add() function. The caller's pointer is not updated.
You could change your function to return a Ternary* (return t in this case at the end of it), and change the call sites to:
Ternary *tree = 0;
tree = add(tree, "hello", 1);
tree = add(tree, "bye", 1);
...
Just a little trick will do:
Replace:
void add(Ternary* t, string s, int i)
With:
void add(Ternary*& t, string s, int i)
That's cleaner than passing and then reading output like this:
tree = add(tree, "bye", 1);
When in C++, make use of their references :) In C you would change the function signature to:
void add(Ternary** t, string s, int i)
and remember to correct t in relevant places.
Well, C++ is clearly cleaner :)
Related
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)
This is an attempted solution of a problem on codefights: https://codefights.com/interview-practice/task/FwAR7koSB3uYYsqDp
My BFS function is not returning the correct character despite me printing right before the return and seeing the correct character in the console. It seems the chracter is being mutated for some reason. When I change the function signature to have a std::string return value, the program crashes. I have no clue what I'm doing wrong. Is it possibly due to lack of freeing pointers or something?
typedef struct proTree{
char value;
proTree* left;
proTree* right;
} proTree;
char BFS(std::vector<proTree*> vec, int currLevel, int level, int pos){
if (currLevel == level){
if (vec[pos-1]->value == 'E'){
return 'E';
} else {
return 'D';
}
}
std::vector<proTree*> newVec;
for (int i=0; i<vec.size(); i++){
newVec.push_back(vec[i]->left);
newVec.push_back(vec[i]->right);
}
BFS(newVec, currLevel+1, level, pos);
}
void createTree(proTree* root, int currLevel, int level){
if (currLevel == level) return;
proTree* eTree = new proTree();
eTree->value = 'E';
proTree* dTree = new proTree();
dTree->value = 'D';
if (root->value=='E'){
root->left = eTree;
root->right = dTree;
} else {
root->left = dTree;
root->right = eTree;
}
createTree(eTree, currLevel+1, level);
createTree(dTree, currLevel+1, level);
}
std::string findProfession(int level, int pos) {
proTree* eTree = new proTree();
eTree->value = 'E';
createTree(eTree, 0, level);
std::vector<proTree*> vec = {eTree};
char result = BFS(vec, 0, level, pos);
if (result == 'E'){
return "Engineer";
} else {
return "Doctor";
}
}
BFS does not return anything (actually returned value is undefined) because last function line is missing return and the value of recursive function invocation is lost. It should be:
return BFS(newVec, currLevel+1, level, pos);
You should pay attention to compilation warnings. In this case compiler should've definitely complained about "missing return in function returning non-void" or something similar.
I'm writing a program to try and get the number of leaves in a binary tree. What I did was I checked if the current ptr was a leaf, and if not, to keeps going to the next subtree. However, when I run it, it keeps returning 2. What am I doing wrong?
I didn't include the source code because its relatively standard (has a rLink, lLink, etc.). There are no errors when I run this:
template <class elemType>
long int bSearchTreeType<elemType>::getLeaves(nodeType<elemType> * current, long int count) const {
if(current->rLink == NULL && current->lLink == NULL) {
count += 1;
return count;
}
if(current->rLink!=NULL) {
getLeaves(current->rLink);
}
if(current->lLink!=NULL) {
getLeaves(current->lLink);
}
}
template <class elemType>
long int bSearchTreeType<elemType>::leaves() const {
if(this->root!=NULL) {
return this->getLeaves(this->root);
}
}
Edit: I declared the function with count = 1 in the parameter list. Thats why I'm able to to that.
I find a few issues.
1) You are calling return this->getLeaves(this->root); but there is no method with that method signature in the code sample you have here.
bSearchTreeType<elemType>::getLeaves(nodeType<elemType> * current, long int count)
2) Your code doesn't handle cases where the current can be null i.e) for tree's like
2
/
1
3) You are not returning anything after traversing the left and the right sub tree.
You could write something like this
template <class elemType>
long int bSearchTreeType<elemType>::getLeaves(nodeType<elemType> * current)
{
if(current == NULL)
return 0;
if(current->rLink == NULL && current->lLink == NULL)
return 1;
int leftSubTree = getLeaves(current->lLink);
int rightSubTree = getLeaves(current->rLink);
return leftSubTree + rightSubTree;
}
I have been going through the debugger but can't seem to pinpoint exactly what is going wrong. I have come to my own conclusion i must be missing a nullptr check somewhere or something. If anyone can provide some help it would be greatly appreciated.
error message from debugger
error msg
which looks like makes the program crash on this line:
if (node->children_[index] == nullptr) {
search function
Node* search(const string& word, Node* node, int index) const {
Node* temp;
//same as recurssive lookup just difference is returns node weather terminal or not
if (index < word.length()) {
index = node->getIndex(word[index]);
if (node->children_[index] == nullptr) {
return nullptr;
}
else {
temp = search(word, node->children_[index], index++);
}
}
return temp; // this would give you ending node of partialWord
}
Node struct for reference
struct Node {
bool isTerminal_;
char ch_;
Node* children_[26];
Node(char c = '\0') {
isTerminal_ = false;
ch_ = c;
for (int i = 0; i < 26; i++) {
children_[i] = nullptr;
}
}
//given lower case alphabetic charachters ch, returns
//the associated index 'a' --> 0, 'b' --> 1...'z' --> 25
int getIndex(char ch) {
return ch - 'a';
}
};
Node* root_;
int suggest(const string& partialWord, string suggestions[]) const {
Node* temp;
temp = search(partialWord, root_, 0);
int count = 0;
suggest(partialWord, temp, suggestions, count);
return count;
}
Might be a very simple thing. Without digging I am not sure about the rank of the -> operator versus the == operator. I would take a second and try putting parenthesis around the "node->children_[index] == nullptr" part like this:
(node->children_[index]) == nullptr
just to make sure that the logic runs like you seem to intend.
Dr t
I believe the root cause is that you're using index for two distinct purposes: as an index into the word you're looking for, and as an index into the node's children.
When you get to the recursion, index has changed meaning, and it's all downhill from there.
You're also passing index++ to the recursion, but the value of index++ is the value it had before the increment.
You should pass index + 1.
[An issue in a different program would be that the order of evaluation of function parameters is unspecified, and you should never both modify a variable and use it in the same parameter list. (I would go so far as to say that you should never modify anything in a parameter list, but many disagree.)
But you shouldn't use the same variable here at all, so...]
I would personally restructure the code a little, something like this:
Node* search(const string& word, Node* node, int index) const {
// Return immediately on failure.
if (index >= word.length())
{
return nullptr;
}
int child_index = node->getIndex(word[index]);
// The two interesting cases: we either have this child or we don't.
if (node->children_[child_index] == nullptr) {
return nullptr;
}
else {
return search(word, node->children_[child_index], index + 1);
}
}
(Side note: returning a pointer to a non-const internal Node from a const function is questionable.)
I'm was wondering if there's a way to check if you're on the first recursive call of a series of many recursive calls.
I'm working on a function that tests to see if the input is a palindrome. After the last recursive call is over, the input string is changed to to the reverse of the original. Now all I want to do is compare the result with the original. But when the base case is reached, I no longer have access to the copy of the original string I made in the else statement.
My thought is then to compare palCopy with palCheck under the else statement but the problem with that is that the program will check this during EVERY recursive call when I only want to check it when control is returned to the original recursive call. Is there a way to conditionally compare palCopy and palCheck only when control is returned to the original recursive call?
void isAPalindrome(MyString palCheck, int bound1, int bound2)
{
if (bound1 >= bound2)
{
cout << palCheck;
}
else
{
MyString palCopy = palCheck; // make a copy of the original argument so as not to alter it
char temp = palCopy[bound1];
palCopy[bound1] = palCopy[bound2];
palCopy[bound2] = temp;
isAPalindrome(palCopy, bound1 + 1, bound2 - 1);
}
C++ has no primitive way to know if you are in the first recursion. But you could use a level variable, that counts the recursion depth. Something like:
void isAPalindrome(MyString palCheck, int bound1, int bound2, int level=0)
{
if (bound1 >= bound2)
cout << palCheck;
else
{
MyString palCopy = palCheck;
char temp = palCopy[bound1];
palCopy[bound1] = palCopy[bound2];
palCopy[bound2] = temp;
isAPalindrome(palCopy, bound1 + 1, bound2 - 1, level+1);
if (level == 0)
// You are in the first recursion call
}
}
In general you can track recursion depth by doing something like:
void recurse(int value, const int depth=0)
{
recurse(value, depth+1);
}
That is using an extra variable to for each of the calls which record the depth of recursion at any given point.
I wouldn't solve this problem this way, but never mind that. The general way to do something like this is to move the recursion into a helper function that takes an extra argument:
static void
is_palindrome_internal(string palCheck, int bound1, int bound2,
bool outermost)
{
...
is_palindrome_internal(..., false);
...
}
void
is_palindrome(string palCheck, int bound1, int bound2)
{
is_palindrome_internal(palCheck, bound1, bound2, true);
}
Then outermost will be true only when the current invocation is the outermost. This approach also has the advantage that you can hide the bound1 and bound2 arguments from the public API (only do this if you don't ever want to operate on substrings, of course).
void
is_palindrome(string palCheck)
{
is_palindrome_internal(palCheck, 0, palCheck.length(), true);
}
You are already passing one copy of string as an arg. You can also pass a reference to the original string so that all levels of recursion have access to both.
void isAPalindrome(MyString palCheck, int bound1, int bound2 , const MyString& original )
{
//Do stuff
isAPalindrome(palCopy, bound1 + 1, bound2 - 1,original);
}
I would use a local struct so that is_palindrome() will accept just one argument:
bool is_palindrome(const std::string& s)
{
struct local
{
static bool is_palin(const std::string& s, int l, int h)
{
return l>= h?true:(s[l] == s[h]? is_palin(s,l+1,h-1):false);
}
};
return local::is_palin(s, 0, s.size() - 1);
}
Online demo : http://www.ideone.com/o1m5C
Use and modify it whichever way you want to.
Make it a seperate function:
void isAPalindromeHelper(MyString& palCheck, int bound1, int bound2)
{
if (bound1 >= bound2)
{
cout << palCheck;
}
else
{
char temp = palCopy[bound1];
palCopy[bound1] = palCopy[bound2];
palCopy[bound2] = temp;
isAPalindromeHelper(palCopy, bound1 + 1, bound2 - 1);
}
}
void isAPalindrome(MyString palCheck)
{
MyString palCopy = palCheck;
isAPalindromeHelper(palCheck, 0, palCheck.size());
if (palCopy == palCheck)
//newstuff here
}