How do I make this else if statement into a recursive statement? - if-statement

I am trying to make this code recursive. It is supposed to print our "R" if int x is odd and "L" if int x is even.
public String findRL(int x){
s="";
while (x > 1){
if (x%2 ==0){
s = "L" + s;
}
else{
s = "R" + s;
x = x/2;
}
}
}

I am trying to make this code recursive
First step should be trying to make the code work. It's declared to return String but it never returns s. Also, it readily goes into an infinite loop once x becomes even. So let's replace it with this similar function:
public String findRL(int x) {
String s = "";
while (x > 1) {
if (x % 2 == 0) {
s += "L";
} else {
s += "R";
}
x /= 2;
}
return s;
}
This might not be equivalent to what you were trying to do, but should be good enough to see how we might convert your actual code to a recursive function:
public String findRL(int x) {
String s = "";
if (x > 1) {
if (x % 2 == 0) {
s = "L";
} else {
s = "R";
}
s += findRL(x / 2);
}
return s;
}
We don't change the if ... else statement into recursion but rather the while loop as recursion typically uses an implicit loop in place of an explicit loop in interation.

Related

Is there a way to store INT and strings in the same array?

I'm not sure how parsing works, nor have I been able to do it in C++.
I've created an algorithm that converts decimals to hexadecimals. The algorithm right now still outputs values bigger than 9, like 10 instead of A. The following function was supposed to deal with the issue but when I run it through, I can't store the normal 1-9 values with the As and Bs in the same array, which means I can't output them. I've been stuck on this for 2 days.
string hexValues(int remainder)
{
string A = "A";
string B = "B";
string C = "C";
string D = "D";
string E = "E";
string F = "F";
if (remainder == 10)
{
return A;
}
else if (remainder == 11)
{
return B;
}
else if (remainder == 12)
{
return C;
}
else if (remainder == 13)
{
return D;
}
else if (remainder == 14)
{
return E;
}
else if (remainder == 15)
{
return F;
}
}
hexMod = userDecNumber4Hex % 16;
if (hexMod > 9)
{
hexadecimalAnswer[y] = hexValues(hexMod);
}
else
{
hexadecimalAnswer[y] = hexMod;
}
while (userDecNumber4Hex != 0)
{
if (userDecNumber4Hex % 16 != 0)
{
hexMod = userDecNumber4Hex % 16;
if (hexMod > 9)
{
hexadecimalAnswer[y] = hexValues(hexMod);
}
else
{
hexadecimalAnswer[y] = hexMod;
}
userDecNumber4Hex = (userDecNumber4Hex-hexMod)/ 16;
y += 1;
}
else if (userDecNumber4Hex % 16 == 0)
{
userDecNumber4Hex = userDecNumber4Hex / 16;
if (userDecNumber4Hex > 9)
{
hexadecimalAnswer[y] = userDecNumber4Hex;
}
}
}
the code is long so i wasn't really sure what to post but there are multiple arrays- but its just one of them that i need to have store the values getting from the hexValues function, while it already has int values
Since the integers in your hexadecimal number are only going to range between 0 and 9, you can store them as characters. At the same time, you can store A-F as characters as well.
Therefore, instead return characters as the face values.
char hexValues (int remainder)
{
if (remainder < 10)
return '0' + remainder;
else
return 'A' + (remainder - 10);
}
For full conversion, here's a good excuse to use Recursion:
string decToHex (int n)
{
if (n < 16)
{
string s (1, decToHex (n));
return s;
}
else
return decToHex (n / 16) + hexValues (n % 16);
}

how to fix "comparison between pointer and integer" error in C++?

