c++ Recursive Tree building with pointers and a state machine - c++

I have a simple state machine (entered below). My major problem is that I am trying to make a recursive call to the function that is my state machine. What I do upon entry of the function is create a new node for my tree and then push that through. When I do a recursive call, I create a new node over and over. This can work, but when adding children to a parent I'm a little confused. Can someone help look over this and help me take my tree node (parent I'm assuming) and attach a child to it?
TreeNodeClass* ProcessTree(TokenT token, vector <list <stateAssoc> >& vecTree, int depth)
{
int state = 1; //Assume this is a new record.
bool noState = false;
bool update = true;
int dex = 0;
string root, value, data, tag;
TreeNodeClass* treeNode;
treeNode = new TreeNodeClass; //Assume a new node per state machine visit.
//Need 11 to break out of loop as well.
while(state != 10)
{
switch(state)
{
case 1: dex = 1;
break;
case 2: dex = 6;
root = yylval;
break;
case 3: dex = 7;
break;
case 4: dex = 3;
value = yylval;
treeNode->CreateAttrib(root, value);
break;
case 5: dex = 2;
break;
case 6: dex = 4;
data = yylval;
break;
case 7: //Really Don't do anything. Set the tag creation at 8...
dex = 8;
tag = yylval;
if(data != "" and data != "authors")
treeNode->CreateTag(data, tag);
break;
case 8: {
//New TreeNode already grabbed.
//TreeNodeClass* childNode = new TreeNodeClass;
childNode = ProcessTree(token, vecTree, depth+1);
childNode->SetHeight(depth);
treeNode->AddChildren(childNode);
}
token = TokenT(yylex()); //Get a new token to process.
dex = 5;
break;
case 9: dex = 9;
update = false;
if(yylval != treeNode->ReturnTag())
{
state = 11;
}
break;
case 10: update = false;
treeNode->SetHeight(1);
break;
default: cout << "Error " << endl;
cout << state << endl;
cin.get();
break;
}
if(!noState)
state = FindMatch(vecTree[dex], token);
if(update)
token = TokenT(yylex());
else
update = true;
}
return treeNode;
}
You may assume that the dex is simply an index to an array of lists that will return a correct state or 11 (error). Also you may assume that this funciton has atleast been called once on an input file and has started parsing. Thank you for your help.

Looking at your code, you have
int state = 1;
//Code
while(state != 10) {
switch(state) {
case:1 dex = 1; break; //Only case you run
//more cases
case 8: { //never enter here
//New TreeNode already grabbed.
//TreeNodeClass* childNode = new TreeNodeClass;
childNode = ProcessTree(token, vecTree, depth+1);
childNode->SetHeight(depth);
treeNode->AddChildren(childNode); //should work if assuming function is correct
}
//stuff
break;
default: break;//blah
}
}
//blah
return treeNode;
I see no other reason than the fact state is always equal to 1 that your code at case 8 would fail. This is assuming treeNodeClass::AddChildren(TreeNodeClass*) has been properly implemented. WIthout that code, I can assume it's not your problem. Is there some method in which state wouldn't be 1 in the switch?

Related

Why did one linked list's end node change from NULL to another list's next node?

