Write a function without using any semicolon - c++

I have a very strange problem in my homework.
So I have to build a function which calculates the sum/difference of two numbers.
It looks fairly easy but there's a catch.
This is the function:
void sumdif()
{
int result = 0;
//input
//output
}
I can't use any semicolons, and this is how the function must look.
Input consists of:
number, + or - (depending if you want to substract or to add) and another number.
The function will output the result.
If I could use semi-colons, it would've been easy.
I have no idea how to resolve this problem in this case, though.
I've thought about using a ternary operator. Unfortunately, I can't see how to take input, output and also differentiate + and - in one line. (and I think I needed ";" anyway so it wouldn't help me).
Here's the problem:
https://www.pbinfo.ro/?pagina=probleme&id=3191
Unfortunately, it is in romanian. You can use google translate for more details, but I've explained the idea.
Through that function you take input, then output the result, and more than that you can't use any semicolon. (this is the hardest part for me - I've never dealt with this before)
How can this problem be solved?

Just performs the operations inside the if condition like in the following:
void sumdif()
{
if (char c = '+') { //declare c
if (cin >> c) { //read c
if (int a = 1) { //declare a
if (cin >> a) { //read a
if (int b = 1) { //declare b
if (cin >> b) { //read b
if (c == '+') { //choose operation
if (cout << (a + b)) { //print sum
}
}
else {
if (cout << (a - b)) { //print difference
}
}
}
}
}
}
}
}
}
LIVE DEMO

Related

How to replace characters of a string in c++ with a recursive function?

Hello I'm a beginner in cpp programming. I was reading some examples of cpp programs and i see this question but i couldn't solve it :
There's an algorithm below starting from 0 as each step that goes forward you should replace all 0's with 01 and 1's 10. The input is the number of stage and the output is the number that generates solve this with recursive function.
Here is the example:
1)0
2)01
3)0110
...
Input:3
Output:0110
I tried this:
string generate(string &algorithm, int n) {
if (n <= 0)
return algorithm;
//confused?
}
int main() {
string algorithm = "0";
string new_algorithm;
long long int n, k;
cin >> n >> k;
new_algorithm = generate(algorithm, n);
return 0;
}
It should be in recursive form but I can't do it straight too!
Any help would be appreciated!
The number of recusions is given so the function will look something like this:
std::string replace_recursive(const std::string& in, int n) {
if (n <= 0) return in;
std::string next = replace(in);
return replace_recursive(next,n-1);
}
It has a stop condition, it executes a single step (by calling replace) and it has the recursive call.
All you need to add is going from in to next. For this it is easiest to use a range based loop and construct the new string by appending. I am trying to not give away the whole solution:
std::string replace(const std::string& in) {
std::string result;
for (const auto& c : in) {
if (c == ....) result += " ... ";
else if (c = ....) result += " .... ";
}
return result;
}

Evaluate infix string expression consisting of only addition and multiplication