I am trying to write a program that takes in 2 string inputs and assigns a numeric value to each letter in the string input. The program then multiples the numeric values assigned to the letters in the string inputs and sees if the product of the values (mod 47) of both inputs are equal. If they are equal, then the program must output "yes" if not, then it must output "NO".
I am using a brute force method, so please feel free to suggest more efficient methods and also how to implement them. I have reached a point where my IDE only gives several warnings, but no errors. However when I run the program, I get an illegal instruction, which is essentially because of a particular function, which I will show later.
I WOULD PREFER THAT THE SOLUTIONS TO MY QUESTION DON'T INCLUDE ANY EXTRA CLASS LIBRARIES AND FILES.
THANK YOU ;)
I've tried using a brute force method e.g in this long function:
This takes in values from a function of return type int which assigns the numeric value to the 6 letter input, and returns them to a variable of return type bool, which finds and compares the final product of the two strings before returning a value of type bool. I've used the brute force method of comparing each individual letter of the string to a letter and assigning a value. I am quite sure that the first function isn't right, although I don't know how to fix it.
int parse(const char * x)
{
if (x == "A")
{
return 1;
}
if (x == "B")
{
return 2;
}
if (x == "C")
{
return 3;
}
if (x == "D")
{
return 4;
}
if (x == "E")
{
return 5;
}
if (x == "F")
{
return 6;
}
if (x == "G")
{
return 7;
}
if (x == "H")
{
return 8;
}
if (x == "I")
{
return 9;
}
if (x == "J")
{
return 10;
}
if (x == "K")
{
return 11;
}
if (x == "L")
{
return 12;
}
if (x == "M")
{
return 13;
}
if (x == "N")
{
return 14;
}
if (x == "O")
{
return 15;
}
if (x == "P")
{
return 16;
}
if (x == "Q")
{
return 17;
}
if (x == "R")
{
return 18;
}
if (x == "S")
{
return 19;
}
if (x == "T")
{
return 20;
}
if (x == "U")
{
return 21;
}
if (x == "V")
{
return 22;
}
if (x == "W")
{
return 23;
}
if (x == "X")
{
return 24;
}
if (x == "Y")
{
return 25;
}
if (x == "Z")
{
return 26;
}
}
bool returnfunc(std::string & GROUP, std::string & k)
{
const char A = GROUP[0];
const char B = GROUP[1];
const char C = GROUP[2];
const char D = GROUP[3];
const char E = GROUP[4];
const char F = GROUP[5];
int xet = parse(&A);
int r = parse(&B);
int m = parse(&C);
int z = parse(&D);
int h = parse(&E);
int j = parse(&F);
double mu = (xet * r * m * z * h * j) % 47;
const char G = k[0];
const char H = k[1];
const char I = k[2];
const char J = k[3];
const char K = k[4];
const char L = k[5];
int w = parse(&G);
int x = parse(&H);
int y = parse(&I);
int a = parse(&J);
int b = parse(&K);
int c = parse(&L);
double fin = (w * x * y * a * b * c) % 47;
{
if (mu == fin)
{
return true;
}
else
{
return false;
}
}
}
/*I expected the program to run but it didn't and I don't understand
why.*/
This is wrong
if (x=="A")
because it compares two pointers for pointer equality. It does not compare what those pointers are pointing at (which is what you want to do).
Here's a simpler version of your code that keeps the same structure but does not involve any pointers (for some reason newbies love pointers, given how difficult they are I've never understood why).
int parse(char x)
{
if (x == 'A')
return 1;
if (x == 'B')
return 2;
// etc etc
}
Then
int xet = parse(A);
int r = parse(B);
// etc etc
PS, the more consise way to write your parse function would be to use a lookup table and a loop
int parse(char x)
{
const char* table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < 26; ++i)
if (x == table[i])
return i + 1;
return 0; // error return
}
int parse(const char * x) {
if (x == "A")
x is a const char* and "A" is a const char* but they will not be equal even if they point at C strings with the same characters since the comparison compares the addresses of the C strings, not the contents.
Also, if your parse function does not find a match it will leave the function without returning a value which is Undefined Behaviour.
Try this instead:
int parse(char x) {
if(x >= 'A' && x <= 'Z') return x - 'A' + 1;
else return 0;
}
And call parse with the char itself as an argument (instead of a pointer to it):
const char A = GROUP[0];
int xet = parse(A);
It's hard to answer this mostly because of this part of your question:
I have reached a point where my IDE only gives several warnings, but no errors.
There may be a warning that we don't know about that might be part of your problem. However, I'm going to take a stab anyway at a couple of things that are wrong.
So, first is this line right here:
int parse ( const char * x)
Now in and of itself, this isn't bad, except it's coupled with something like this:
if(x=="A")
{
return 1;
}
That is all sort of bad. x is a pointer. That means that the value store in x is an address. That means you are comparing the c string "A" to an address. That's not usually a good thing to do.
What you want is probably this instead:
if(*x == "A")
That's much better.
Well, not quite, actually, because you probably want single quotes here instead of double quotes:
if(*x == 'A')
By the way, you could probably simplify your parse function as follows, and it'd do the same thing:
int parse ( const char * x) {
return (*x - 'A') + 1; // parenthesis for clarity. Not really needed here.
}

Recursion given grammar

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.

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