Lookup function not working - c++

I'm trying to have an algorithm that makes a DFA for a tic tac toe game. With the code I have right now, there are repeating states. I made a lookup function to see if the state already before adding it and add the already made state to a the parent state's vector of children.
I have tried implementing it, but I'm still getting the same number of nodes that I was getting before I implemented it meaning its never finding another state that with the same 'position' array and it is suppose to. I don't see what I'm doing wrong. It never returns anything.
UPDATE: I do know that it is returning to soon and not going through all the elements, but I don't know how to make it go through all the states and make it stop returning too soon.
UPDATE 2.0: So I've changed where my lookup is, it is now in my Main.cpp file. I also changed how it goes through, but it still isn't returning correctly.
Any ideas? Here is my code:
States.cpp
#include "States.hpp"
State::State(){
final = false;
reject = false;
draw = false;
for (int i = 0; i < 9; i++)
_position[i] = 2;
firstPlayerMove = true;
_children = new vector<State *> ();
};
void State::setStateChildren(State *s){
_children->push_back(s);
}
vector<State*> *State::getChildren(){
return _children;
}
void State::setFirstMove(bool b){
firstPlayerMove = b;
}
bool State::firstMove(){
return firstPlayerMove;
}
void State::setPosition(int p[]){
for (int i = 0; i < 9; i++){
_position[i] = p[i];
}
}
int *State::position(){
return _position;
}
bool State::isFinal(){
return final;
}
bool State::isReject(){
return reject;
}
Main.cpp
#include <iostream>
#include <vector>
#include "States.hpp"
using namespace std;
void dependents(State *root, State *state, bool first);
int size (State *s);
bool win(int p[], int symbol);
bool draw(int p[]);
void CreateDFA(State *root, State *state, int n){
if (n == 0 || state == nullptr)
return;
if (state->isFinal() || state->isReject() || state->isDraw())
return;
dependents(root, state, state->firstMove());
for (vector<State*>::iterator iter = state->getChildren()->begin(); iter != state->getChildren()->end(); iter++){
CreateDFA(root, *iter, n - 1);
}
}
void dependents(State *root, State *state, bool first){
int symbol;
if (first)
symbol = 1;
else
symbol = 0;
int count = 0;
while (count < 9){
if (state->position()[count] == 2 && state->position()[count] != 1 && state->position()[count] != 0){
int check[9];
for(int i = 0; i < 9; i++)
check[i] = state->position()[i];
check[count] = symbol;
State *child = root->find(root, check);
if (child == nullptr){
child = new State();
child->setPosition(state->position());
child->setFirstMove(!(state->firstMove()));
child->position()[count] = symbol;
child->setFinal(win(child->position(), 1));
child->setReject(win(child->position(), 0));
child->setDraw(draw(child->position()));
}
state->setStateChildren(child);
}
count++;
}
}
bool win(int p[], int symbol){
if(p[0] == symbol && p[1] == symbol && p[2] == symbol)
return true;
if(p[0] == symbol && p[4] == symbol && p[8] == symbol)
return true;
if(p[0] == symbol && p[6] == symbol && p[3] == symbol)
return true;
if(p[1] == symbol && p[4] == symbol && p[7] == symbol)
return true;
if(p[2] == symbol && p[4] == symbol && p[6] == symbol)
return true;
if(p[2] == symbol && p[5] == symbol && p[8] == symbol)
return true;
if(p[3] == symbol && p[4] == symbol && p[5] == symbol)
return true;
if(p[6] == symbol && p[7] == symbol && p[8] == symbol)
return true;
return false;
}
bool draw(int p[]){
if(p[0] != 2 && p[1] != 2 && p[2] != 2 && p[3] != 2 && p[4] != 2 && p[5] != 2 && p[6] != 2 && p[7] != 2 && p[8] != 2){
cout << "Set Draw" << endl;
return true;
}
return false;
}
int size (State *s){
if (s == nullptr)
return 0;
int count = 0;
for(vector<State*>::iterator iter = s->getChildren()->begin(); iter != s->getChildren()->end(); iter++)
count = size(*iter) + count;
return count + 1;
}
bool check(int p[], int a[]){
for(int i = 0; i < 9; i++)
if (p[i] != a[i])
return false;
return true;
}
State *find(State * root, int p[]){
if (root->isFinal() || root->isReject() || root->isDraw())
return nullptr;
State * s = nullptr;
for (vector<State*>::iterator iter = root->getChildren()->begin(); iter != root->getChildren()->end(); iter++){
if(check((*iter)->position(), p)){
s = new State (**iter);
break;
}
else
s = find((*iter), p);
}
return s;
}