The first function, linkAndMove, is used for basic linking together and moving point process.
The Union function is used for finding all numbers in linked lists la and lb (without repeats)
My test example: la {1,3} lb{3,5}
But in the last when la point to NULL, and lb point to 5.
After first function linkAndMove, the list la changed to {1,3,5}
Why did la's end node change from NULL to lb's now node 5?
before first function
after first function
void linkAndMove(slink **pNode, slink **qNode, slink **finNode,
int linkFlag, int moveFlag) {
if (linkFlag == -1 || moveFlag == -1) {
cout << "ERROR! No matched logical in basic link list process." << endl;
exit(1);
}
switch (linkFlag) {
case 0:
if ((*finNode)->data != (*pNode)->data) {
(*finNode)->next = (slink *) malloc(sizeof(MemLEN));
(*finNode)->next = (*pNode);
(*finNode) = (*finNode)->next;
}
break;
case 1:
if ((*finNode)->data != (*qNode)->data) {
(*finNode)->next = (slink *) malloc(sizeof(MemLEN));
(*finNode)->next = (*qNode);
(*finNode) = (*finNode)->next;
}
break;
case 2:
break;
default:
cout << "ERROR! No matched logical in basic link list process." << endl;
exit(1);
}
switch (moveFlag) {
case 0:
(*pNode) = (*pNode)->next;
break;
case 1:
(*qNode) = (*qNode)->next;
break;
case 2:
(*pNode) = (*pNode)->next;
(*qNode) = (*qNode)->next;
break;
default:
cout << "ERROR! No matched logical in basic link list process." << endl;
exit(1);
}
}
void Union(slink *la, slink *lb, slink *lc) {
slink *pNode, *qNode;
pNode = la->next;
qNode = lb->next;
int linkFlag, moveFlag;
while (pNode != NULL || qNode != NULL) {
linkFlag = -1;
moveFlag = -1;
if (pNode == NULL) {
linkFlag = moveFlag = 1;
} else if (qNode == NULL) {
linkFlag = moveFlag = 0;
} else {
if (pNode->data > qNode->data) {
linkFlag = 1;
moveFlag = 1;
} else if (pNode->data < qNode->data) {
linkFlag = 0;
moveFlag = 0;
} else {
linkFlag = 0;
moveFlag = 2;
}
}
/*if (pNode == NULL) {
linkAndMove(NULL, &qNode, &lc, linkFlag, moveFlag);
} else*/
linkAndMove(&pNode, &qNode, &lc, linkFlag, moveFlag);
}
}
I found the reason.
Because in function linkAndMove, the pointer finNode is connected to the list la's node. In preivous codes, using node's next to connect pNode, so changed the la's end node from NULL to that node.
The solution I found is create new node for list lc, that cannot infect the orignal data list la. Codes here.
switch (linkFlag) {
case 0:
if ((*finNode)->data != (*pNode)->data) {
(*finNode)->next = initLinkNode();
(*finNode) = (*finNode)->next;
(*finNode)->data = (*pNode)->data;
}
break;
case 1:
if ((*finNode)->data != (*qNode)->data) {
(*finNode)->next = initLinkNode();
(*finNode) = (*finNode)->next;
(*finNode)->data = (*qNode)->data;
}
break;
case 2:
break;
default:
cout << "ERROR! No matched logical in basic link list process." << endl;
exit(1);
}

C++ Boggle Solver Issues

void scoreBoardHelper(Grid<char>& board, Lexicon& lex, Set<string>& visitedPrefixes, string current, GridLocation location, Set<string>& foundWords, Set<GridLocation> visitedTiles){
if(lex.contains(current) && current.size()>3){
foundWords.add(current);
}
if(current == ""){
current += board[location];
visitedTiles.add(location);
}
//check neighbors
GridLocation neighbor = location;
for(int i = 0; i<8; i++){
switch (i) {
case 0:
neighbor.col++;
break;
case 1:
neighbor.col--;
break;
case 2:
neighbor.row++;
break;
case 3:
neighbor.row--;
break;
case 4:
neighbor.col++;
neighbor.row++;
break;
case 5:
neighbor.col--;
neighbor.row--;
break;
case 6:
neighbor.col--;
neighbor.row++;
break;
case 7:
neighbor.col++;
neighbor.row--;
break;
}
if(board.inBounds(neighbor) && board[neighbor]!=current[current.size()-2] && !visitedTiles.contains(neighbor) && lex.containsPrefix(current + board[neighbor]) && !visitedPrefixes.contains(current + board[neighbor])){
visitedPrefixes.add(current + board[neighbor]);
visitedTiles.add(neighbor);
scoreBoardHelper(board, lex, visitedPrefixes, current + board[neighbor], neighbor, foundWords, visitedTiles);
}
neighbor = location;
}
}
int scoreBoard(Grid<char>& board, Lexicon& lex) {
Set<string> visitedPrefixes;
Set<GridLocation> visitedTiles;
string current = "";
GridLocation location;
Set<string> foundWords;
for(int r=0;r<board.numRows();r++){
location.row=r;
for(int c=0;c<board.numCols();c++){
location.col=c;
scoreBoardHelper(board, lex, visitedPrefixes, current, location, foundWords, visitedTiles);
}
}
int previousPoints = 0;
for(string word : foundWords){
cout<<"found word: "<<word<<endl;
previousPoints += points(word);
}
return previousPoints;
}
I wrote these 2 functions but they don't seem to solve boggle. When I remove the !visitedTiles.contains(neighbor) check, it works as expected but it finds extra words that it should discard. When it has this check it narrows the solution unexpectedly and finds 2 words where it should find many more. Note: The points function works fine.

