If and If statement / using { } - if-statement

I have a simple question . Why the first program don't work and return me 0 but the second where if go into another if works ? It wont go down and check the next if ?
#include <stdio.h>
int main ()
{
int m,n,tmp,i;
int nnumber=0,numbermin=9999999;
scanf("%d %d",&m,&n);
for(i=m;i<=n;i++)
{
tmp=i;
while (tmp > 0 && (tmp % 10) % 2 == 0)
{
tmp/=10;
}
if (tmp == 0){ // This don't work i as want from this if to go down
// there and check the next if
// i only got 0 at the printf("%d" , numbermin);
nnumber=i;
}
if(nnumber<numbermin)
{
numbermin=nnumber;
}
}
if(nnumber==0)
printf("NO");
else
printf("%d",numbermin);
}
And the code that runs good .
#include <stdio.h>
int main ()
{
int m,n,tmp,i;
int nnumber=0,numbermin=9999999;
scanf("%d %d",&m,&n);
for(i=m;i<=n;i++)
{
tmp=i;
while (tmp > 0 && (tmp % 10) % 2 == 0)
{
tmp/=10;
}
if (tmp == 0) {
nnumber=i;
if(nnumber<numbermin)
{
numbermin=nnumber; // But this work perfect i want to know why the first ex didn't work ?
}
}
}
if(nnumber==0)
printf("NO");
else
printf("%d",numbermin);
}
Why only the second one work good but the first don't ?

This is caused by the fact that in the first example, if tmp isn't equal to 0, then the second if statement can still be evaluated as true while the first does not.
if (tmp == 0){
nnumber=i;
}
if(nnumber<numbermin)
{
numbermin=nnumber;
}
While in the second example, if tmp is equal to 0, then the first if statement is evaluated as false and disallows anything within it from affecting the program.
if (tmp == 0){
nnumber=i;
if(nnumber<numbermin){
numbermin=nnumber;
}
}
This would explain the difference in results when running these two versions of the code.

Related

c++ how to get depth of a binary tree recursively

I wrote a code that suposed to return the depth of a binary tree from the root to the node who called the function. using recursive way but I faced a problem about how to count the number of times that the function gets called so I whould know how much convexity I passed. Someone know how can I do that?
int BSNode::getDepth(const BSNode& root) const
{
if (this != nullptr)
{
if (root.getData() > this->_data)
{
this->getDepth(*root.getRight());
}
else if (root.getData() < this->_data)
{
this->getDepth(*root.getLeft());
}
else if (root.getData() == this->_data)
{
// return the number that the function counted
}
}
else
{
return 0;
}
}
You should at least return something in every case. And when you arrive at the intended node (having the data you are looking for), then return 0. In all other cases, return what you get from recursion plus 1. If the value is not found then indeed -1 should be returned. And if this -1 is coming back from recursion, it should be returned like that also to the caller (without adding 1).
Here is the code adapted:
int BSNode::getDepth(const BSNode& root) const
{
int temp;
if (this != nullptr)
{
if (root.getData() > this->_data)
{
temp = this->getDepth(*root.getRight());
return temp == -1 ? -1 : temp + 1;
}
else if (root.getData() < this->_data)
{
temp = this->getDepth(*root.getLeft());
return temp == -1 ? -1 : temp + 1;
}
else if (root.getData() == this->_data)
{
return 0;
}
}
else
{
return -1;
}
}

Tests randomly fails