Related

Backspace String Compare given two strings s and t, return true if they are equal

I am getting a runtime error for this test case using stack
"bxj##tw", "bxj###tw"
Line 171: Char 16: runtime error: reference binding to misaligned address 0xbebebebebebec0ba for type 'int', which requires 4 byte alignment (stl_deque.h)
0xbebebebebebec0ba: note: pointer points here
<memory cannot be printed>
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_deque.h:180:16
class Solution {
public:
bool backspaceCompare(string s, string t) {
stack<int>st1;
stack<int>st2;
for(int i=0; i<s.size(); i++){
if(st1.empty() && s[i]!='#'){
st1.push(s[i]);
}
else{
if(!st1.empty() && s[i]=='#'){
st1.pop();
}
else if(s[i]=='#' && (st1.empty())){
continue;
}
else{
st1.push(s[i]);
}
}
}
for(int i=0; i < t.size(); i++){
if(st2.empty() && t[i]!='#'){
st2.push(t[i]);
}
else{
if(!st2.empty() && t[i]=='#'){
st2.pop();
}
else if(t[i]=='#' && st2.empty()){
continue;
}
else{
st2.push(t[i]);
}
}
}
if(st1.empty() && st2.empty()){
return "";
}
while(!st1.empty()){
if(st1.top()!= st2.top()){
return false;
}
else{
st1.pop();
st2.pop();
}
}
return true;
}
};
I wouldn't use a stack<char> since the natural representation is a string, and you're not using any functionality of the stack's ability to expand or shrink in the front (other than the end where you can just say return a == b). string has push_back and pop_back methods as well.
For small input (like the ones guaranteed for this challenge problem), I'd recommend constructing the two "editors" and comparing with ==:
class Solution {
public:
bool backspaceCompare(string s, string t) {
return backspace(s) == backspace(t);
}
private:
string backspace(const string &s) {
string editor = "";
string::const_iterator commandItr = s.cbegin();
while(commandItr != s.cend())
if(*commandItr == '#' && !editor.empty()) {
editor.pop_back();
++commandItr;
} else if(*commandItr != '#')
editor.push_back(*commandItr++);
else
++commandItr;
return editor;
}
};
However, they did challenge the coder to use O(1) memory. Here is an example of that:
class Solution {
public:
bool backspaceCompare(string s, string t) {
int left = s.size() - 1;
int right = t.size() - 1;
while(true) {
left = backspace(s, left);
right = backspace(t, right);
if (left == -1 && right == -1)
return true;
if (left == -1 && right != -1 || right == -1 && left != -1)
return false;
if(s[left--] != t[right--])
return false;
}
}
private:
// Returns first index from back that indexes to a non-deleted character
int backspace(string const &s, int startingIndex) {
if(startingIndex == -1)
return -1;
if(s[startingIndex] != '#')
return startingIndex;
unsigned backspaceCount = 0;
while(true) {
while(startingIndex != -1 && s[startingIndex] == '#') {
++backspaceCount;
--startingIndex;
}
while (startingIndex != -1 && backspaceCount && s[startingIndex] != '#') {
--startingIndex;
--backspaceCount;
}
if (startingIndex == -1)
return -1;
else if(s[startingIndex] != '#' && !backspaceCount)
return startingIndex;
}
}
};

Infix to Postfix using Stacks w/ Professor's Algorithm

