Solving a linear equation in one variable - c++

What would be the most efficient algorithm to solve a linear equation in one variable given as a string input to a function? For example, for input string:
"x + 9 – 2 - 4 + x = – x + 5 – 1 + 3 – x"
The output should be 1.
I am considering using a stack and pushing each string token onto it as I encounter spaces in the string. If the input was in polish notation then it would have been easier to pop numbers off the stack to get to a result, but I am not sure what approach to take here.
It is an interview question.

Solving the linear equation is (I hope) extremely easy for you once you've worked out the coefficients a and b in the equation a * x + b = 0.
So, the difficult part of the problem is parsing the expression and "evaluating" it to find the coefficients. Your example expression is extremely simple, it uses only the operators unary -, binary -, binary +. And =, which you could handle specially.
It is not clear from the question whether the solution should also handle expressions involving binary * and /, or parentheses. I'm wondering whether the interview question is intended:
to make you write some simple code, or
to make you ask what the real scope of the problem is before you write anything.
Both are important skills :-)
It could even be that the question is intended:
to separate those with lots of experience writing parsers (who will solve it as fast as they can write/type) from those with none (who might struggle to solve it at all within a few minutes, at least without some hints).
Anyway, to allow for future more complicated requirements, there are two common approaches to parsing arithmetic expressions: recursive descent or Dijkstra's shunting-yard algorithm. You can look these up, and if you only need the simple expressions in version 1.0 then you can use a simplified form of Dijkstra's algorithm. Then once you've parsed the expression, you need to evaluate it: use values that are linear expressions in x and interpret = as an operator with lowest possible precedence that means "subtract". The result is a linear expression in x that is equal to 0.
If you don't need complicated expressions then you can evaluate that simple example pretty much directly from left-to-right once you've tokenised it[*]:
x
x + 9
// set the "we've found minus sign" bit to negate the first thing that follows
x + 7 // and clear the negative bit
x + 3
2 * x + 3
// set the "we've found the equals sign" bit to negate everything that follows
3 * x + 3
3 * x - 2
3 * x - 1
3 * x - 4
4 * x - 4
Finally, solve a * x + b = 0 as x = - b/a.
[*] example tokenisation code, in Python:
acc = None
for idx, ch in enumerate(input):
if ch in '1234567890':
if acc is None: acc = 0
acc = 10 * acc + int(ch)
continue
if acc != None:
yield acc
acc = None
if ch in '+-=x':
yield ch
elif ch == ' ':
pass
else:
raise ValueError('illegal character "%s" at %d' % (ch, idx))
Alternative example tokenisation code, also in Python, assuming there will always be spaces between tokens as in the example. This leaves token validation to the parser:
return input.split()

ok some simple psuedo code that you could use to solve this problem
function(stinrgToParse){
arrayoftokens = stringToParse.match(RegexMatching);
foreach(arrayoftokens as token)
{
//now step through the tokens and determine what they are
//and store the neccesary information.
}
//Use the above information to do the arithmetic.
//count the number of times a variable appears positive and negative
//do the arithmetic.
//add up the numbers both positive and negative.
//return the result.
}

The first thing is to parse the string, to identify the various tokens (numbers, variables and operators), so that an expression tree can be formed by giving operator proper precedences.
Regular expressions can help, but that's not the only method (grammar parsers like boost::spirit are good too, and you can even run your own: its all a "find and recourse").
The tree can then be manipulated reducing the nodes executing those operation that deals with constants and by grouping variables related operations, executing them accordingly.
This goes on recursively until you remain with a variable related node and a constant node.
At the point the solution is calculated trivially.
They are basically the same principles that leads to the production of an interpreter or a compiler.

Consider:
from operator import add, sub
def ab(expr):
a, b, op = 0, 0, add
for t in expr.split():
if t == '+': op = add
elif t == '-': op = sub
elif t == 'x': a = op(a, 1)
else : b = op(b, int(t))
return a, b
Given an expression like 1 + x - 2 - x... this converts it to a canonical form ax+b and returns a pair of coefficients (a,b).
Now, let's obtain the coefficients from both parts of the equation:
le, ri = equation.split('=')
a1, b1 = ab(le)
a2, b2 = ab(ri)
and finally solve the trivial equation a1*x + b1 = a2*x + b2:
x = (b2 - b1) / (a1 - a2)
Of course, this only solves this particular example, without operator precedence or parentheses. To support the latter you'll need a parser, presumable a recursive descent one, which would be simper to code by hand.

