Recursion given grammar - c++

I am to implement a recursive program given the grammar. I understand the concept of recursion, but implementing it can be overwhelming.
I'm having trouble with strings with parenthesis.
Inputing "(b-c)" should result in it being a valid expression, but the output says invalid.
I've been tracing the program where it deals with the parenthesis, but i can seem to figure out where I am wrong.
Also, the program may not be perfect, but i'd like to address this issue. Thanks for any help.
Main prompts user for input. I only provided what I believe is necessary.
Main
if(i.findExpression(str)){
cout << str << " is legal infix expression.\n";
}
else{
cout << str << " is not a legal infix expression.\n";
}
The grammar to follow is:
expression = term | term + term | term - term
term = factor | factor * factor | factor / factor
factor = letter | (expression)
letter = a|b|...|z
Find Expression
bool infix::findExpression(string strExp){
int i;
int n = (int)strExp.length();
bool found = true;
for (i = 0; i < n; i++){
if((strExp.at(i) == '(') and (n != i)){ //
while((strExp.at(i)!=')') and (n != i)){ //
i++;
}
found = false;
}
else if((strExp.at(i) == '+' or strExp.at(i) == '-') and
(n != i))
{
found = true;
break;
}
else
found = false;
}// added
if(found){
return(findTerm(strExp.substr(0,i))&&findTerm(strExp.substr(i+1, n-(i+1))));
}
else{
return findTerm(strExp.substr(0,n));
}
}
Find Term
bool infix::findTerm(string strExp){
int n = (int)strExp.length();
bool found = true;
int i;
for(i = 0; i < n; i++){
if((strExp.at(i) == '(')and (n != i)){
while((strExp.at(i)!=')')and (n != i)){
i++;
}
found = false;
}
else if((strExp.at(i)=='*' or strExp.at(i)=='/')and (n != i)){
found = true;
break;
}
else
found = false;
}
if(found){
return(findFactor(strExp.substr(0,i)) && findFactor(strExp.substr(i+1, n-(i+1))));
}
else{
return findFactor(strExp.substr(0,n));
}
}
Find Factor
bool infix::findFactor(string strExp)
int i;
char ch;
int n = (int)strExp.length();
bool found = true;
ch = strExp.at(0);
if((n==1)&&islower(ch)){
return true;
}
else if(ch == '('){
for(i = n; i > 0; i--){
if((n-1 != i) and (strExp.at(i-1) == ')')){
found = true;
break;
}
else{
found = false;
}
}
if(found){
return findExpression(strExp.substr(1, i-1));
}
else{return false;}
}
else{return false;}
}

