This is the beginning question on Else/If function - if-statement

var respond = ["hello", "nothing"];
function speak() {
if ("hey") {
return "hello";
}
else if ("whats up") {
return "nothing";
}
}
var check = speak("whats up");
It worked when I typed speak("hey") it returned "hello" but speak ("whats up") not did not return "nothing". Where did I go wrong?

You need to specify a parameter coming into the function "speak", and then you need to compare that to the text "hey". The statement if("hey") will always return true, as will any non-empty string in Javascript.
Try
function speak(word){
if (word == "hey"){
return "hello";
}
else if (word == "whats up") {
return "nothing";
}
}

Related

Don't understand why I am getting this error on the else.

public static boolean isPalindrome(String word, int firstIndex, int lastIndex)
{
if(firstIndex>lastIndex)
return true;
else if(word.charAt(firstIndex)==(word.charAt(lastIndex)));
{
return true && isPalindrome(word, firstIndex+1, lastIndex-1);
}
**else**
return false;
}
Getting error on else: "Syntax error on token "else", delete this token
"
I don't really get what is wrong with this code, specifically that else statement.
Remove the semi colon at the end of else if
else if(word.charAt(firstIndex)==(word.charAt(lastIndex)));
Try this:
public static boolean isPalindrome(String word, int firstIndex, int lastIndex)
{
boolean palindrome = false;
if(firstIndex>lastIndex) {
palindrome = true;
}
else if(word.charAt(firstIndex)==(word.charAt(lastIndex)))
{
if (isPalindrome(word, firstIndex+1, lastIndex-1)) {
palindrome = true;
}
}
return palindrome;
}

How to Use Recursion to Return a String?

I am trying to solve this recursively. I am having a hard time returning the string:
string reverse(string);
int main() {
cout << reverse("1234") << endl;
} // end main
string reverse(string integer) {
if (integer == "")
return "";
else
return reverse(integer.substr(1, integer.length()));
} // end reverse
I know the function has small issue (I hope). Can you please help me fix it? Thanks,
Try this one
string reverse(string integer) {
if (integer.length() == 0)
return "";
else
return reverse(integer.substr(1, integer.length())) + integer.substr(0,1);
} // end reverse
See live demo.
Your problem is that you keep recursing on shorter strings until you reach the empty string.
Since you never do anything with the result of the recursive call, you also end up with the empty string.
If you want the first character of the string to wind up in the result, you need to use it somewhere, you can't just throw it away.
You should put the first character at the back of the result of reversing the rest of the string, like this:
string reverse(string s)
{
if (s == "")
return "";
else
return reverse(s.substr(1, s.length())) + s[0];
}
or, shorter
string reverse(string s)
{
return s.empty() ? "" : reverse(s.substr(1)) + s[0];
}

Use function in nested if statement to trigger action

