I'm doing this code for a project to evaluate an algorithmic equation, if it doesn't have a "a" in the string of the algorithmic equation I'm given, I'm supposed to return the value and return false. If it does have "a" I'm supposed to return value = 0 and return true. This is all being done a in a bool function.
#include <string>
#include <sstream>
bool Evaluate(const string& expression, int& value){
int a;
int b;
int c;
int d;
int e;
string valueA;
string valueB;
string valueC;
string valueD;
string valueE;
int y;
int z;
unsigned int i;
stringstream x;
int szz;
string alg;
if(!expression.find('a')) {
szz = expression.size();
alg = expression.copy(0, szz);
for (i = 0; i <= szz; ++i) {
alg.find_first_of('*/%');
if (isdigit(alg[i] - '*')) {
a = alg.find('*');
y = a - 1;
z = a + 1;
valueA = alg.substr(y, z);
a = stoi(valueA);
x << a;
valueA = x.str();
alg.replace(y, 2, valueA);
}
if (isdigit(alg[i] - '/')) {
b = alg.find('/');
y = b - 1;
z = b + 1;
valueB = alg.substr(y, z);
b = stoi(valueB);
x << b;
valueB = x.str();
alg.replace(y, 2, valueB);
}
value = stoi(alg);
return false;
}
else{
value = 0;
return true;
}
}
I'm expecting to get the correct values and the correct true/false. Currently if there's an a in the equation I get the result correct as 0, but not the evaluate result (true/false). The opposite happens if there's no a in the equation, I get the evaluate result correct as false but not the actual correct value.
Your algorithm does a lot more than what you write. The goal, apparently, is not to look for a but rather to evaluate entire math expressions.
Furthermore, your algorithm is flawed in many ways, I just point out some here:
The if in
string alg;
if(!alg.find('a')) {
is always true since there never is an 'a' in alg since alg is created empty just the line before.
This does just copy an entire string
szz = expression.size();
alg = expression.copy(0, szz);
and is 100% equivalent to string alg = expression;
You don't need a for loop in
for (i = 0; i <= szz; ++i) {
alg.find_first_of('*/%');
since the find_first_of does what it advertises and already loops over the string itself.
You just discard the return value of alg.find_first_of('*/%');. You want to write int operator_position = alg.find_first_of('*/%');, then you know that at alg[operator_position] there is one of */%.
You have several lines of this type
isdigit(alg[i] - '*')
but it appears to be obvious to me that this is very much not what you want. From the logic of your code, I understand you need to know if a sub-string in alg is a digit (or still an expression containing +-*/%). Your statement only acts on a single char
Other potential problems.
You actual problem you describe can be solved easily:
bool Evaluate(const string& expression, int& value){
if (expression.find('a')!=string::npos) {
// whatever it means to "contain the value" ????
return false;
}
value = 0;
return true;
}
But this will serve no reasonable purpose and I am sure you are really just mis-representing the actual problem posed....
Here is what I would infer as an actual related problem and algorithm: Q: evaluate math expressions from a string and return the answer. Thus, "2*6+4-6/2" should return 13. If you want to achieve this, you need iterative function calling of Evaluate and I would propose double Evaluate(const string& expression):
you evaluate if your string contains any of +- if yes, you iteratively evaluate the two independent parts (using expression.substr(start,length)) proceeding as well as preceeding the operator_position (see above for a hint). You then either add or subtract the two results depending on + or -. You return the result.
(else) you evaluate if your string contains any of */% and if yes, you iteratively evaluate the two independent sub-strings proceeding and preceeding the operator_position. You either multiply, divide or modulo the two values and return the result.
if none of the two above, then the remaining expression must be a number and you convert the string into a double (std::stod(expression)) and return it.
This iterative algorithm will magically correctly evaluate any math expression.
Related
I am working on this LeetCode problem to take an integer and reverse it, given that the reversed in is within the signed 32-bit range, in which case we should return 0.
and this code is doing just that, even with numbers like 1534236469/-1534236469. Except when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
I know this is not the cleanest code, but can you help me recognise what I'm missing?
#include<iostream>
#include<limits>
using namespace std;
class Solution {
public:
int reverse(int x) {
int a, r, y;
string num, fnum;
a = abs(x);
try{
while(a != 0){
r = a % 10;
a = a / 10;
num = to_string(r);
fnum = fnum + num;
y = stoi(fnum);
}
} catch(out_of_range& oor){
return 0;
}
if(x==0){
return 0;
} else if (x<0){
return -y;
} else {
return y;
}
}
};
int main(){
Solution mine;
cout << mine.reverse(-2147483648);
}
[...] when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
That number is "tricky" because it's equal to std::numeric_limits<int>::min() in your environment and given a two's complement representation of type int, it happens that std::abs(-2147483648) == -2147483648.
Next in your (contrived, I must say, there's no need to use a string here) code, the line num = to_string(r); would result in num = "-8", so that the loop would compose a string like "-8-4-6-3-8-4-7-4-1-2".
When applyed to strings like that, stoi doesn't throw an exception, it just stops parsing (you would have noticed it by passing and inspecting its other parameters).
If you want to check if the result is outside the range of an int, you could use locally a wider type (e.g. long long) and check the boundaries after the calculations or keep using int, but compare all the intermediate values with the limits before any calculation.
So I've tried to create a simple program to calculate n-th fibonacci number mod 10^9+7 using the doubling formula with F[0]=0 and F[1]=1. and the program seems to work on my computer with compilers VS2010 and CodeBlocks with MinGW however testing my program on ideone returns 0 for every input. It seems that after the first iteration F.find(n) actually finds elements which shouldn't exist. Here's my code (in VS2010 I just changed the includes).
#include <bits/stdc++.h>
using namespace std;
std::map<unsigned long long,unsigned long long> F;
unsigned long long fib(unsigned long long n)
{
if(n==-1) return 0; // Shifting index by 1
if(n==0) return 1;
if(n==1) return 1;
if(F.find(n) != F.end()) return F[n]; // This seems to be the problem,
else
{
if(n%2==0) //
{
F[n/2-1] = fib(n/2-1)%1000000007;
F[n/2] = fib(n/2)%1000000007;
return F[n] = (F[n/2-1]*F[n/2-1]+F[n/2]*F[n/2])%1000000007;
}
else
{
F[n/2] = fib(n/2)%1000000007;
F[n/2+1] = fib(n/2+1)%1000000007;
return F[n] = (F[n/2]*(2*F[n/2+1]-F[n/2]))%1000000007;
}
}
}
int main() {
unsigned long long int broj;
cin >> broj; // input the number
cout << fib(broj-1) << endl;
return 0;
}
You have issue with expressions like this:
F[n/2-1] = fib(n/2-1)%1000000007;
as order of evaluation of operator[] on std::map is not defined it may call it before fib(n/2-1) and create an empty element there. You should store cached value in function where you calculate it.
Also calling std::map::operator[] with the same key as you used with std::map::find is wasteful.
Possible fix:
auto p = F.emplace( n, 0 );
if( p.second ) {
// element was not there
// calculate and store at p.first->second
}
return p.first->second;
Another possible fix is to add two temp variables lets say
unsigned long long a,b; and change the lines
F[n/2-1] = fib(n/2-1)%1000000007;
F[n/2] = fib(n/2)%1000000007;
To
a = fib(n/2-1)%1000000007;
b = fib(n/2)%1000000007;
F[n/2-1] = a;
F[n/2] = b;
This way it doesn't matter whether map creates the element then assign value. It also can optimize the following line
return F[n] = (F[n/2-1]*F[n/2-1]+F[n/2]*F[n/2])%1000000007;
To avoid searching for F[n/2-1] and F[n/2] into
return F[n] = (a*a+b*b)%1000000007;
I am currently using the code below that removes all digits equal to zero from an integer.
int removeZeros(int candid)
{
int output = 0;
string s(itoa(candid));
for (int i = s.size(); i != 0; --i)
{
if (s[i] != '0') output = output * 10 + atoi(s[i]);
}
return output;
}
The expected output for e.g. 102304 would be 1234.
Is there a more compact way of doing this by directly working on the integer, that is, not string representation? Is it actually going to be faster?
Here's a way to do it without strings and buffers.
I've only tested this with positive numbers. To make this work with negative numbers is an exercise left up to you.
int removeZeros(int x)
{
int result = 0;
int multiplier = 1;
while (x > 0)
{
int digit = x % 10;
if (digit != 0)
{
int val = digit * multiplier;
result += val;
multiplier *= 10;
}
x = x / 10;
}
return result;
}
For maintainability, I would suggest, don't work directly on the numeric value. You can express your requirements in a very straightforward way using string manipulations, and while it's true that it will likely perform slower than number manipulations, I expect either to be fast enough that you don't have to worry about the performance unless it's in an extremely tight loop.
int removeZeros(int n) {
auto s = std::to_string(n);
s.erase(std::remove(s.begin(), s.end(), '0'), s.end());
return std::stoi(s);
}
As a bonus, this simpler implementation handles negative numbers correctly. For zero, it throws std::invalid_argument, because removing all zeros from 0 doesn't produce a number.
You could try something like this:
template<typename T> T nozeros( T const & z )
{
return z==0 ? 0 : (z%10?10:1)*nozeros(z/10)+(z%10);
}
If you want to take your processing one step further you can do a nice tail recursion , no need for a helper function:
template<typename T> inline T pow10(T p, T res=1)
{
return p==0 ? res : pow10(--p,res*10);
}
template<typename T> T nozeros( T const & z , T const & r=0, T const & zp =0)
{
static int digit =-1;
return not ( z ^ r ) ? digit=-1, zp : nozeros(z/10,z%10, r ? r*pow10(++digit)+zp : zp);
}
Here is how this will work with input 32040
Ret, z, r, zp, digits
-,32040,0,0, -1
-,3204,0,0, -1
-,320,4,0,0, -1
-,32,0,4,4, 0
-,3,2,4, 0
-,0,3,24, 1
-,0,0,324, 2
324,-,-,-, -1
Integer calculations are always faster than actually transforming your integer to string, making comparisons on strings, and looking up strings to turn them back to integers.
The cool thing is that if you try to pass floats you get nice compile time errors.
I claim this to be slightly faster than other solutions as it makes less conditional evaluations which will make it behave better with CPU branch prediction.
int number = 9042100;
stringstream strm;
strm << number;
string str = strm.str();
str.erase(remove(str.begin(), str.end(), '0'), str.end());
number = atoi(str.c_str());
No string representation is used here. I can't say anything about the speed though.
int removezeroes(int candid)
{
int x, y = 0, n = 0;
// I did this to reverse the number as my next loop
// reverses the number while removing zeroes.
while (candid>0)
{
x = candid%10;
n = n *10 + x;
candid /=10;
}
candid = n;
while (candid>0)
{
x = candid%10;
if (x != 0)
y = y*10 + x;
candid /=10;
}
return y;
}
If C++11 is available, I do like this with lambda function:
int removeZeros(int candid){
std::string s=std::to_string(candid);
std::string output;
std::for_each(s.begin(), s.end(), [&](char& c){ if (c != '0') output += c;});
return std::stoi(output);
}
A fixed implementation of g24l recursive solution:
template<typename T> T nozeros(T const & z)
{
if (z == 0) return 0;
if (z % 10 == 0) return nozeros(z / 10);
else return (z % 10) + ( nozeros(z / 10) * 10);
}
I have to input a number n, an a digit and a b digit and output the number n with all the a digits in it replaced by a b one. For example:
Input:
n = 1561525
a = 5
b = 9
Output:
n = 1961929
Should be recursive ! I didn't post any code as I've done it in a non-recursive way but apparently it's not even close to what I need.
Thanks for the help !
Check this, it works but maybe it is to much C
int convert(int num, int a, int b)
{
if( num )
{
int res = convert(num/10,a,b);
int t = num%10;
res *=10;
t = t == a ? b:t;
res = res + t;
return res;
}
return 0;
}
Divide by 10 the initial number, until nothing left of it, and then construct it again replacing a with b.
To make things easier, you can convert the number into a string (a char[] in C++). Then, it's a simple matter of iterating over it and checking at each step if the number we want to replace was found in the current position. For a possible solution, here's an implementation of the algorithm in Python - one of the nice things of the language is that it reads almost as pseudocode, and it should be relatively simple to port to C++:
def aux(n, a, b, i):
if i == len(n):
return ''
elif n[i] == a:
return b + aux(n, a, b, i+1)
else:
return n[i] + aux(n, a, b, i+1)
def change(n, a, b):
return int(aux(str(n), str(a), str(b), 0))
It works as expected:
change(1561525, 5, 9)
=> 1961929
So the easiest and safest way I can think of, is by using std::replace:
int replace(int num, int d1, int d2) {
string s = std::to_string(num); // convert to string
std::replace( s.begin(), s.end(), d1+'0', d2+'0'); // call std::replace
return atoi( s.c_str() ); // return the int
}
Now if you really have to use recursion (there is no need for it here), here's one possible solution:
using std::string;
// recursive function, accepts a string, current index, c2 replaces c1
string replace_rec (string s, unsigned index, char c1, char c2) {
// check if the it's still a valid index
if (index < s.size()) {
// if this is a char to be converted, do so
if (s[index] == c1)
s[index] = c2;
// call itself but with an updated string and incremented index
replace_rec(s, index+1, c1, c2);
}
// the last call will result in the string with all chars checked. return it
return s;
}
// call this function with input, the num to be replaced and what with
int replace(int num, int d1, int d2) {
string s = std::to_string(num); // convert to string
// convert the result back to int and return it.
return atoi( replace_rec(s, 0, d1+'0', d2+'0').c_str() );
}
In any case, you can call your replace() function like this:
int main(){
cout << replace (4578, 4, 9); // output: 9578
cin.get();
}
As a part of a larger program, I must convert a string of numbers to an integer(eventually a float). Unfortunately I am not allowed to use casting, or atoi.
I thought a simple operation along the lines of this:
void power10combiner(string deciValue){
int result;
int MaxIndex=strlen(deciValue);
for(int i=0; MaxIndex>i;i++)
{
result+=(deciValue[i] * 10**(MaxIndex-i));
}
}
would work. How do I convert a char to a int? I suppose I could use ASCII conversions, but I wouldn't be able to add chars to ints anyways(assuming that the conversion method is to have an enormous if statement that returns the different numerical value behind each ASCII number).
There are plenty of ways to do this, and there are some optimization and corrections that can be done to your function.
1) You are not returning any value from your function, so the return type is now int.
2) You can optimize this function by passing a const reference.
Now for the examples.
Using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result;
std::stringstream ss;
ss << deciValue.c_str();
ss >> result;
return result;
}
Without using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result = 0;
for (int pos = 0; deciValue[pos] != '\0'; pos++)
result = result*10 + (deciValue[pos] - '0');
return result;
}
EDITED by suggestion, and added a bit of explanation.
int base = 1;
int len = strlen(deciValue);
int result = 0;
for (int i = (len-1); i >= 0; i--) { // Loop right to left. Is this off by one? Too tired to check.
result += (int(deciValue[i] - '0') * base); // '0' means "where 0 is" in the character set. We are doing the conversion int() because it will try to multiply it as a character value otherwise; we must cast it to int.
base *= 10; // This raises the base...it's exponential but simple and uses no outside means
}
This assumes the string is only numbers. Please comment if you need more clarification.
You can parse a string iteratively into an integer by simply implementing the place-value system, for any number base. Assuming your string is null-terminated and the number unsigned:
unsigned int parse(const char * s, unsigned int base)
{
unsigned int result = 0;
for ( ; *s; ++s)
{
result *= base;
result += *s - '0'; // see note
}
return result;
}
As written, this only works for number bases up to 10 using the numerals 0, ..., 9, which are guaranteed to be arranged in order in your execution character set. If you need larger number bases or more liberal sets of symbols, you need to replace *s - '0' in the indicated line by a suitable lookup mechanism that determines the digit value of your input character.
I would use std::stringstream, but nobody posted yet a solution using strtol, so here is one. Note, it doesn't perform handle out-of-range errors. On unix/linux you can use errno variable to detect such errors(by comparing it to ERANGE).
BTW, there are strtod/strtof/strtold functions for floating-point numbers.
#include <iostream>
#include <cstdlib>
#include <string>
int power10combiner(const std::string& deciValue){
const char* str = deciValue.c_str();
char* end; // the pointer to the first incorrect character if there is such
// strtol/strtoll accept the desired base as their third argument
long int res = strtol(str, &end, 10);
if (deciValue.empty() || *end != '\0') {
// handle error somehow, for example by throwing an exception
}
return res;
}
int main()
{
std::string s = "100";
std::cout << power10combiner(s) << std::endl;
}