Been scratching my head for hours already and I have no clue what my mistake is. I'm following my professor's derived algorithm step by step and I don't know why it isn't working properly.
Here's the derived Algorithm:
Here's the code that I tried to make:
#include <iostream>
#include "ecpe202.h"
#define Max 100
using namespace std;
int getICP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 4;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 4;
}
}
int getISP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 3;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 0;
}
}
bool isOperator(char ch){
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '*' || ch == '(' || ch == ')'){
return (true);
}
else{
return (false);
}
}
int main(){
char infix[Max];
char ch;
int length;
myQueue que;
myStack stk;
createQ(que);
createS(stk);
cout << "Enter an infix Expression: ";
cin >> infix;
cout << endl << endl;
cout << "The postfix Expression: ";
length = strlen(infix);
for (int i = 0; i < length; i++){
addQ(que, infix[i]);
}
while (!isEmptyQ(que)){
ch = retrieveQ(que);
//start of infix to postfix algo
//1. push
if (ch == '('){
pushS(stk, ch);
}
//2. if scanned is operand
if (!isOperator(ch)){
cout << ch;
}
else{
//2.1 push if...
if (isEmptyS(stk) || getICP(ch) > getISP(topS(stk)) || topS(stk) == '('){
pushS(stk, ch);
}
//2.2. pop all operators
else{
while(!isEmptyS(stk) && getISP(topS(stk)) >= getICP(ch) || topS(stk) == '('){
cout << popS(stk);
}
}
pushS(stk, ch);
}
//3. If scanned ')'
bool loop = true;
if (ch == ')'){
do{
if (ch == '('){
loop = false;
}
else{
cout << popS(stk);
}
}while(loop == true);
}
//repeat 1-3
}
cout << endl;
}
For the ecpe202.h:
#include<dos.h>
#include<windows.h>
#define FOREVER true
#define MAXSTACK 100
#define MAXQUEUE 100
using namespace std;
struct myStack{
int tos;
char s[MAXSTACK];
};
struct myQueue{
int head, tail, q[MAXQUEUE];
};
//STACK
void createS(myStack &S){
S.tos=-1;
}
void pushS(myStack &S, char item){
S.s[++S.tos] = item;
}
char popS(myStack &S){
return(S.s[S.tos--]);
}
char topS(myStack S){
return (S.s[S.tos]);
}
bool isFullS(myStack S){
if(S.tos == MAXSTACK - 1)
return true;
return false;
}
bool isEmptyS(myStack S){
if (S.tos == -1)
return true;
return false;
}
//QUEUE
void createQ(myQueue &Q){
Q.head = 0;
Q.tail = 0;
}
void addQ(myQueue &Q, char item){
Q.q[Q.tail++] = item;
Q.tail %= MAXQUEUE;
}
char retrieveQ(myQueue &Q){
char temp;
temp = Q.q[Q.head++];
Q.head %= MAXQUEUE;
return temp;
}
bool isFullQ(myQueue Q){
if (Q.tail == MAXQUEUE)
return true;
return false;
}
bool isEmptyQ(myQueue Q){
if (Q.tail == Q.head)
return true;
return false;
}
//GOTOXY
void gotoxy(int x, int y){
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void clrscr(){
system("CLS");
}
The output that my code:
What seems to be wrong in my program? tried re-reading it a couple of times and I still can't fix it.

g++ saying function doesn't exist even when including the proper header

So I am working on some homework for my uni and need to convert a string to a float. For whatever reason g++ is complaining that the 'stof' function doesn't exist. Although I have included the required header. Here is my code, the error is on the line that says
holder = stof(x.substr(0, end_of_num));
#include <iostream>
#include <string>
#include <list>
using namespace std;
float process_func(string x);
bool isPartOfNum(char x);
int main() {
string x;
while (true) {
cout << "input a string" << endl;
getline(cin, x);
cout << process_func(x);
}
return 0;
}
float process_func(string x) {
int end_of_num =0;// used to find last index from num
int negMult = 1; //used to multiply value at end if there was a negative
bool onNum = false; //used to
list <float> numList;
list <char> operList;
if ((x.at(0) < 48 || x.at(0) > 57) && x.at(0) != '-') //check if start of string doesnt have a number or negative symbol
return -1;
if (x.at(0) != '-')
negMult = -1;
float holder;// temp holder for floats
int i = 0;
while (i<x.length()) {
if (isPartOfNum(x.at(i))) {
end_of_num++;
onNum = true;
}
else if (onNum) {
holder = stof(x.substr(0, end_of_num));
numList.push_back(holder); //adds num as float to list
x.erase(0, end_of_num + 1); //+1 removes the space after the number before the operator
end_of_num = 0;
onNum = false;
}
if (x.at(i) == '+' || x.at(i) == '-' || x.at(i) == '*' || x.at(i) == '/') {
operList.push_back(x.at(i));
}
} //at this point both lists should be full of all needed pieces of info
int answer = 0;
int temp;
bool firstOper=true; // used to hold first operation
while (numList.size() >=2) { //requires at least 2 entries for last operation
while (!operList.empty()) {
temp = numList.front();
numList.pop_front();
if (operList.front() == '+') {
if (firstOper) {
answer = temp + numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer += temp;
}
}
else if (operList.front() == '-') {
if (firstOper) {
answer = temp - numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer -= temp;
}
}
else if (operList.front() == '*') {
if (firstOper) {
answer = temp * numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer *= temp;
}
}
else if (operList.front() == '/') {
if (firstOper) {
answer = temp / numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer /= temp;
}
}
operList.pop_front();
}
}
return answer;
}
bool isPartOfNum(char x) {
if ((x >= 48 && x <= 57) || (x == '-' || x == '.'))
return true;
return false;
}
Solved by compiling using c++ 11

Dictionary function with BST returns vector

The function dictionary_select returns a vector which contains words that are starting with W.
In this code dictionary_select gives an error message. But I can not find it. Is there anybody can help me?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct tree {
string data;
tree *left;
tree *right;
};
typedef tree* dictionary;
bool dictionary_ins_word(dictionary & D, const string & W)
{
if(W == "" || W == " ")
return false;
tree* dic;
dic = new tree;
dic->data = W;
dic->left = NULL;
dic->right = NULL;
if(D == NULL) {
D = dic;
}
else {
if(W <= D->data)
dictionary_ins_word(D->left, W);
else
dictionary_ins_word(D->right, W);
}
return true;
}
bool dictionary_lookup(const dictionary & D, const string & W)
{
if(W == "" || W == " ")
return false;
if(D == NULL)
return false;
if(W == D->data)
return true;
else if (W < D->data)
return dictionary_lookup(D->left, W);
else
return dictionary_lookup(D->right, W);
}
bool dictionary_is_empty(const dictionary & D)
{
if(D == NULL)
return true;
else
return false;
}
bool dictionary_del_word(dictionary & D, const string & W)
{
if(!dictionary_lookup(D, W))
return false;
if(W < D->data)
dictionary_del_word(D->left, W);
else if(W > D->data)
dictionary_del_word(D->right, W);
else {
string item;
tree* temp;
temp = D;
if(D->left == NULL) {
D = D->right;
delete temp;
}
else if(D->right == NULL) {
D = D->left;
delete temp;
}
else {
while(D->left->right != NULL)
D->left = D->left->right;
item = D->left->data;
D->data = item;
dictionary_del_word(D->left, W);
}
}
return true;
}
bool dictionary_min(string & W, const dictionary & D)
{
dictionary min;
if(D == NULL)
return false;
min = D;
while(min->left != NULL)
min = min->left;
W = min->data;
return true;
}
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(W <= D->data)
return dictionary_select(D->left, W);
else
return dictionary_select(D->right, W);
}
int main()
{
bool b[5];
dictionary l;
string W, str;
vector <string> vec;
l = new tree;
l->data = "berdi";
l->left = NULL;
l->right = NULL;
b[0] = dictionary_ins_word(l, "atas");
b[1] = dictionary_ins_word(l, "cara");
b[2] = dictionary_ins_word(l, "ata");
b[3] = dictionary_ins_word(l, "atax");
vec = dictionary_select(l, "ata");
for(int i=0; i<vec.size(); i++) {
cout << vec[i] << " ";
}
getchar();
return 0;
}
The problem is your function dictionary_select declares the result vector and never returns it. Below is how you would change this:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > tempVector; // add this to store the result from the recursion
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(W <= D->data)
tempVector = dictionary_select(D->left, W); // get the recursion result
else
tempVector = dictionary_select(D->right, W); // get the recursion result
result.insert(result.end(), tempVector.begin(), tempVector.end()); // append all the results
return result; // return the result
}
UPDATE
In order for the function to return the correct data, you have to also ensure that you look at both left and right sides of the tree to get the appropriate results. The function below has the update:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > tempVectorLeft; // add this to store the result from the left recursion
vector < string > tempVectorRight; // add this to store the result from the right recursion
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(found == 0 || W <= D->data)
tempVectorLeft = dictionary_select(D->left, W); // store results
if(found == 0 || W > D->data)
tempVectorRight = dictionary_select(D->right, W); // store results
result.insert(result.end(), tempVectorLeft.begin(), tempVectorLeft.end()); // append all the left results
result.insert(result.end(), tempVectorRight.begin(), tempVectorRight.end()); // append all the right results
return result;
}
I propose you the following variant:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > zeroVec;
if (D == NULL)
return zeroVec;
string temp = D->data;
size_t found = temp.find(W);
if (found == 0)
result.push_back(D->data);
if (found || W <= D->data)
for(auto x: dictionary_select(D->left, W))
result.push_back(x);
if (found || W > D->data)
for (auto x : dictionary_select(D->right, W))
result.push_back(x);
return result;
}
The problem in the if / else approach used in you initial algortihm to choose between recureion on left or right node, is that you could have a note like this:
atar
/ \
ata atax
So if the data in the head of the node matches, you need to check both left and right to be sure that you're not missing something.

