If statement incorrectly recognising spaces in a bracket - c++

I am writing a mini programming language and I am currently working on my first proper command. My command is called 'prout("Sample text")'. When my program sees a space in between the letter t from the word prout and the opening bracket, it outputs an unexpected indent error, which is supposed to happen. What isn't supposed to happen is it recognising spaces in the text that the user wants to output and outputs an unexpected indent error. Does anybody know how to implement a way to stop the program from recognising that spaces in the text that the user wants to output is an unexpected indent error?
Here is the current output:
>>> prout("Hello")
Hello
>>> prout ("Hello")
Error: Unexpected indent //That is supposed to happen
>>> prout("Hello I am a programmer!")
Error: Unexpected indent //That is the problem
I've tried to use the attribute .npos to filter the spaces but this hasn't worked.
#include <iostream>
#include "printoutput.h"
#include "Line.h"
using namespace std;
void printoutput::print(string input) {
int i = 0;
int length = input.length();
if (input.find('(') != input.npos && (input.find(')') != input.npos) && (input.find('\"') != input.npos)) {
for (int i = 0; i <= input.length(); i++) {
char letter = input[i];
if (input.find(' ') != input.npos && (i == 5)) {
cout << "Error: Unexpected indent";
break;
}
if ((letter == 'p') && (i != 0) || (letter == 'r') && (i != 1) || (letter == 'o') && (i != 2) || (letter == 'u') && (i != 3) || (letter == 't') && (i != 4) || (letter == '(') && (i != 5) || (letter == '\"') && (i != 6 && i != input.length() - 2) || (letter == ')') && (i != length - 1)) {
char inputletter = input[i];
cout << inputletter;
}
else if ((i != 0 && (i != 1) && (i != 2) && (i != 3) && (i != 4) && (i != 5)) && (i != 6 && i != length - 2) && (i != length - 1)) {
char inputletter = input[i];
cout << inputletter;
}
}
}
if (input.find('\"') == input.npos) {
cout << "Syntax error: Missing quotation marks";
}
else if (input.find('(') == input.npos || (input.find(')')) == input.npos) {
cout << "Syntax error: Missing parenthesis";
}
cout << endl;
}
I expect the output to show the user's text that they have wanted to output with the spaces that they may have included.

Think about what this line does
if (input.find(' ') != input.npos && (i == 5)) {
If says if the input contains a space and if i equals 5 then output an error. Since i loops through all the indexes of the string this will be true of any string of length at least 5, which contains a space anywhere.
I'm thinking that what you really meant is this
if (input[5] == ' ')
but I'm not really sure.

Related

Why is iteration through a char vector is faster than the iteration through a string in C++

I am practicing a coding challenge where I have to reverse the vowels in a string.
My first approach failed because of exeeding Time limit. Here is my first approach using string iteration to reverse the vowels in a string.
string reverseVowels(string s) {
string str = "";
//storing the vowels from the string into another string
for (auto x : s)
if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u' || x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U')
str = str + x;
//swapping the vowels
int count = 0;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u' || s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U')
{
s[i] = str[count];
count++;
}
}
return s;
}
My second approach using the char vector iteration had passed all the tests. Here is my second approach
class Solution {
public:
string reverseVowels(string s) {
vector<char> v;
//storing the vowels from the string into vector
for (auto x : s)
if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u' || x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U')
v.push_back(x);
//swapping the vowels
int count = 0;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u' || s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U')
{
s[i] = v[count];
count++;
}
}
return s;
}
};
Could you explain why my first method failed the tests but second method passed the tests
Replace str = str + x; with str.push_back(x); or str += x;, and you'll likely see the same performance as with vector.
str = str + x; makes a copy of str, appends the character to that copy, then makes another copy when assigning back to str. As a result, your algorithm is quadratic, for no good reason.
It's because you're doing str = str + x, that creates an unnecessary copy of str, but std::vector::push_back or std::string::push_back appends a character to the vector or string, which is much faster than creating a copy of str.
str = str + x
this creates an additional copy of str while copying.
std::vector::push_back
this straight appends to the vector string

Counting vowels c++

While user inputs 10 alphabets, program should tell how many of them are vowels. I have written this code:
while (count<10)
{
cin >> n;
count++;
if (n == 'A' || n == 'a' && n == 'E' || n == 'e' && n == 'I' || n == 'i' && n == 'O' || n == 'o' && n == 'U' || n == 'u')
{
total++;
}
}
cout << total << endl;
This generates output of 0 even if there are vowels entered by user. something wrong?
Let's start by cutting down the condition down a bit, to only look at a and e
if (n == 'A' || n == 'a' && n == 'E' || n == 'e')
and then only considering the lowercase letters for simplicity (but retains the problem)
if (n == 'a' && n == 'e')
if you read this out loud it says "if n is 'a' AND n is 'e'". The "AND" (from the && operator) means that both conditions must be true. You've created an impossible condition here, if n is 'a', then it is not 'e', so you get if (true && false) - which is false. If n is 'e', then it is not 'a', so you get if (false && true).
Simply replace all of your && (and) operators with || (or) operators to have the condition be true if at least one of your equality comparisons is true.
if (n == 'A' || n == 'a' || n == 'E' || n == 'e'
|| n == 'I' || n == 'i' || n == 'O' || n == 'o'
|| n == 'U' || n == 'u')
There are some ways to simplify the condition.
One is to add a #include <cctype> and use std::tolower to convert n to lowercase, then you only need to compare against lowercase characters.
n = std::tolower(n);
if (n == 'a' || n == 'e' || n == 'i' || n == 'o' || n == 'u')
Another, less repetitive approach is to create a std::string with all the vowels in it, and then see if it contains n, #include <string> up top.
std::string vowels = "aeiouAEIOU";
while (/*...*/) {
// ...
if (vowels.find(n) != std::string::npos) {
++total;
}
}
As n314159 pointed out, if you are using C++17 or later, you can use a std::string_view instead, which is cheaper. #include <string_view>
static constexpr std::string_view vowels = "aeiouAEIOU";
while (/*...*/) {
// ...
if (vowels.find(n) != std::string_view::npos) {
++total;
}
}
I recommend using a switch statement with fall-through, which is more readable but also potentially more efficient (may be implemented with jump table).
int count = 10;
while (count--) {
switch(std::tolower(n)) {
case 'a': case 'e':
case 'i': case 'o':
case 'u': total ++; break;
default:;
}
}