Trouble with a recursive algorithm and pointers

So I'm trying to make an algorithm that starts at the first "room" and then recursively goes outward and starts deleting all rooms from the outside in. A room is a struct with 4 "doors" (pointers to rooms): North, South, East, and West.
The function takes two arguments: pointer to the current room and a char (to identify the direction: North, South, East, or West).
Here is my logic for the algorithm (roomDelete):
Base Case
Start at the first room and call the function (roomDelete) on any non-NULL pointers; input to the function calls should be appropriate pointer to the room to the N/S/E/W, and appropriate char representing the direction N/S/E/W.
Check to see that all pointers (N/S/E/W) are NULL --> delete this current room.
Done/return.
Recursion
Make sure not to backtrack (travel back in the direction you came from), by using a char to hold the value opposite of the direction char.
Call the function on any non-NULL, non-backtrack pointers/directions.
Break connection to previous room.
Check to see that all pointers are NULL --> delete this current room.
Here is a simple picture on what the rooms/pointers look like:
http://i.imgur.com/btKz5JB.png
I have code that I tried to test. If I have a room (by itself), then the function works. But as soon as another room is thrown into the mix, then the function never returns/finishes. I'm not sure why. Is my logic sound? Am I missing something?
Any help is appreciated.
CODE:
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
#define NUM_DOORS 4
struct room {
struct room * north;
struct room * south;
struct room * east;
struct room * west;
} ;
int roomDelete(room *, char);
int main(void)
{
room * test_ptr = new room;
cout << "Created room at location: " << test_ptr << endl;
test_ptr->north = NULL;
test_ptr->south = NULL;
test_ptr->east = NULL;
test_ptr->west = NULL;
test_ptr->north = new room;
cout << "Created room at location: " << test_ptr->north << endl;
test_ptr->north->north = NULL;
test_ptr->north->south = test_ptr;
test_ptr->north->east = NULL;
test_ptr->north->west = NULL;
int test = roomDelete(test_ptr, '\0');
cout << test << endl;
return 0;
}
int roomDelete(room * room_ptr, char coord)
{
char coordinate[NUM_DOORS] = {'N', 'S', 'E', 'W'};
char coordinate_opposite[NUM_DOORS] = {'S', 'N', 'W', 'E'};
char coord_opp = '\0';
// call function on any remaining rooms
if(coord == '\0') // this is the beginning/initial room
{
for(int i = 0; i < NUM_DOORS; i++)
{
switch (coordinate[i])
{
case 'N':
{
if(room_ptr->north != NULL)
roomDelete(room_ptr->north, 'N');
break;
}
case 'S':
{
if(room_ptr->south != NULL)
roomDelete(room_ptr->south, 'S');
break;
}
case 'E':
{
if(room_ptr->east != NULL)
roomDelete(room_ptr->east, 'E');
break;
}
case 'W':
{
if(room_ptr->west != NULL)
roomDelete(room_ptr->west, 'W');
break;
}
default:
cout << "There was an error deallocating for the room at location: " << room_ptr << endl;
}
}
// delete the current room
if(room_ptr->north == NULL && room_ptr->south == NULL && room_ptr->east == NULL && room_ptr->west == NULL)
{
cout << "Deleting room at location: " << room_ptr << endl;
delete room_ptr;
}
else
return 2; // outward rooms have not been deleted yet
}
else // recursion
{
// this sets the value for the door that won't be handed to the delete function
for(int j = 0; j < NUM_DOORS; j++)
{
if(coord == coordinate[j])
coord_opp = coordinate_opposite[j];
}
if(coord_opp == '\0')
{
cout << "An error occurred while setting the value of the opposite coordinate.\n";
return 1;
}
// call the function on any remaining rooms
for(int k = 0; k < NUM_DOORS; k++)
{
if(coordinate[k] != coord_opp) // this is to avoid backtracking (which would cause infinite recursion)
{
switch (coordinate[k])
{
case 'N':
{
if(room_ptr->north != NULL)
roomDelete(room_ptr->north, 'N');
break;
}
case 'S':
{
if(room_ptr->south != NULL)
roomDelete(room_ptr->south, 'S');
break;
}
case 'E':
{
if(room_ptr->east != NULL)
roomDelete(room_ptr->east, 'E');
break;
}
case 'W':
{
if(room_ptr->west != NULL)
roomDelete(room_ptr->west, 'W');
break;
}
default:
cout << "There was an error deallocating for the room at location: " << room_ptr << endl;
}
}
}
// delete connection (ptr's) between current room and previous
switch(coord)
{
case 'N':
{
room_ptr->south->north = NULL;
room_ptr->south = NULL;
}
case 'S':
{
room_ptr->north->south = NULL;
room_ptr->north = NULL;
}
case 'E':
{
room_ptr->west->east = NULL;
room_ptr->west = NULL;
}
case 'W':
{
room_ptr->east->west = NULL;
room_ptr->east = NULL;
}
default:
cout << "There was a problem with severing the connection for the room at location: " << room_ptr << endl;
}
// delete current room
if(room_ptr->north == NULL && room_ptr->south == NULL && room_ptr->east == NULL && room_ptr->west == NULL)
{
cout << "Deleting room at location: " << room_ptr << endl;
delete room_ptr;
}
else
return 3; // outward rooms have not been deleted yet
}
return 0; // successful in deallocating the entire complex
}
I don't understand your algorithm, but I can tell where you are failing.
switch (coord)
{
case 'N':{
room_ptr->south->north = NULL;
room_ptr->south = NULL;
}
case 'S':{
room_ptr->north->south = NULL; // <-- Program Fails Here
room_ptr->north = NULL;
}
room_ptr->north at this moment is a null pointer and you are thus writing at location you are not allowed to.
Maybe you don't fully understand switch statements? It has so called "fall-through" behavior , i.e. it doesn't break out by itself just because it is a new case, it will just find a place where to start executing code and keep executing it until it hits "}" or finds explicitly written "break;" in it's way.

an error about heap corrupting

I wrote a C++ program, actually it's a game.
I've received this error:
Windows has triggered a breakpoint in bla bla...
Can someone help me?
That's code, but error occur on line AAA:
void r_motions(char **map,int size)
{
int parameter_i,parameter_j,player_i,player_j;
int *r_location_i = new int[1],*r_location_j = new int[1];
player_finder(map,size,player_i,player_j);
int r_num = robots_finder(map,size,r_location_i,r_location_j);
for(int i=1;i<=r_num;i++)
{
parameter_i =0;
parameter_j =0;
if(r_location_i[i]>player_i) parameter_i = -1;
if(r_location_i[i]<player_i) parameter_i = 1;
if(r_location_j[i]>player_j) parameter_j = -1;
if(r_location_j[i]<player_j) parameter_j = 1;
map[r_location_i[i]][r_location_j[i]] = '.';
r_location_i[i] = r_location_i[i]+parameter_i;
r_location_j[i] = r_location_j[i]+parameter_j;
}
for(int i=1;i<=r_num;i++)
{
switch (map[r_location_i[i]][r_location_j[i]])
{
case '.':
map[r_location_i[i]][r_location_j[i]] = '+';
break;
case '#':
map[r_location_i[i]][r_location_j[i]] = '+';
print_map(map,size);
cout << "Robots win ." << endl;
sleep(1000);
exit(1);
break;
case '+':
map[r_location_i[i]][r_location_j[i]] = '*';
break;
case '*':
map[r_location_i[i]][r_location_j[i]] = '*';
break;
default: cout << "what r u doin' ??";
break;
}
}
}
All right, just for starters, look at this:
int *r_location_i = new int[1], ...;
...
for(int i=1;i<=r_num;i++)
{
parameter_i =0;
...
if(r_location_i[i]>player_i) parameter_i = -1; // reading outside the array
...
r_location_i[i] = r_location_i[i]+parameter_i; // writing outside the array
...
}
Go back and study arrays. Do not touch another pointer until you know exactly what's wrong with the code above.

C++ Stack Implementation (not working right)

Here's the previous thread where I got help with this same lab. My stack is misbehaving, to say the least, when I add an item to stack, to print out later, it doesn't seem to add right. I always print out plus'(+), not matter if I enter another operand(*,/,+).
I am using a stack to convert a, user inputed, infix express to postfix. It seems to work fine except printing out the operands in the stack at the end.
#include <iostream>;
#include <vector>
using namespace std;
class DishWell{
public:
char ReturnFront(){
return Well.front();
}
void Push(char x){
Well.push_back(x);
}
void Pop(){
Well.pop_back();
}
bool IsEmpty(){
return Well.empty();
}
private:
vector<char> Well;
};
bool Precidence(char Input, char Stack){
int InputPrecidence,StackPrecidence;
switch (Input){
case '*':
InputPrecidence = 4;
break;
case '/':
InputPrecidence = 4;
break;
case '+':
InputPrecidence = 3;
break;
case '-':
InputPrecidence = 3;
break;
case '(':
InputPrecidence = 2;
break;
default:
InputPrecidence = 0;
}
switch (Stack){
case '*':
StackPrecidence = 4;
break;
case '/':
StackPrecidence = 4;
break;
case '+':
StackPrecidence = 3;
break;
case '-':
StackPrecidence = 3;
break;
case '(':
StackPrecidence = 2;
break;
default:
StackPrecidence = 0;
}
if(InputPrecidence>StackPrecidence) return true;
else return false;
}
int main(int argc, char** argv) {
DishWell DishTray;
char Input;
bool InputFlag;
InputFlag = true;
cout<<"Enter Input, invalid input will terminate"<<endl;
while(InputFlag){
cout<<"Input: ";
cin>>Input;
cout<<endl;
if((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||Input>='0'&&Input<='9')))//If Digit or Number
cout<<Input;
if((Input=='*'||Input=='/'||Input=='+'||Input=='-')){//if operand
if(DishTray.IsEmpty())
DishTray.Push(Input);
else if(Precidence(Input,DishTray.ReturnFront()))
DishTray.Push(Input);
else if(!Precidence(Input,DishTray.ReturnFront()))
cout<<"Output: "<<Input<<endl;
}
else if(!((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||(Input>='0'&&Input<='9')))||((Input=='*'||Input=='/'||Input=='+'||Input=='-')))//if not digit/numer or operand
InputFlag = false;
}
int counter = 0;
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnFront()<<endl;
DishTray.Pop();
}
return 0;
Thank you, Macaire Bell
Your loop calls front(), but then calls pop_back(). This will always return the first element in the vector, until all elements are popped, since you are never erasing the front element. Your ReturnFront() method should probably be:
char ReturnBack(){
return Well.back();
}
And then your loop at the end:
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnBack()<<endl; // will return last element
DishTray.Pop(); // actually pop the element printed
}
When you're working with a stack, you usually want to be able to see the value on the top of the stack. Your class only allows the very first item pushed (i.e. the bottom of the stack) to be visible. Your ReturnFront() should probably return Well.back() and perhaps it should be called something like ReturnTop().
Wouldn't you want to see the value returned from pop_back() instead if discarding it as you're currently doing?