Below shows the main program with an if statement. If the if statement is true, then it moves onto triggering the function.
If what in the function is true, then x = true, which triggers the final action. The, x from the aux function still comes out as undeclared.
What am I doing wrong?
void aux(bool x) {
std::string text;
std::getline(std::cin, text);
if (text.find("be ") != std::string::npos ||
text.find("do ") != std::string::npos ||
text.find("can ") != std::string::npos ||
text.find("but ") != std::string::npos) {
x = true;
}
}
int main() {
std::string text;
std::getline(std::cin, text);
if (text.find("7 ") != std::string::npos) {
aux();
{
if (x);
{
std::cout<<"A function to equal a group of words"<<std::endl;
}
}
}
getchar();
return 0;
}
You may want to change your aux function to return a boolean instead of taking it as a parameter:
bool aux() {
if (/* your checks here */) {
return true;
} else {
return false;
}
}
The bool to the left of the function name, in place of void indicates that the result of calling your function will be a boolean.
Then in main you would use aux like this:
if (aux()) {
std::cout<<"A function to equal a group of words" <<std::endl;
}
Seems like you don't know about local and global variable.
You can use pass by reference to solve the problem as follows:
void aux(bool &x)
{
std::string text;
std::getline(std::cin, text);
if(text.find("be ") != std::string::npos || text.find("do ") != std::string::npos ||
text.find("can ") != std::string::npos || text.find("but ") != std::string::npos)
{
x = true;
}
else{
x = false;
}
}
int main()
{
bool x = false;
if (text.find("7 ") != std::string::npos)
{
aux(x);
//{ un-necessary brackets.
if (x);
{
std::cout<<"A function to equal a group of words" <<std::endl;
}un-necessary brackets.
//}
}
getchar();
return 0;
}
Problem you have:
You have following mistakes in your code.
1.You have defined a function like this:
void aux(bool x){
//your code here
}
But you haven't called it by passing any variable as parameter/argument. Do as following:
aux(var1);//var1 is boolean variable
2 . The change in x doesn't appear there because the x will be treated as a new variable inside the aux(var1) function. So if you use pass by reference, then the changes will be persistence to the variable (here x).
You seem to be operating on the assumption that 'x' should be available to your main() function after calling aux(). C/C++ does not work that way - there is no 'x' in the scope of your main function because you never declared anything named x.
Furthermore, it will not have the value you want unless you return x from your aux() function and assign it to something in your main function.
You should familiarize yourself with the topic of 'scope' in C/C++ as that will prevent further misunderstanding, but the basic problem you need to solve with your sample is:
You arent passing a bool to your aux() function, so it wont work (it is a parameter for aux()
You arent returning the value of x from your aux function
You arent declaring a boolean in your main function to take the value returned from aux() function
It is completely vague what is your expectations about bool x? If you want to change the x and x is outter variable then you need either pass it by the reference or return the value. Return of the value is much more logical.
bool
aux()
{
std::string text;
std::getline(std::cin, text);
if(text.find("be ") != std::string::npos ||
text.find("do ") != std::string::npos ||
text.find("can ") != std::string::npos ||
text.find("but ") != std::string::npos)
return true;
return false
}
Now it is also logical to use the result of aux() without dangling x with random value:
int main()
{
std::string text;
std::getline(std::cin, text);
if (text.find("7 ") != std::string::npos)
{
if (aux()) // We dont need the variable here since we use return value of the aux
std::cout<< "A function to equal a group of words" << std::endl;
else
std::cerr << "Bad string detected" << std::endl;
}
getchar();
return 0;
}
Now it starts to work

"\b" is added to the string as a character

In the below code the "\b" removes a char from the string, but it increases its size as if the char could be inside it but not visible.
while (true) {
c = _getch();
if (c=='\r') {break;}
else if (c=='\b') { cout<<"\b"<<" "<<"\b"; s+="\b \b"; }
else {cout<<"*"; s=s+c;}
}
For instance the the size of this string (abc"\b"d), "c is removed and replaced by d", is still 5.
I would like to know how to efficiently handle the backspace in this circumstance.
If you are reading character by character into a string, you could do something like this:
std::string mystr;
while (true) {
c = _getch();
if (c=='\r') {break;}
if(c == '\b')
{
// This will remove last character from your string
if(mystr.size () > 0)
{
cout<<"\b"<<" "<<"\b";
mystr.resize (mystr.size () - 1);
// or mystr.pop_back() in C++11
}
}
else
{
cout<<"*";
mystr += c;
}
}
You need to "physically" remove the last character from the string when you get a backspace:
while (true) {
c = _getch();
if (c=='\r') {
break;
}
if (c=='\b') {
cout<<"\b"<<" "<<"\b";
if (s.length() > 0) {
s = s.substring(0, s.length()-1);
}
}
else {cout<<"*"; s=s+c;}
}
As an optimization, we can trim s instead of reassigning, as suggested by Jason:
s.resize(s.size() -1);
(While we're at it, we could save s.length() (or s.size()) into a local variable to avoid the extra call - assuming the compiler, knowing about std::string, doesn't do it already).
for(char c=_getch(); c!='\r'; c=_getch())
if(c=='\b')
mystr.pop_back();
else
mystr.push_back(c);

Lex only detects symbols when there is whitespace between them

I want Lex, when given an input of "foo+1", to first return the identifier "foo", then the character '+', and then the integer 1. This works if I lex "foo + 1", but for some reason with the grammar I have, it doesn't work if I omit the spaces, and it skips over the '+', just returning "foo" and then 1. I can't figure out why. Is there anything here that seems problematic?
%{
#include "expression.h"
#include "picoScanner.h"
static int block_comment_num = 0;
static char to_char(char *str);
int yylineno = 0;
%}
%option nodefault yyclass="FlexScanner" noyywrap c++
%x LINE_COMMENT
%x BLOCK_COMMENT
%%
Any { return pico::BisonParser::token::ANY; }
Int { return pico::BisonParser::token::INT; }
Float { return pico::BisonParser::token::FLOAT; }
Char { return pico::BisonParser::token::CHAR; }
List { return pico::BisonParser::token::LIST; }
Array { return pico::BisonParser::token::ARRAY; }
Table { return pico::BisonParser::token::TABLE; }
alg { return pico::BisonParser::token::ALG; }
if { return pico::BisonParser::token::IF; }
then { return pico::BisonParser::token::THEN; }
else { return pico::BisonParser::token::ELSE; }
is { return pico::BisonParser::token::IS; }
or { return pico::BisonParser::token::OR; }
and { return pico::BisonParser::token::AND; }
not { return pico::BisonParser::token::NOT; }
when { return pico::BisonParser::token::WHEN; }
[A-Z][a-zA-Z0-9_]* { yylval->strval = new std::string(yytext);
return pico::BisonParser::token::TYPENAME; }
[a-z_][a-zA-Z0-9_]* { printf("saw '%s'\n", yytext); yylval->strval = new std::string(yytext);
return pico::BisonParser::token::ID; }
"==" { return pico::BisonParser::token::EQ; }
"<=" { return pico::BisonParser::token::LEQ; }
">=" { return pico::BisonParser::token::GEQ; }
"!=" { return pico::BisonParser::token::NEQ; }
"->" { return pico::BisonParser::token::RETURN; }
[\+\-\*/%] { return yytext[0]; }
[-+]?[0-9]+ { yylval->ival = atoi(yytext);
return pico::BisonParser::token::INT_LITERAL; }
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { yylval->fval = atof(yytext);
return pico::BisonParser::token::FLOAT_LITERAL; }
\"(\\.|[^\\"])*\" { yylval->strval = new std::string(strndup(yytext+1, strlen(yytext) - 2));
return pico::BisonParser::token::STRING_LITERAL; }
\'(\\.|[^\\'])*\' { yylval->cval = to_char(yytext+1);
return pico::BisonParser::token::CHAR_LITERAL; }
[ \t\r]+ { /* ignore */ }
\n { yylineno++; }
. { printf("~~~~~~~~~~munched %s\n", yytext); return yytext[0]; }
%%
static char to_char(char *str) {
if (strlen(str) <= 1) {
fprintf(stderr, "Error: empty character constant (line %d)\n", yylineno);
exit(1);
} else if (str[0] != '\\') {
return str[0];
} else {
if (strlen(str) == 1) {
fprintf(stderr, "Error: somehow we got a single slash character\n");
exit(1);
}
switch (str[1]) {
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'a': return '\a';
case 'b': return '\b';
case 'f': return '\f';
case 'v': return '\v';
case '\'': return '\'';
case '"': return '"';
case '\\': return '\\';
case '?': return '\?';
case 'x':
fprintf(stderr, "Error: unicode not yet supported (line %d)\n", yylineno);
exit(1);
default:
fprintf(stderr, "Error: unrecognized escape sequence '\\%c' (line %d)\n",
str[1], yylineno);
exit(1);
}
}
}
I am not familair with lex, but I'm pretty sure the following causes the error:
[-+]?[0-9]+ { yylval->ival = atoi(yytext);
return pico::BisonParser::token::INT_LITERAL; }
foo is parsed as an identifier, but then "+0" is parsed as an int literal (due to the atoi conversion, the sign is discarded).
It is probably a good idea to only consider unsigned numeric literals at a lexer level, and handle signs at the level of the parser (treating the + and - tokens differently depending on their context).
Not only does this resolve the ambiguity, but it also enables you to "correctly" (in the sense that these are legal in C, C++, Java etc.) parse integer literals such as - 5 instead of -5.
Moreover: are the escaping backslashs in the arithmetic operator rule really necessary? Afaik, the only characters with special meaning inside a character class are -, ^, and ] (but I might be wrong).
Looks to me like it's matching foo+1 as foo and +1 (an INT_LITERAL). See related thread: Is it possible to set priorities for rules to avoid the "longest-earliest" matching pattern?
You could add an explicit rule to match + as a token, otherwise it sounds like Lex is going to take the longest match it can (+1 is longer than +).