How can I evaluate an infix string expression which only consists of + and * operators. (No parenthesis).
Example 1:
Input: "1+2*3"
Output: 7
Example 2:
Input: "1+2*3+4"
Output: 11
Here is my code I have so far (which is not giving correct result), I wonder if I can do it with one stack (or none)
int evaluateExpression(string s) {
stack<int> operandStack;
stack<char> operatorStack;
string token = "";
for(char &c : s) {
if(c == '*' || c == '+') {
operandStack.push(stoi(token));
operatorStack.push(c);
token = "";
}
else {
token += c;
}
if(operandStack.size() > 1
&& operandStack.size() == operatorStack.size() + 1
&& operatorStack.top() == '*') {
int a = operandStack.top(); operandStack.pop();
int b = operandStack.top(); operandStack.pop();
operandStack.push(a * b);
}
}
while(operandStack.size() > 1) {
int a = operandStack.top(); operandStack.pop();
int b = operandStack.top(); operandStack.pop();
operandStack.push(a + b);
}
return operandStack.top();
}
Note: do not want to use any non-standard libraries. Ideally with no use of any library.
Yes, you do need only one stack. You can use the standard approach with a shift-reduce parser. In your case, and the simple grammar, this may be already a little bit too much. But I will describe it anyway.
The secret is to use a "parse stack". So only one stack. Not an operator and operand stack. There you will use attributed tokens. A token has a type, like ADD, MULT, NUMBER and, an associated attribute. The attribute is usually a union or a struct. It would be empty for ADD and MULT and would contain a value for NUMBER.
The scanner, which has usually the function getNextToken will produce your tokens. In your case, extremely simple, just those 3 tokens.
Then, in a loop, you will do always the following actions.
Always push the fresh token onto the parse stack
Try to match the top of the stack with a production of the grammar (and look ahead token)
Reduce the stack (Remove matched elements), evaluate the expression, and put the result on the parse stack
So, always: Shift, Match, Reduce
In your case you need for the match function one lookahead symbol, so, the next token. You will find exactly such an example here. There you can find a compiler, with one front end (Scanner, Parser) and 2 different code generators as back end. The code generators are not needed for you task, you can directly evaluate while reducing.
But, for such an easy grammar, you do not need a stack at all. In the book crafting A Compiler with C is a good example. My copy of the book is from 1991, but of course the content is still valid.
They basically write a function for each production/terminal/non-terminal in the grammar and evaluate the tokens and call the functions of other terminals or non-terminals. Interesting approach and not difficult for your use case.
Hope this helps a little . . .
int evaluateExpression(string s) {
string token = "";
char currOperator = '+';
stack<int> st;
string temp = s + '.';
for(const char &c : temp) {
if(isdigit(c)) {
token += c;
}
else if(c != ' ') {
if(currOperator == '*') {
int stackTop = st.top();
st.pop();
st.push(stackTop * stoi(token));
}
else if(currOperator == '+') {
st.push(stoi(token));
}
token = "";
currOperator = c;
}
}
int result = 0;
while(!st.empty()) {
result += st.top();
st.pop();
}
return result;
}

RPN calculator / post fix calculator

So, i have to make a postfix calculator or a RPN calculator, the question goes like
The task is to write a simplified calculator that works only on integers. Your code has to provide a function called evaluate, which takes one argument: a std::string and returns an integer. The calculator has to work in the following way:
it reads a string character by character,
if it reads a digit it puts it on its own internal stack,
if it reads a space it has to ignore it,
if it reads a character +,-, * or / it performs the operation on two topmost elements of the stack, deletes them and puts the result on the stack,
when it reaches the end of the std::string argument it returns the top of the stack.
Code:
using namespace std;
int evaluate(string);
bool isdigit(char c);
bool isOp(char c);
bool isdigit(char c)
{
if (c >= '0' && c <= '9')
{
return true;
}
return false;
}
int main()
{
string str;
cout << "\n Enter the input : ";
cin >> str;
evaluate(str);
}
int evaluate(string str)
{
stack<int> mystack;
stack<int> vals;
for (int i = 0; i < str.size(); i++)
{
char c = str[i];
if (isdigit(c))
{
vals.push(c);
}
else if (c == ' ')
{
c = ' ';
cout << str;
}
else
{
int value1, value2, result;
value2 = vals.top();
vals.pop();
value1 = vals.top();
vals.pop();
switch (str[i])
{
case '+':
result = value1 + value2;
mystack.push(result);
break;
case '-':
result = value1 - value2;
mystack.push(result);
break;
case '*':
result = value1 * value2;
mystack.push(result);
break;
case '/':
result = value1 / value2;
mystack.push(result);
break;
}
cout << "result is " << mystack.top();
}
}
}
i expect the actual answers, but i guess the program is not ignoring
the space and when i input the string without spaces theres still a
wrong output
Pay attention that the provided algorithm works only if it gets postfix expression, and not a infix expression.
First problem:
Now, have a look on the following line:
vals.push(c);
c is a char, and vals is an integers stack. When c presenting 1 in your code, the c++ compiler actually see '0' + 1. For example:
For the input 23+, you'll get the result: 101. Why?
'2' != 2 and '3' != 3. Actually the calculation is:
'0' + 2 + '0' + 3, which means 48 + 2 + 48 + 3 because '0' == 48 in ascii code.
To fix this little problem, all you have to do is to decrease the inserted value into the vals stack by '0':
vals.push(c - '0');
Now the result for the input 23+ is: 5.
Second problem:
You are using two stacks instead of one that actually needed. When you push the result value into the second stack (mystack), you actually can't get an access to it (or rather say make it more complicated to use it's value) whenever you will get another part of expression, for example:
23+5*
You can debug this case (use watch table/debug code feature of the IDE you are working with) and see that you are trying to access the 5 of the first result, and get nothing left in the first stack, because the result stored in the second one. Solution: use single stack.
case '+':
result = value1 + value2;
//mystack.push(result);
vals.push(result);
break;
General Improvements
function: isdigit
The first thing I would advice you to do, is to remove the if statement- you don't need it. The following code will do the trick:
bool isdigit(char c) {
return c >= '0' && c <= '9';
}
If this sentence will give you true, the function will return true, otherwise it will return false.
The second thing, is like the comments says, this function already exists in the standard c++ library. Just use:
#include <cctype>
And remove your implementation to this function. The same function with the same name already exists: http://www.cplusplus.com/reference/locale/isdigit/
Important!
This answer was given due to extra time in my life and a boring situation I'm in, but more importantly because I think that it can help to understand how to debug code and to solve future (and more complicated) cases. This kind of questions are Debug questions type. You don't actually have to look here for the answer, but to debug you code and to see what's wrong. Please use the tools you got here wisely, and Good Luck!
EDIT:
For more c++ style solution, in higher difficult level, you can see the following solution (consider it like welcome saying from c++):
int evaluate(string str) {
// [] () -> {} ====> READ ABOUT: Lambda expressions
stack<int> vals;
/*
* pop
* ---
* Returns the top value of a stack, and the pop it from the stack.
*/
auto pop = [] (stack<int> &s) -> int {
int res = s.top();
s.pop();
return res;
};
/*
* op
* --
* Returns a function that execute the selected operator on two integers params.
*/
auto op = [] (char op) -> std::function<int(int, int)> {
switch (op) {
case '+':
default : return [] (int a, int b) -> int { return a + b; };
case '-': return [] (int a, int b) -> int { return a - b; };
case '*': return [] (int a, int b) -> int { return a * b; };
case '/': return [] (int a, int b) -> int { return a / b; };
}
};
/*
* for_each is a loop implementation in c++ as part of the standard library (std).
* It's get the first iterator place (str.begin()), end iterator place (str.end()), and function to execute on
* each value in the collection (between start and end iterators).
*/
std::for_each(str.begin(), str.end(), [&vals, pop, op] (char c) {
if (isdigit(c)) vals.push(c - '0');
else if (c != ' ') vals.push(op(c)(pop(vals), pop(vals)));
// op(c) -> returns a function according to the operator
// op(c)(n1, n2) -> use the returned operator on n1 and n2
// pop(vals) -> function that returns the top value of the stack, and then pop it from the stack.
// op(c)(pop(vals), pop(vals)) -> apply the selected op on the first two values in the stack
});
cout << "The result is: " << vals.top() << endl;
}