I'm writing board game and I need following functionality: player rolls two dices, if he rolled doubles (same number on both dice), he gets to roll again, if he rolled doubles again, he goes to jail.
In my Game class it looks like that
void logic::Game::rollTheDice() {
m_throwsInCurrentTurn++;
int firstThrow = m_firstDice.roll();
int secondThrow = m_secondDice.roll();
m_totalRollResult += firstThrow + secondThrow;
if (firstThrow == secondThrow) m_doublesInCurrentTurn++;
}
std::string logic::Game::checkForDoubles() {
std::string message;
if (m_doublesInCurrentTurn == 0 && m_throwsInCurrentTurn == 1) {
m_canThrow = false;
m_canMove = true;
}
if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 1) {
message = "Doubles! Roll again.";
m_canThrow = true;
m_canMove = false;
}
if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 2) {
m_canThrow = false;
m_canMove = true;
}
if (m_doublesInCurrentTurn == 2 && m_throwsInCurrentTurn == 2) {
message = "Doubles again! You are going to jail.";
m_canThrow = false;
m_canMove = false;
getActivePlayer().lockInJail();
}
return message;
}
void logic::Game::setInMotion(unsigned number) {
m_players[m_activePlayer].startMoving();
m_players[m_activePlayer].incrementPosition(number);
}
m_canThrow basicly enables or disables ability to click "Roll the Dice" button, m_canMove decides if player token can start moving, m_players[m_activePlayer] is std::vector<Player>, startMoving() does that,
void logic::Player::startMoving() {
m_isMoving = true;
}
needed for token movement, so baiscly not relevant here.
Last function from Game class I need to show you is reset(), used mainly for testing purposes
void logic::Game::reset() {
m_throwsInCurrentTurn = 0;
m_doublesInCurrentTurn = 0;
m_totalRollResult = 0;
}
Now finnaly Unit Test that sometimes goes wrong. Sometimes, I mean completely random, like 1 out of 10-20 times.
//first throw is double, second throw is not
TEST_F(GameTestSuite, shouldFinishAfterSecondRollAndMove) {
auto game = m_sut.get();
do {
if (game.getThrowsInCurrentTurn() == 2) game.reset();
game.rollTheDice();
game.checkForDoubles();
if (game.getThrowsInCurrentTurn() == 1 && game.getDoublesInCurrentTurn() == 1) {
ASSERT_EQ(game.canThrow(), true);
ASSERT_EQ(game.canMove(), false);
}
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
ASSERT_EQ(game.canThrow(), false);
ASSERT_EQ(game.canMove(), true);
game.setInMotion(game.getTotalRollResult());
ASSERT_EQ(game.getActivePlayer().isMoving(), true);
ASSERT_EQ(game.getActivePlayer().getPosition(), game.getTotalRollResult());
}
This line exactly, ASSERT_EQ(game.canThrow(), false); sometimes is equal true after do-while loop that should end once m_canThrow is set to false
Shouldn't:
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
be
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() <= 1);
You want to allow up to two turns but 0 or 1 doubles.

The issue of using Do-While loop in C++?

I have tried to list prime numbers using C++ Do-While loop but I have trouble and not found problems inside my code. Can any one help me in this?
I have tried so far:
#include <iostream>
using namespace std;
int main()
{
int num2check = 3, innerCheck;
bool isPrime;
do
{
isPrime = true;
innerCheck = 2;
while ((innerCheck < num2check) && (isPrime == true));
{
if (num2check % innerCheck == 0)
{
isPrime = false;
break;
}
else
{
innerCheck++;
}
}
if (isPrime == true)
{
cout << num2check << " is prime.";
num2check++;
}
else
{
num2check++;
}
}while(num2check < 50);
return 0;
}
You need to remove the semicolon in this line
while ((innerCheck < num2check) && (isPrime == true));
In programming standards, the ; signifies an end of statement, or in this case that it is a null statement, so here the while loop doesn't executes anything and keeps on running in infinite loop as the condition will always holds true

Out of range vector subscript C++

I have this method in one of my cpp files where I have navigated my failure to be. I have also added cout statements and checked that there is content in both foo and mainWord. I think my problem has to do with how I've added elements to foo or how I am trying to re-add them. The size mainWord is 88 and the size of foo is more than 1000. Here is where I add elements to foo:
while (myfile>>magic)//store the colours in an array
{
foo.push_back(magic);
}
and here is where I try and change them and add them back in.
void Penguin::addWord(std::vector<int> foo)
{
unsigned fooCounter=0;
int temp;
for (int i=0;i<88;i+2)
{
if(foo.at(fooCounter) == 11111111 && foo.at(fooCounter) != NULL)
{
if(mainWord[i]==1 && mainWord[i+1]==1)
{
foo.at(fooCounter) = 11111111;
}
else if(mainWord[i]== 1 && mainWord[i+1] == 0)
{
foo.at(fooCounter) = 11111110;
}
else if(mainWord[i]== 0 && mainWord[i+1] == 1)
{
foo.at(fooCounter) = 11111101;
}
else
{
foo.at(fooCounter) = 11111100;
}
}
else if (foo.at(fooCounter) == 11111111 && foo.at(fooCounter) != NULL)
{
if(mainWord[i]== 1 && mainWord[i+1] == 1)
{
foo.at(fooCounter) = 00000011;
}
else if(mainWord[i]== 1 && mainWord[i+1] == 0)
{
foo.at(fooCounter) = 00000010;
}
else if(mainWord[i]== 0 && mainWord[i+1] == 1)
{
foo.at(fooCounter) = 00000001;
}
else
{
foo.at(fooCounter) = 00000000;
}
}
fooCounter++;
}
}
I keep getting an error that says: "Debug Assertion Failed. Vector subscript out of range"
...Please help
You have an infinite loop because i is never updated in the for loop. You need to fix the typo:
for (int i=0;i<88;i+=2)
^
^