Can't get boolean to return false C++

I am making a program for my C++ course to validate the date using different functions but mostly boolean. My problem is that it won't give false when it is. I have tried it using the else command instead of leaving the return false; without the else but it didn't seem to change anything. Here is the code though:
int main()
{
char Data[80];
int Month,Day,Year;
int *pMonth,*pDay,*pYear;
pMonth = &Month;
pDay = &Day ;
pYear = &Year ;
cout << "\n\t\tGive me date : ";
cin >> Data;
trial();
PauseScreen(28,20,3);
return 0;
}
void SetCursorPosition(int X, int Y)
{
COORD XY = { Y,X };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),XY);
}
void SetTextColor(int Color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), Color);
}
void ClearScreen()
{
system("cls");
}
void PauseScreen(int x, int y, int color)
{
SetCursorPosition(x,y);
SetTextColor(color);
system("pause");
}
int InputValues(char *A, int *pM, int *pD, int *pY)
{
char Buffer[10];
Buffer[0] = A[0];
Buffer[1] = A[1];
Buffer[2] = '\0';
*pM = atoi(Buffer);
Buffer[0] = A[3];
Buffer[1] = A[4];
Buffer[2] = '\0';
*pD = atoi(Buffer);
Buffer[0] = A[6];
Buffer[1] = A[7];
Buffer[2] = A[8];
Buffer[3] = A[9];
Buffer[4] = '\0';
*pY = atoi(Buffer);
return strlen(A);
}
bool ValidateMonth(int A)
{
if ( A > 0 && A < 13 )
{
return true;
}
return false;
}
bool ValidateDay(int day,int month)
{
if ( month == 1 || month == 3 || month == 5 || month == 7 || month == 9|| month == 10|| month == 12 && (day > 0 && day < 32) )
{
return true;
}
return false;
}
bool ValidateDayTwo(int day,int month)
{
if ( month == 4 || month == 6 || month == 8 || month == 11 && (day > 0 && day < 31) )
{
return true;
}
return false;
}
void trial()
{
if(ValidateDay && ValidateDayTwo && ValidateMonth)
{
SetCursorPosition(10,10);
cout << "Date is Valid";
}
else
{
SetCursorPosition(10,10);
cout << "You done messed up BALAKI";
}
}
You're not actually calling your functions in your if statement. ValidDay, ValidDayTwo, ValidMonth
if(ValidateDay && ValidateDayTwo && ValidateMonth)
Instead you'll need to invoke the function by passing in arguments
if(ValidateDay(somearg1) && ValidateDayTwo(somearg2) && ValidateMonth(somearg2))
bool ValidateMonth(int A)
{
if ( A > 0 && A < 13 )
{
return true;
}
return false;
}
There is no need to say "If the condition is true, return true; otherwise, return false". You can simply return the result of evaluating the condition:
bool ValidateMonth(int A)
{
return A > 0 && A < 13;
}
You didn't call the functions correctly (well, you actually didn't call them at all) - there are no arguments:
if(ValidateDay(?) && ValidateDayTwo(?) && ValidateMonth(?))
For example, your ValidateDayTwo function takes two parameters.
The fact that the functions' return types are bool doesn't change anything, this doesn't do what you think it does. The name of the function is a pointer to the function itself, and you didn't get false as expected, because that pointer is not NULL.