A way to not accept float as input c++

I'm working on a project where I need to check for the correct input (n), I currently have a bit of code which won't allow string to be entered as it will ask again for a correct amount. I'm having trouble writing a code that won't allow float numbers to get through as it currently just ignores the float part of the input. I'm sorry if this is a simple question, but I haven't found a way to get around this yet.
for(int i=0; i<1; ++i)
{
string b1;
int e;
do
{
getline(cin,b1);
e=atoi(b1.c_str());
}
while(e==0 && b1!="0");
n=e; // where n is the user input
}
Assuming you consider anything with decimal point ('.') or using scientific notation with a negative exponent as a non-acceptable floating point number, just check if the entered string contains one of those:
std::string::iterator it;
if (b1.end() != std::find(b1.begin(), b1.end(), '.')
|| (b1.end() != (it = std::find_if(b1.begin(), b1.end(),
[](char c){ return c == 'e' || c == 'E'; })
&& it + 1 != b1.end()
&& '-' == it[1])) {
// deal with the string being a floating point number with a fractional part
}
Note, that this will consider, e.g., "10e-1" to be a bad value although it is actually just a fancy spelling of "1".
If you enter a float value then it will have a decimal point (.). As your input is a string hence you can do the following check :-
do
{
getline(cin,b1);
if(bi.find(".")!=b1.npos); // search if a decimal point is present or not
cout<<"wrong input";
else
e = stoi(b1); // stoi works similar to atoi but on strings
}
First thing you want to do is not repeat the code over and over ever time you want to read an integer. Make a function:
int getInt(std::istream & in)
This will take any input stream, cin, a file, a std::stringstream, whatever. Next we set up a few local variables we need.
{
std::string b1;
int e;
Now we build the input loop
while (std::getline(in, b1))
This will loop until the input stream fails. If it never fails and the user can't get their act togehter, we'll be here for a long long time. With Gilligan. The Skipper too. Maybe we can bum some money off of Mr. Howell for start-up seed capital, eh?
{
size_t pos;
Catch any exceptions thrown by the string -to-int conversion
try
{
Convert to int. pos will be updated with the character that ended the conversion. If it is not the end of the string, the string does not contain an int. If it does contain an int, we exit the function and return the int.
e = std::stoi(b1, &pos);
if (pos == b1.length())
{
return e;
}
}
We don't really need to do anything in the catch block. You could output a message to instruct or mock the user if you wish.
catch (...)
{
}
}
If we got here, the IO stream failed and we need to let folks know. Throw an exception.
// IO failure. throw exception
}
Usage is simple:
int value = getInt(cin);
You may wish to wrap the call in an try-catch block to catch the IO failure exception. cin's failure cases are pretty weird and usually fatal, though.
When calling getInt on a file you will want to handle things more carefully because end of file is a common occurrence.
All together without the running commentary:
int getInt(std::istream & in)
{
std::string b1;
int e;
while (std::getline(in, b1))
{
size_t pos;
try
{
e = std::stoi(b1, &pos);
if (pos == b1.length())
{
return e;
}
}
catch (...)
{
}
}
// IO failure. throw exception
}
You can use std::stringstream for this purpose :-
for(int i=0; i<1; ++i)
{
string b1;
char c=' ';
int e=0, check=0;
do
{
getline (cin, b1);
stringstream ss(b1);
ss >> check;
if(ss>>c)
cout << "bad input";
else
e=check;
}
while(e==0 && b1!="0");
n=e;
}

How to validate that there are only digits in a string?

I'm new to C++. I'm working on a project where I need to read mostly integers from the user through the console. In order to avoid someone entering non-digit characters I thought about reading the input as a string, checking there are only digits in it, and then converting it to an integer. I created a function since I need to check for integers several times:
bool isanInt(int *y){
string z;
int x;
getline(cin,z);
for (int n=0; n < z.length(); n++) {
if(!((z[n] >= '0' && z[n] <= '9') || z[n] == ' ') ){
cout << "That is not a valid input!" << endl;
return false;
}
}
istringstream convert(z); //converting the string to integer
convert >> x;
*y = x;
return true;
}
When I need the user to input an integer I'll call this function. But for some reason when I make a call tho this function the program doesn't wait for an input, it jumps immediately to the for-loop processing an empty string. Any thoughts? Thanks for your help.
There are many ways to test a string for only numeric characters. One is
bool is_digits(const std::string &str) {
return str.find_first_not_of("0123456789") == std::string::npos;
}
This would work:
#include <algorithm> // for std::all_of
#include <cctype> // for std::isdigit
bool all_digits(const std::string& s)
{
return std::all_of(s.begin(),
s.end(),
[](char c) { return std::isdigit(c); });
}
You can cast the string in a try/catch block so that if the cast fails you it would raise an exception and you can write whatever you want in the console.
For example:
try
{
int myNum = strtoint(myString);
}
catch (std::bad_cast& bc)
{
std::cerr << "Please insert only numbers "<< '\n';
}
Character-classification is a job typically delegated to the ctype facets of a locale. You're going to need a function that takes into account all 9 digits including the thousands separator and the radix point:
bool is_numeric_string(const std::string& str, std::locale loc = std::locale())
{
using ctype = std::ctype<char>;
using numpunct = std::numpunct<char>;
using traits_type = std::string::traits_type;
auto& ct_f = std::use_facet<ctype>(loc);
auto& np_f = std::use_facet<numpunct>(loc);
return std::all_of(str.begin(), str.end(), [&str, &ct_f, &np_f] (char c)
{
return ct_f.is(std::ctype_base::digit, c) || traits_type::eq(c, np_f.thousands_sep())
|| traits_type::eq(c, np_f.decimal_point());
});
}
Note that extra effort can go into making sure the thousands separator is not the first character.
try another way like cin.getline(str,sizeof(str)), and str here is char*. I think ur problem may be cause by other functions before calling this function. Maybe u can examine other parts of ur codes carefully. Breakpoints setting is recommended too.
Always use off-the-shelf functions. Never write alone.
I recommend
std::regex
Enjoy.