infix to postfix program

I have written the following infix to postfix program but it's not working.
My program takes input but doesn't show any result. Can anyone help find the problem in my program.
And also it would be a great help if you tell if my Algorithm for converting infix to postfix is correct or not.
using namespace std;
class Stack
{
private:
int top;
char s[mx];
public:
Stack()
{
top=-1;
}
void push(char c)
{
if(!stackFull())
s[++top]=c;
}
void pop()
{
if(!stackEmpty())
top--;
else cout<<"Stack is empty"<<endl;
}
char topShow()
{
if(!stackEmpty())
return s[top];
}
bool stackEmpty()
{
if(top==-1)
return 1;
else return 0;
}
bool stackFull()
{
if(top == (mx-1))
return 1;
else return 0;
}
};
class Expression
{
private:
char entry2;
int precedence;
char infix[mx];
char postfix[mx];
public:
int prec(char symbol)
{
switch(symbol)
{
case '(':return 0; break;
case '-':return 1; break;
case '+':return 2; break;
case '*':return 3; break;
case '/':return 4; break;
}
}
void Read()
{
cout<<"Enter the infix expression: ";cin>>infix;
for(int i=0;infix[i]!='\0';i++)
{
convertToPostfix(infix[i]);
}
}
void ShowResult()
{
cout<<"Postfix expression"<<endl;
for(int j=0;postfix[j]!='\0';j++)
{
cout<<postfix[j];
}
}
void convertToPostfix(char c)
{
int p=0;
Stack myStack;
precedence=prec(c);
entry2=myStack.topShow();
if(isdigit(c))
{
postfix[++p]=c;
}
if(precedence>prec(entry2))
{
myStack.push(c);
}
if(precedence<prec(entry2))
{
switch(c)
{
case '(': myStack.push(c); break;
case ')': while(myStack.topShow()!= '(')
{
postfix[++p]=myStack.topShow();
myStack.pop();
};myStack.pop();break;
case '+':
case '-':
case '*':
case '/': while(prec(myStack.topShow())>=precedence)
{
postfix[++p]=myStack.topShow();
myStack.pop();
};break;
}
}
}
};
int main()
{
Expression myExp;
myExp.Read();
myExp.ShowResult();
return 0;
}
Here are some issues I found:
Boolean Functions Return true or false
Match return types with return values. The numbers 1 and 0 are not Boolean values.
Precedence table
Add and subtract have same precedence.
Multiply and divide have same precedence.
Multiply and divide have higher precedence than add and subtract.
Stack disappears
Since the stack is declared as a local variable in the function, it will be created fresh when entering the function and destroyed before exiting the function.
Solution: move it to the class as a class member or declare it as static.
Multiple statements per line are not more efficient
Blank lines and newlines do not affect performance, and add negligible time to the build.
However, they make your program more readable which helps when inspecting or debugging. Use them.
And similarly with space before and after operators.
Build the habit now rather than correcting when you get a job.
Call function once and store the value
You call prec(entry2) twice, which is a waste of time. Call it once and save the value in a variable. Similarly with stack.TopShow().
Use std::vector not an array
The std::vector will grow as necessary and reduce the chance of buffer overflow.
With an array, you must check that your indices are always within range. Also, array capacities don't change; you have to declare a new instance and copy the data over.
The variable mx is not declared
The compiler should catch this one. You use mx as the capacity for an array and comparing for full. However, it is never declared, defined nor initialized. Prefer std::vector and you won't have to deal with these issues.
Input is not validated
You input a letter, but don't validate it.
Try these characters: space, #, #, A, B, etc.
Missing default for switch
Crank up your compiler warnings to maximum.
Your switch statements need defaults.
What precedence do numeric characters ('0'..'9') have?
(You check the precedence of numeric characters.)
Check all paths through your functions and program.
Using a debugger (see below) or pen and paper, check your program flow through you functions. Include boundary values and values not within the bounds.
Case statements: break or return
You don't need a break after a return statement. Think about it. Can the program continue executing at the line after a return statement?
Use a debugger or print statements
You can print variables at different points in your program. This is an ancient technique when debuggers are not available.
Learn to use a debugger. Most IDEs come with them. You can single step each statement and print out variable values. Very, very, useful.
class infixToPostfix{
public static void postfix(String str){
Stack<Character> stk = new Stack<Character>();
for(Character c : str.toCharArray()){
// If operands appears just print it
if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'){
System.out.print(c);
}else{
// Open paranthesis push is
if(c == '('){
stk.push(c);
//Close paranthesis pop until close paranthesis
}else if( c == ')'){
while(stk.peek() != '(')
System.out.print(stk.pop());
stk.pop();
// check the precedence of operator with the top of stack
}else if(c == '+' || c == '-'){
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '*' || top == '/' || top == '+' || top == '-'){
System.out.print(stk.pop());
}
}
stk.push(c);
}else{
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '/' || top == '*'){
System.out.print(stk.pop());
}
}
stk.push(c);
}
}
}
//Print all the remaining operands
while(!stk.isEmpty()) System.out.print(stk.pop());
System.out.println();
}
public static void main(String args[]){
String str = "A+B-(c+d*Z+t)/e";
postfix(str);
}
}
using stack and map u can solve the problem
1) create a map having operator as key and some integer to set priority. operator with same precedence will have same value something like:
map<char,int>oprMap;
oprMap['^'] = 3;
oprMap['*'] = 2;
oprMap['/'] = 2;
oprMap['+'] = 1;
oprMap['-'] = 1;
2) iterate through given expression call these checks
1) if current element
i) is operand add it to result
ii) not operand do following check
a. while not (stack is empty and element is open bracket and found operator with higher precedence.
add top of the stack to the result and pop()
b. push current element to stack
iii) if open brackets push to stack
iv) if closed brackets pop until get closed bracket and add it to result
3) while stack is not empty pop() and add top element to the result.
{
stack<char>S;
for (int i = 0; i < n; i++) {
if(isOperand(exps[i])) {
res = res + exps[i];
} else if(isOperator(exps[i])){
while(!(S.empty() && isOpenParanthesis(S.top()) && isHeigherPrecedence(S.top(),exps[i])){
res = res+S.top();
S.pop();
}
S.push(exps[i]);
} else if(isOpenParanthesis(exps[i])) {
S.push(exps[i]);
} else if(isClosingParanthesis(exps[i])) {
while(!S.empty() && !isOpenParanthesis(S.top())) {
res = res+S.top();
S.pop();
}
S.pop();
}
}
while(!S.empty()) {
res = res + S.top();
S.pop();
}
}
}
#include<bits/stdc++.h>
using namespace std;
// This isHigher function checks the priority of character a over b.
bool isHigher(char a,char b)
{
if(a=='+' || a=='-')
return false;
else if((a=='*' && b=='*') || (a=='*' && b=='/') || (a=='/' && b=='*') ||
(a=='/' && b == '/')|| (a=='^' && b=='^')||(a=='*' && b=='^') || (a=='/' &&
b=='^'))
return false;
return true;
}
int main(){
string s;
cin>>s;
s = s + ")";
//Vector postfix contains the postfix expression.
vector<char>postfix;
stack<char>mid;
mid.push('(');
for(int i=0;i<s.length();i++)
{
if(s[i] == '(')
mid.push(s[i]);
else if(s[i] == '+' || s[i] == '^' || s[i] == '-' || s[i] == '*'||
s[i] == '/')
{
if(mid.top() == '(')
mid.push(s[i]);
else {
if(isHigher(s[i],mid.top()))
mid.push(s[i]);
else
{
while(mid.top()!='(')
{
if(!isHigher(s[i],mid.top()))
{
postfix.push_back(mid.top());
mid.pop();
}
else
break;
}
mid.push(s[i]);
}
}
}
else if(s[i] == ')')
{
while(mid.top() != '(')
{
postfix.push_back(mid.top());
mid.pop();
}
mid.pop();
}
else
postfix.push_back(s[i]);
}
for(int i=0;i<postfix.size();i++)
cout<<postfix[i];
return 0;
}