Recursive descent parsers typically have methods exactly reflecting the rules. The rules consume the corresponding input. Typically this is done by operating on some kind of stateful token stream.
If you want to use simple strings, one way to handle how much is consumed by a recursive call is to let the recursion return the new position (although I'd really recommend operating on a token stream instead, as you normally would use the return value to return the corresponding subtree).
In this case, for your example, the method for handling expressions would look similar to this:
// expression = term | term + term | term - term
// Returns the position in strExp after parsing, or -1 for errors.
int infix::parseExpression(string strExp) {
int pos = parseTerm(strExp);
if (pos == -1) { // Error signal
return -1;
}
if (pos >= strExp.length()) {
return pos; // done
}
if (strExp.at(pos) != '-' && strExp.at(pos) != '+') {
return -1; // error
}
return parseTerm(strExpr.substr(pos + 1));
}
// term = factor | factor * factor | factor / factor
int infix::parseTerm(string strExp) {
...
Comparing the result to the string length should provide whether the expression is valid. You can encapsulate this check in another method for convenience.

Related

How to find specific numbers of repeating consecutive digits?

I am having trouble making this function evaluate if a a six digit integer has either a set of two repeated consecutive digits or four. All other sets of repeated consecutive digits should evaluate to false.
Examples of good input: 122345, 133335
Bad input: 123335, 666478
Here is my code:
bool hasDuplicate(int number){
int rem, num, dig;
do {
rem = number % 10;
num = number / 10;
dig = num % 10;
if (rem == dig) {
return true;
}
else {
return hasDuplicate(num);
}
} while (number > 0);
return false;
}
Consider converting the number to string and then just scanning the characters in the string from left to right.
bool hasDuplicate(int number) {
std::string s = std::to_string(number);
bool good = false;
bool bad = false;
int consecutive = 1;
// deliberately starting at s[1]
for (size_t i = 1; i < s.size(); i++) {
bool dupe = (s[i - 1] == s[i]);
if (dupe) {
consecutive++;
}
// last iteration or this char is not a duplicate of the previous one
if ((i + 1 == s.size()) || (!dupe)) {
bool good_sequence = (consecutive == 2) || (consecutive == 4);
good = good || good_sequence;
bool bad_sequence = (consecutive == 3) || (consecutive > 4);
bad = bad || bad_sequence;
}
if (!dupe) {
consecutive = 1;
}
}
return good && !bad;
}

My sudoku board generating function is getting stuck in an infinite loop

The user is supposed to input a number between 0 and 81, and it should generate a sudoku board with that many (valid) numbers filled in (Even if the sudoku board may not be solvable).
It works fine for small numbers of n, but if it has to backtrack, it gets stuck oscillating between ~42 and ~56.
In this program, it's important to note that n is the number that the user has specified, nOn is the number the function is on.
the array named positions[] contains the numbers 0-80 in a randomized order (compliments of the shuffle function) and is designed to represent the randomized order in which to fill the grid.
bool Sudoku::generateSudoku(int n, int nOn)
{
int xpos = positions[nOn] / 9;
int ypos = positions[nOn] % 9;
int queryCount = 0;
char query = rand()%9 + '1';
bool success = false;
if (nOn >= n)
{
return true;
}
else
{
while (queryCount < 9 && !success)
{
if (isValid(xpos, ypos, query, 0))
{
sudoku[xpos][ypos][0] = query;
success = generateSudoku(n, nOn + 1);
}
if (query == '9')
{
query = '1';
}
else
{
query++;
}
queryCount++;
}
if (!success)
{
sudoku[xpos][ypos][0] = '*';
return false;
}
else
{
return true;
}
}
}
I've gone over it several times with 2 of my friends and I can't find why it's getting choked up. Any help would be appreciated!
edit: I've added a similar function that I know works for comparison. This one starts in the upper left hand corner and recursively backtracks when it runs into invalid solutions. it's able to solve any (solvable) puzzle in a matter of seconds
int Sudoku::solveSudoku(int x, int y)
{
bool success = false;
char query = '1';
int counter = 0;
if (x == 8 && y == 9)
{
return 1;
}
else if (y == 9)
{
y = 0;
x++;
}
if (sudoku[x][y][0] != '*')
{
sudoku[x][y][1] = sudoku[x][y][0];
success = solveSudoku(x, y + 1);
}
else
{
while (query <= '9' && !success)
{
if (isValid(x, y, query, 1))
{
sudoku[x][y][1] = query;
success = solveSudoku(x, y + 1);
}
else
{
query++;
}
}
}
if (success)
{
return 1;
}
else
{
sudoku[x][y][1] = sudoku[x][y][0];
return false;
}
}

prefix notation c++, segmentation fault (stack and queue)

I am trying to figure out why I get segmentation fault, and my guess is that it is in my recursive function, which simplifies a prefix notation operation.
For example:
"m + 4 4" Returns: "+ m 8"
During testing I get a segmentation fault signal:
Exited with signal 11 (SIGSEGV)
I believe though that the problem lies in my recusive function "Operate"
string Operate(stack<string> &S, queue<string> &Q)
{
S.push(Q.front());
Q.pop();
std::string::size_type sz;
string result = "";
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (Q.empty() == false)
{
S.push(Q.front());
Q.pop();
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (S.size() < 3)
return "wrong input";
string arg1 = S.top();
S.pop();
string arg2 = S.top();
S.pop();
string oper = S.top();
S.pop();
if (StringIsDigit(arg1) && StringIsDigit(arg2))
{
int a = stoi(arg1, &sz);
int b = stoi(arg2, &sz);
char o = oper.at(0);
int c = 0;
if (o == '+')
c = b + a;
else if (o == '-')
c = b - a;
else if (o == '*')
c = b * a;
else
return "e";
result = to_string(c);
}
else
result = oper + " " + arg2 + " " + arg1;
}
else
{
result = S.top();
S.pop();
}
return result;
}
or in the function StringIsDigit:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
Link to the whole program code:
https://pastebin.com/04pfE55N
The answer was quite simple, my error: SEGFAULT was as many pointed out for me error in reading from memory, segmentation fault, wiki.
When did the segfault occur?
It was when my function StringIsDigit() tried to figure out if negative values over 2 characters was an integer. In the "if statement, when checking if the string was indeed an integer, say -100", I continued to read the string until I reached the end of the arg string, but with arg.at(i + 1). Leading to the code trying to access memory outside the string array.Thanks Struthersneil for finding this flaw!
Please look at my old StringIsDigit() to find out the of by one value error I made:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
The solution
The solution I want to make sure that the string was an integer since my algorithm supports expressions, such as x+3. This means that I need to iterate through the string is call isdigit() on every character in the string array. Though '-' is not an integer, '-' is needed obviously to express a negative integer, so I made a flawed check as you can see in my old StringIsDigit(). Instead of using that conditional if statement, I checked if the first character '-' and the second is not a whitespace ' ', and then I just let the isdigit() function do the rest of the work.
bool StringIsDigit(string arg)
{
bool result = true;
//I only need to check if the first is a '-' char and
//the next char is not ' '.
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}

Conver BCD Strings to Decimal

I am looking for better ways to optimize this function for better performance, speed its targeted towards embedded device. i welcome any pointers, suggestion thanks
function converts string BCD to Decimal
int ConvertBCDToDecimal(const std::string& str, int splitLength)
{
int NumSubstrings = str.length() / splitLength;
std::vector<std::string> ret;
int newvalue;
for (auto i = 0; i < NumSubstrings; i++)
{
ret.push_back(str.substr(i * splitLength, splitLength));
}
// If there are leftover characters, create a shorter item at the end.
if (str.length() % splitLength != 0)
{
ret.push_back(str.substr(splitLength * NumSubstrings));
}
string temp;
for (int i=0; i<(int)ret.size(); i++)
{
temp +=ReverseBCDFormat(ret[i]);
}
return newvalue =std::stoi(temp);
}
string ReverseBCDFormat(string num)
{
if( num == "0000")
{
return "0";
}
else if( num == "0001")
{
return "1";
}
else if( num == "0010")
{
return "2";
}
else if( num == "0011")
{
return "3";
}
else if( num == "0100")
{
return "4";
}
else if( num == "0101")
{
return "5";
}
else if( num == "0110")
{
return "6";
}
else if( num == "0111")
{
return "7";
}
else if( num == "1000")
{
return "8";
}
else if( num == "1001")
{
return "9";
}
else
{
return "0";
}
}
Update
this is what i plan to get, for a BCD Value::0010000000000000 Decimal Result 2000
BCD is a method of encoding decimal numbers, two to a byte.
For instance 0x12345678 is the BCD representation of the decimal number 12345678. But, that doesn't seem to be what you're processing. So, I'm not sure you mean BCD when you say BCD.
As for the code, you could speed it up quite a bit by iterating over each substring and directly calculating the value. At a minimum, change ReverseBCDFormat to return an integer instead of a string and calculate the string on the fly:
temp = temp * 10 + ReverseBCDFormat(...)
Something like that.
What you call BCD is not actually BCD.
With that out of the way, you can do this:
int ConvertBCDToDecimal(const std::string& str, int splitLength)
{
int ret = 0;
for (unsigned i = 0, n = unsigned(str.size()); i < n; )
{
int v = 0;
for (unsigned j = 0; j < splitLength && i < n; ++j, ++i)
v = 2*v + ('1' == str[i] ? 1 : 0); // or 2*v + (str[i]-'0')
ret = 10*ret + v;
}
return ret;
}
Get rid of all the useless vector making and string copying. You don't need any of those.
Also, I think your code has a bug when processing strings with lengths that aren't a multiple of splitLength. I think your code always considers them to be zero. In fact, now that I think about it, your code won't work with any splitLength other than 4.
BTW, if you provide some sample inputs along with their expected outputs, I would be able to actually verify my code against yours (given that your definition of BCD differs from that of most people, what your code does is not exactly clear.)
as soon as you're optimizing function, here is different variant:
int ConvertBCDToDecimal(const std::string& str) {
unsigned int result = 0;
const std::string::size_type l = str.length();
for (std::string::size_type i = 0; i < l; i += 4)
result = result * 10 + ((str[i] - '0') << 3) + ((str[i + 1] - '0') << 2) + ((str[i + 2] - '0') << 1) + (str[i + 3] - '0');
return result;
}
note: you don't need splitLength argument, as you know that every digit is 4 symbols

Perfect square and perfect cube

Is there any predefined function in c++ to check whether the number is square of any number and same for the cube..
No, but it's easy to write one:
bool is_perfect_square(int n) {
if (n < 0)
return false;
int root(round(sqrt(n)));
return n == root * root;
}
bool is_perfect_cube(int n) {
int root(round(cbrt(n)));
return n == root * root * root;
}
sqrt(x), or in general, pow(x, 1./2) or pow(x, 1./3)
For example:
int n = 9;
int a = (int) sqrt((double) n);
if(a * a == n || (a+1) * (a+1) == n) // in case of an off-by-one float error
cout << "It's a square!\n";
Edit: or in general:
bool is_nth_power(int a, int n) {
if(n <= 0)
return false;
if(a < 0 && n % 2 == 0)
return false;
a = abs(a);
int b = pow(a, 1. / n);
return pow((double) b, n) == a || pow((double) (b+1), n) == a;
}
No, there are no standard c or c++ functions to check whether an integer is a perfect square or a perfect cube.
If you want it to be fast and avoid using the float/double routines mentioned in most of the answers, then code a binary search using only integers. If you can find an n with n^2 < m < (n+1)^2, then m is not a perfect square. If m is a perfect square, then you'll find an n with n^2=m. The problem is discussed here
Try this:
#include<math.h>
int isperfect(long n)
{
double xp=sqrt((double)n);
if(n==(xp*xp))
return 1;
else
return 0;
}
The most efficient answer could be this
int x=sqrt(num)
if(sqrt(num)>x){
Then its not a square root}
else{it is a perfect square}
This method works because of the fact that x is an int and it will drop down the decimal part to store only the integer part. If a number is perfect square of an integer, its square root will be an integer and hence x and sqrt(x) will be equal.
For identifying squares i tried this algorithm in java. With little syntax difference you can do it in c++ too.
The logic is, the difference between every two consecutive perfect squares goes on increasing by 2. Diff(1,4)=3 , Diff(4,9)=5 , Diff(9,16)= 7 , Diff(16,25)= 9..... goes on.
We can use this phenomenon to identify the perfect squares.
Java code is,
boolean isSquare(int num){
int initdiff = 3;
int squarenum = 1;
boolean flag = false;
boolean square = false;
while(flag != true){
if(squarenum == num){
flag = true;
square = true;
}else{
square = false;
}
if(squarenum > num){
flag = true;
}
squarenum = squarenum + initdiff;
initdiff = initdiff + 2;
}
return square;
}
To make the identification of squares faster we can use another phenomenon, the recursive sum of digits of perfect squares is always 1,4,7 or 9.
So a much faster code can be...
int recursiveSum(int num){
int sum = 0;
while(num != 0){
sum = sum + num%10;
num = num/10;
}
if(sum/10 != 0){
return recursiveSum(sum);
}
else{
return sum;
}
}
boolean isSquare(int num){
int initdiff = 3;
int squarenum = 1;
boolean flag = false;
boolean square = false;
while(flag != true){
if(squarenum == num){
flag = true;
square = true;
}else{
square = false;
}
if(squarenum > num){
flag = true;
}
squarenum = squarenum + initdiff;
initdiff = initdiff + 2;
}
return square;
}
boolean isCompleteSquare(int a){
// System.out.println(recursiveSum(a));
if(recursiveSum(a)==1 || recursiveSum(a)==4 || recursiveSum(a)==7 || recursiveSum(a)==9){
if(isSquare(a)){
return true;
}else{
return false;
}
}else{
return false;
}
}
For perfect square you can also do:
if(sqrt(n)==floor(sqrt(n)))
return true;
else
return false;
For perfect cube you can:
if(cbrt(n)==floor(cbrt(n)))
return true;
else
return false;
Hope this helps.
We could use the builtin truc function -
#include <math.h>
// For perfect square
bool is_perfect_sq(double n) {
double r = sqrt(n);
return !(r - trunc(r));
}
// For perfect cube
bool is_perfect_cube(double n) {
double r = cbrt(n);
return !(r - trunc(r));
}
bool isSquare(int n) {
return floor(sqrt(n)) == ceil(sqrt(n));
}
bool isQube(int n) {
return floor(cbrt(n)) == ceil(cbrt(n));
}