How can I switch what points on an array equal in c++?

These change the array that I print to the screen. direc is an input before this. However, when array[1][2] == '#', it still moves '#' to array[1][0].
if (array[1][1] == '#' && direc == 'A' || direc == 'a' ) {
array[1][1] = '_';
array[1][0] = '#';
}
else {
if (array[1][1] == '#' && direc == 'D' || direc == 'd' ) {
array[1][1] = '_';
array[1][2] = '#';
}
else {
if (array[1][2] == '#' && direc == 'A' || direc == 'a' ) {
array[1][1] = '#';
array[1][2] = '_';
}
}
}
You can either add parentheses, as already noted in the comments, like this
if (array[1][1] == '#' && (direc == 'A' || direc == 'a' )) {
Alternatively you could use std::tolower in which case you no longer nee
if (array[1][1] == '#' && std::tolower(direc) == 'a') {
You could still add extra parentheses if you are not comfortable that operator && is lower precedence than operator ==
(the full table of operator precedences can be seen here)

Infix to Postfix - Deleting Parenthesis

Having trouble getting the parenthesis to pop from the string.
I enter an infix expression such as (A+B)*C and would like to get AB+C*.
Instead, I get (AB)+C*. Any help would be greatly appreciated.
string Postfx::convertToPostfix(Postfx C,string in)
{
stack<char> S;
string postfx = "";
for (int i = 0; i<in.length();i++)
{
if (in[i] == ' ' || in[i] == ',') continue;
else if ((in[i]) == '+' || in[i] == '-' || in[i] == '/' || in[i] == '*')
{
while (!S.empty() && S.top() != '(' && C.precedence(S.top(), in[i]))
{
postfx += S.top();
S.pop();
}
S.push(in[i]);
}
else if ((in[i]) != '+' || in[i] != '-' || in[i] != '/' || in[i] != '*')
{
postfx += in[i];
}
else if (in[i] == '(')
{
S.push(in[i]);
}
else if (in[i] == ')')
{
while (!S.empty() && S.top() != '(')
{
postfx += S.top();
S.pop();
}
S.pop();
}
}
while (!S.empty()) {
postfx += S.top();
S.pop();
}
return postfx;
}
I think that your
else if ((in[i]) != '+' || in[i] != '-' || in[i] != '/' || in[i] != '*')
line catches brackets as well, so
else if (in[i] == '(')
and below never gets executed.
I think you should move
else if ((in[i]) != '+' || in[i] != '-' || in[i] != '/' || in[i] != '*')
to be the last option in the chained if.
Moreover, this if catches absolutely any symbol (because any symbol is either not equal to '+', or not equal to '-'). You need to replace || by &&; but if you will anyway have this if the last in chained if, you need no condition there at all, something like:
if ((in[i] == ' ')|| ...
else if ((in[i] == '+')|| ...
else if (in[i] == '(') ...
else if (in[i] == ')') ...
else postfx += in[i]; // no condition here
P.S. Also if you wrap the initial expression in brackets:
in = "(" + in + ")"
before the loop, you will not need the final while (!S.empty()) loop.
Don't append the parentheses to the output. They're only in the stack to guide your actions. I don't know where you got this code but you need to take a good look at the Dijkstra Shunting-yard algorithm. Your version doesn't match it at several points, and some of it doesn't even make sense:
if (in[i] != '+' || in[i] != '-' || in[i] != '/' || in[i] != '*')

Arduino check non alphanumeric

How to check if a string contains non alphanumeric values? I want to create a condition to return if match one non alphanumeric character.
void checkTag(char tag[]){
if(strlen(tag) == 0) return;
if(strlen(tag) == 1) return;
if(strlen(tag) == 2) return;
if(strlen(tag) == 3) return;
In Serial Monitor is showed:
À¨À¨Àª®)
for (int i=0;i<strlen(tag); i++){
if ( (tag[i] >= 'a' && tag[i] <= 'z') || (tag[i] >= 'A' && tag[i] <= 'Z') || (tag[i] >= '0' && tag[i] <= '9'){
//this char is OK
}else{
return;
}
}
//if you are here tag is valid
edit: changed the comments to be sure you don't put code in the if