Related

Avoiding NANs for expressions that are partly imaginary in c++

I have an expression whose outcome is a real number, but is composed of imaginary terms (that cancel one another). A significantly more simple example than the one I am considering would be something like,
z = a + 1/[sqrt(a-b) - a] - f[sqrt(a-b)] = a
where a and b are real numbers and f is some function that statisfies the above expression. It would not surprise you that in some cases, say for b > a (which does not always occur, but could occur in some cases), the above expression returns nan, since some of its terms are imaginary.
Sometimes, it is possible to work out the algebra and write out this not-really-complex expression using real numbers only. However, in my case, the algebra is very messy (so messy that even Matlab's symbolic package and Mathematica are unable to trivially simplify).
I am wondering if there is some other way to work out expressions you know to be real, but are partly imaginary.
PS: not important for this question, but for more info about the expression I am dealing with, please see another question I previously asked.
tl;dr for the comment thread:
If you know you're doing something that will involve imaginary numbers, just use std::complex.
You can't avoid getting NaN if you insist on asking for a real result to something (sqrt, say) that you know will have an imaginary component. There is no real answer it can give you.
At the end of your computation, if imag(result) is zero (or within a suitable epsilon), then your imaginary parts cancelled out and you have a real(result).
As a concrete example:
#include <complex>
#include <iostream>
int main()
{
std::complex<double> a{-5, 0}; // -5 + 0i
std::complex<double> b{ 5, 0}; // +5 + 0i
auto z = b + sqrt(a) - sqrt(a);
std::cout << "z = " << real(z) << " + " << imag(z) << "i\n";
}
prints
z = 5 + 0i
With your new example
z = a + 1/(sqrt(a-b) - a) - f(sqrt(a-b)) = a
it'll be useful to make a of type std::complex in the first place, and to use a complex 1+0i for the numerator as well. This is because of the way overloaded operators are resolved:
using cx = std::complex<double>;
cx f(cx); // whatever this does, it also needs to handle complex inputs
cx foo(cx a, cx b)
{
return a + cx{1}/(sqrt(a-b) - a) - f(sqrt(a-b));
}
auto

How to use a string or a char vector (containing any chemical composition respectively formula) and calculate its molar mass?

I try to write a simple console application in C++ which can read any chemical formula and afterwards compute its molar mass, for example:
Na2CO3, or something like:
La0.6Sr0.4CoO3, or with brackets:
Fe(NO3)3
The problem is that I don't know in detail how I can deal with the input stream. I think that reading the input and storing it into a char vector may be in this case a better idea than utilizing a common string.
My very first idea was to check all elements (stored in a char vector), step by step: When there's no lowercase after a capital letter, then I have found e.g. an element like Carbon 'C' instead of "Co" (Cobalt) or "Cu" (Copper). Basically, I've tried with the methods isupper(...), islower(...) or isalpha(...).
// first idea, but it seems to be definitely the wrong way
// read input characters from char vector
// check if element contains only one or two letters
// ... and convert them to a string, store them into a new vector
// ... finally, compute the molar mass elsewhere
// but how to deal with the numbers... ?
for (unsigned int i = 0; i < char_vec.size()-1; i++)
{
if (islower(char_vec[i]))
{
char arr[] = { char_vec[i - 1], char_vec[i] };
string temp_arr(arr, sizeof(arr));
element.push_back(temp_arr);
}
else if (isupper(char_vec[i]) && !islower(char_vec[i+1]))
{
char arrSec[] = { char_vec[i] };
string temp_arrSec(arrSec, sizeof(arrSec));
element.push_back(temp_arrSec);
}
else if (!isalpha(char_vec[i]) || char_vec[i] == '.')
{
char arrNum[] = { char_vec[i] };
string temp_arrNum(arrNum, sizeof(arrNum));
stoechiometr_num.push_back(temp_arrNum);
}
}
I need a simple algorithm which can handle with letters and numbers. There also may be the possibility working with pointer, but currently I am not so familiar with this technique. Anyway I am open to that understanding in case someone would like to explain to me how I could use them here.
I would highly appreciate any support and of course some code snippets concerning this problem, since I am thinking for many days about it without progress… Please keep in mind that I am rather a beginner than an intermediate.
This problem is surely not for a beginner but I will try to give you some idea about how you can do that.
Assumption: I am not considering Isotopes case in which atomic mass can be different with same atomic number.
Model it to real world.
How will you solve that in real life?
Say, if I give you Chemical formula: Fe(NO3)3, What you will do is:
Convert this to something like this:
Total Mass => [1 of Fe] + [3 of NO3] => [1 of Fe] + [ 3 of [1 of N + 3 of O ] ]
=> 1 * Fe + 3 * (1 * N + 3 * O)
Then, you will search for individual masses of elements and then substitute them.
Total Mass => 1 * 56 + 3 * (1 * 14 + 3 * 16)
=> 242
Now, come to programming.
Trust me, you have to do the same in programming also.
Convert your chemical formula to the form discussed above i.e. Convert Fe(NO3)3 to Fe*1+(N*1+O*3)*3. I think this is the hardest part in this problem. But it can be done also by breaking down into steps.
Check if all the elements have number after it. If not, then add "1" after it. For example, in this case, O has a number after it which is 3. But Fe and N doesn't have it.
After this step, your formula should change to Fe1(N1O3)3.
Now, Convert each number, say num of above formula to:
*num+ If there is some element after current number.
*num If you encountered ')' or end of formula after it.
After this, your formula should change to Fe*1+(N*1+O*3)*3.
Now, your problem is to solve the above formula. There is a very easy algorithm for this. Please refer to: https://www.geeksforgeeks.org/expression-evaluation/. In your case, your operands can be either a number (say 2) or an element (say Fe). Your operators can be * and +. Parentheses can also be present.
For finding individual masses, you may maintain a std::map<std::string, int> containing element name as key and its mass as value.
Hope this helps a bit.

How to check if a number is an integer in Pari/GP?

I'm trying to write an if statement like this
if(denominator([(i-1)! + 1] / i)-1,print(hi),print(ho))
i can be any integer, for example 10. When I set i to 10 it gives this error:
? [(x-1)! + 1] / x
*** this should be an integer: [(x-1)!+1]/x
^-----------
I really only need to check if [(x-1)! + 1] / x is an integer or not. The denominator thing is what I came up with, I also tried Mod but couldn't get that working either.
It seems that you are confused with the names x and i.
Please, see that expression below works properly:
i = 10;
print([(i-1)! + 1] / i);
gp > [362881/10]
I'm not sure what the error was but I ended up using a floor function for determining if it was an integer or not.
You could use:
print(if(((i-1)! + 1) % i, "hi", "ho"))
If i (in your question x) is not an integer, you get an error from the ! (factorial) operator (but see gamma as well).
Do not use [] here, it creates a vector.
The opreator % which I used, gives the remainder. For example 11 % 4 gives the integer 3. In comparison Mod(11, 4) is not an ordinary integer, it is a member of the ring Z/4Z (integers modulo 4). That is very useful in many cases.
I supposed you wanted to write out strings, so I used quotes ". If hi and ho are variables, omit the quotes of course.

Evaluate String "1+2^4*4*(4+4*9)-10"

I'm trying to evaluate this string. "1+2^4*4*(4+4*9)-10"
My strategy is to take each element, put it in a list, convert to the correct data type (int) or operator, concatenate and then evaluate. I'm trying to avoid using eval() and ast.literal_eval() was throwing a "malformed string error." I'm currently stuck at the point where I need to convert my operators from strings into operators.
Here's what I've done so far:
equation = ("1+2^4*4*(4+4*9)-10")
listint1 = 0
listint2 = 1
finallist = []
for elements in equation:
finallist.append(equation[listint1:listint2])
listint1 = listint1 + 1
listint2 = listint2 + 1
finalfinallist = []
for element in finallist:
if element.isdigit() == True:
finalfinallist.append(int(element))
else:
finalfinallist.append(element)
for element in finalfinallist:
if element == str:
if element == "+":
element = +
elif element == "^":
element = ^
elif element == "*":
element = *
elif element == "("
element = (
elif element == ")":
element = )
elif element == "-"
element = -
print finalfinallist
Thoughts?
What you are trying to build is a parser. You can have a look at https://en.wikipedia.org/wiki/Comparison_of_parser_generators. Parsers are used to implement context free grammars, see https://en.wikipedia.org/wiki/Context-free_grammar
I assume that by 2^4you mean exponentiation, and not bitwise-xor (as per python operators).
There may be an ambiguity when trying to parse 2^4*4, as it may be (2^4)*4 = 16 * 4 = 64, or 2^(4*4) = 2^16 = 65536. I do not know ast, but try looking at "associativity rules".
You'd probably want to start with building an expression tree, for this kind of thing!
Wikipedia: Expression Trees
This would make handling the operators somewhat easier, this way you'll know when to expect an operator, and can do a string comparison to determine what operator to use on the operands in the expression tree!
Bear in mind, I've never had to do this in Python, only in C. So if there's a more Pythonic way to do this, I'm currently unaware, and would love to hear it.

Understanding (and forming) the regular expression of this finite automaton

For the above automaton, the regular expression that has been given in my textbook is the following :
a*(a*ba*ba*ba*)*(a+a*ba*ba*ba*)
I am having trouble deriving this...the following is my attempt at it :
aa* + aa*(ba*ba*ba*)* + ba*ba*ba* + ba*ba*ba*(ba*ba*ba*)*
Either I am wrong or I am not being able to simplify it into the form given in the book. Can someone please guide me here, point out the mistake or explain it to me step-by-step?
I'd really really thankful and appreciate that.
Check this out. It presents three good, algorithmic methods for answering questions like these. Learn one of them, or all three of them if you have the time or inclination. State removal is fairly intuitive, although I like Kleene's transitive closure method.
http://krchowdhary.com/toc/dfa-to-reg-exp.pdf
EDIT: Your RE is equivalent to the one provided. here's the reduction of theirs to yours:
0. a*(a*ba*ba*ba*)*(a+a*ba*ba*ba*)
1. = a*(a*ba*ba*ba*)*a + a*(a*ba*ba*ba*)*a*ba*ba*ba*
2. = a*(ba*ba*ba*)*a + a*(ba*ba*ba*)*ba*ba*ba*
3. = a*a + a*(ba*ba*ba*)*a + a*(ba*ba*ba*)*ba*ba*ba*
4. = aa* + a*(ba*ba*ba*)*ba*ba*ba*a + a*(ba*ba*ba*)*ba*ba*ba*
5. = aa* + a*(ba*ba*ba*)*ba*ba*ba*
6. = aa* + aa*(ba*ba*ba*)*ba*ba*ba* + (ba*ba*ba*)*ba*ba*ba*
7. = aa* + aa*(ba*ba*ba*)* + (ba*ba*ba*)*ba*ba*ba*
8. = aa* + aa*(ba*ba*ba*)* + ba*ba*ba* + (ba*ba*ba*)*ba*ba*ba*
9. = aa* + aa*(ba*ba*ba*)* + ba*ba*ba* + ba*ba*ba*(ba*ba*ba*)*
Step 1 is right since r(s+t) = rs + rt.
Step 2 is right since r*(r*sr*)* = r*(sr*)*.
Step 3 is right since r = r + s if L(s) is a subset of L(r).
Step 4 is right since r*r = rr* and rs + rq*s = rs + rqq*s.
Step 5 is right since rs + r = r.
Step 6 is right since r*s = rr*s + s.
Step 7 is right since rs + rqq*s = rs + rq*s.
Step 8 is right since r = r + s if L(s) is a subset of L(r).
Step 9 is right since r*r = rr*.
Please feel free to ask any questions or point out any mistakes I may have made.
EDIT2: If you are interested in these kinds of questions, show some love for the new Computer Science StackExchange by going to this link and committing!!!
http://area51.stackexchange.com/proposals/35636/computer-science-non-programming?referrer=rpnXA1_2BNYzXN85c5ibxQ2
The textbook seems correct. Taking it step by step:
a*(a*
If this part of the regular expression is true (in other words you do actually read in an 'a'), you will move to state 3. Following the rest of the expression:
ba*
will have you in state 2,
ba*
in state 4 and
ba*
will have you back in state 3.
Now, suppose that you did not read in an 'a' during a*(a*, reading the next b will move you to state 2. You then end up in exactly the same situation as previously, and by following the rest a*ba*ba*) you end up back in state 3.
Since you are now back in state 3, the part (a*ba*ba*ba*)* can execute as many times as it wants, as this will simply be the same as our first scenario (where you read in an 'a' during a*(a*).
The second part simply explains the first scenario again, where you have to read at least one 'a', and then the rest is the same.
Hope this helps, let me know if it still does not make sense. Don't know if my explanation is too clear.