I'm relatively new to programming, and I'm currently working on a C# string based calculator. A lot of it works fine already, but I'm having problems with negative coefficients. My calculator engine always looks for the next operator and calculates accordingly, so the problem is that if I want to calculate "-5+6", the first operation is "-5", but it obviously can't be calculated. How can I separate operator and coefficient?
What I've come up with so far (small extract of the whole code)
if (nextOperation.Contains("+"))
{
string firstOperationResult = Calculate(nextOperation.Split('+').ToList(), "+")[0];
string partialFormulaReplacement = partialFormula.Replace(nextOperation, firstOperationResult);
return CalculateDashOperation(partialFormulaReplacement);
}
else if (nextOperation.Contains("-") && nextOperation.IndexOf("-") > 0)
{
string resultOfFirstOperation = Calculate(nextOperation.Split('-').ToList(), "-")[0];
string partialFormulaReplacement = partialFormula.Replace(nextOperation, resultOfFirstOperation);
return CalculateDashOperation(partialFormulaReplacement);
}
//added
else if (nextOperation.Contains("-") && nextOperation.IndexOf("-") == 0)
{
//what to do
}
//added
return partialFormula;
"-5" can be treated as meaning "0-5", so you could say there's an implicit zero if you see an operand in the first position of the string. Note that this approach will only work for the operators + and -.
As for the problem of attempting to calculate "-5" again, I suggest you use the 0 as an argument to your Calculate function, rather than prepending it to the string you're processing:
Calculate(new List<string>{"0", nextOperation[1]}, "-")
Also, as has been pointed out in the comments, this approach will not cover all possible cases, and if this isn't an academic exercise then there are solutions out there that already solve this problem.
The sample code looks a little short. But let's try to suggest:
nextOperation is a string containing something like "1 * -6 + 6"
In order to evaluate this expression yout have to 'encrypt' your string first.
The topic you are looking for is parenthesis
A nice explanation of the basic (in python) can be found here.
But this question is already answered here.
Use NCalc Library:
Dont reinvent wheel, * and / priorities is already implemented.
Simple expressions
Expression e = new Expression("2 + 3 * 5");
Debug.Assert(17 == e.Evaluate());
Handles mathematical functional from System.Math
Debug.Assert(0 == new Expression("Sin(0)").Evaluate());
Debug.Assert(2 == new Expression("Sqrt(4)").Evaluate());
Debug.Assert(0 == new Expression("Tan(0)").Evaluate());
Related
Lets say i have
int a = 1;
int b = 2;
string exp = "b > a";
and i want to evaluate the string expression with those variables
if(exp.SomeKindOfParseOrCast())
{
//here be magic
}
Is it possible in any simple way?
Nope, not in C# - these are parameter names, and thus are compile time values, and this expression parsing you are describing is done in runtime - the computer doesn't know the name of the parameters while it's being evaluated. Instead, you could do something a little more strict, like an expression parser - implement your own way to parse string expressions.
Very very simplified:
if(exp.Equals("b > a"))
{
if(b>a)
// do what you do if b is bigger than a
else
// do what you do with a wrong expression
}
else if (exp.Equals("a > b")
{
if(a>b)
// do what you do if a is bigger than b
else
// do what you do with a wrong expression
}
else if (exp.Equals("a = b")
{
if(a==b)
// do what you do if a is equal to b
else
// do what you do with a wrong expression
}
else
// do what you do with a badly formatted expression
if you would like to take this a step forward, you can cut spaces, make sure the expression is lowercase, etc. - there's many examples around, I personally like this one.
Is it possible in any simple way?
No, in C# this is not possible in a simple way like it were in languages such as JavaScript with its eval function. Anyway, you'd have to provide bindings of in-expression parameters to actual values.
You can use Roslyn.
Here is an example of how to compile and run your own code in runtime.
Disclaimer: I'm the owner of the project Eval Expression.NET
This library is very easy to use and allow to evaluate and compile almost all the C# language.
// For single evaluation
var value1 = Eval.Execute<bool>("b > a", new { a = 1, b = 2 });
// For many evaluation
var compiled = Eval.Compile<Func<int, int, bool>>("b > a", "a", "b");
var value2 = compiled(1, 2);
I am converting code from Java to C#, but having issues figuring out some keyword equivalence. I have looked over the web and can't find anything. Updated added number 3.
1) Does anyone know what C# uses for charAt()? Below is how I am trying to use it.
curr = tokens[i].charAt(0);
2) Also having issues converting isEmpty() to C# syntax.
if (par.isEmpty())
3) How should I convert this:
op2 = compute.pop().intValue();
Thanks!
1) Strings can have their characters accessed by using the [] operator:
curr = (tokens[i])[0];
2) IsEmpty becomes String.IsNullOrEmpty or String.IsNullOrWhiteSpace depending on what you want (the second is only available in .NET 4+ as well).
3) From what research I could find, it looks like intValue deals with boxing/unboxing. If you stick with working with ints, you shouldn't need to worry about that in C#. "Pop" will work the same if you have a Stack collection. Hopefully that gives you enough to convert the line.
1) In C# a string is also an array of characters.So you can access a character using the indexer:
curr = tokens[i][0]
2) You can compare your string with string.Empty or use String.IsNullOrEmpty method to check whether a string is empty or not:
if( par == string.Empty )
OR:
if( string.IsNullOrEmpty(par) );
Assuming tokens[i] is a string, treat the string as an array of characters:
var firstCharacter = tokens[i][0];
Assuming par is also a string, the string.IsNullOrEmpty() method can help you test whether or not a particular string is empty:
if (string.IsNullOrEmpty(par))
{
}
If par is a Stack<String> as you've indicated, then you could test whether it was empty (has no elements) with a simple bit of LINQ:
if (!par.Any())
{
// par has no elements
}
Alternatively, you could use the Count property in the Stack class:
if (par.Count == 0)
{
// par has no elements
}
A different approach:
1) You can use curr = tokens[i].ElementAt(0); This will return the same result as charAt(0)
2) if( string.IsNullOrEmpty(par) ); will do the job.
This question already has answers here:
Is there a string math evaluator in .NET?
(18 answers)
Closed 9 years ago.
I have a string of the following type:
"23 + 323 =" or "243 - 3 ="
So the format is: number + operator + number = equal.
And I also have an int which is the answer to that question.
How can I parse the string and check if the answer is correct?
Thank You,
Miguel
Maybe using regular expressions you can do something like...
String sExpression = "23 + 323 =";
int nResult = 0;
Match oMatch = Regex.Match(#"(\d+)\s*([+-*/])\s*(\d+)(\s*=)?")
if(oMatch.Success)
{
int a = Convert.ToInt32(oMatch.Groups[1].Value);
int b = Convert.ToInt32(oMatch.Groups[3].Value);
switch(oMatch.Groups[2].Value)
{
case '+';
nResult = a + b;
break;
case '-';
nResult = a - b;
break;
case '*';
nResult = a * b;
break;
case '/';
nResult = a / b;
break;
}
}
and extend to your need.. (floats, other operators, validations, etc)
You want to split on equals then split on the operator. Then you can use some standard string processing techniques to do the operation and check it against the answer. There are probably far more efficient and/or cleaner solutions than this, this is simply the first one at my fingertips and since you didn't post any code it is what you get. Note that this also is not flexible. It only works when there are two operands and with the four primary arithmetic operators. Unless there's some requirement saying you don't use third party libraries I'd recommend using something like what's linked to in the comments. If you need to implement this in a more general sense (works with multiple operations like (x + y - z) * x ) then you have a lot more work cut out for you.
string input = "23 + 323 = 346";
string[] sides = input.Split('=');
string[] operands;
int answer = 0;
if (sides.Length == 2)
{
if (sides[0].Contains('+'))
{
operands = sides[0].Split('+');
operands[0].Trim();
operands[1].Trim();
answer = int.Parse(operands[0]) + int.Parse(operands[1]);
// note if you're serious about error handling use tryparse to ensure the values are integers
if (answer != int.Parse(sides[1].Trim()))
// answer is wrong
}
else if (sides[0].Contains('-'))
{
// same logic
}
}
else
//input formatting error
As all of the comments to your question indicate, you need some kind of tokenizer, expression parser, and expression evaluator.
The tokenizer splits the source string into separate tokens, like numbers and operators.
The expression parser scans and syntactically parses the sequence of tokens, recognizing expressions and building some kind of parse tree (i.e., an abstract expression tree).
The expression evaluator then walks the nodes of the resulting expression tree, evaluating the binary and unary subexpressions. The result is the evaluation of the top-most node in the tree.
This is all quite a complex set of things to do, so (like the other comments state), you should try to find a library that someone has already written to do all this for you.
Actually it is not that different from parsing single arithmetic expression. Here you simply evaluate two of them (on both sides of equal sign) and then check the outcome.
Well, you can go "crazy", and parse not only = but >, >= too, which will give you more flexibility.
Because in arithmetic expression parenthesis should be legal (common sense), for example (5+2)*3 you should avoid struggle with regexes and alike approaches and go with parser.
Pick one you feel comfortable with, GOLD, ANTLR, Cocoa. My own parser (generator) -- NLT -- contains already arithmetic expression example. Add single rule for checking equality and you are ready to go.
Please note, the 'C#' tag was included intentionally, because I could accept C# syntax for my answer here, as I have the option of doing this both client-side and server-side. Read the 'Things You May Want To Know' section below. Also, the 'regex' tag was included because there is a strong possibility that the use of regular expressions is the best approach to this problem.
I have the following highlight Plug-In found here:
http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
And here is the code in that plug-in:
/*
highlight v4
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb#eaio.com>
*/
jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
return this.length && pat && pat.length ? this.each(function() {
innerHighlight(this, pat.toUpperCase());
}) : this;
};
jQuery.fn.removeHighlight = function() {
return this.find("span.highlight").each(function() {
this.parentNode.firstChild.nodeName;
with (this.parentNode) {
replaceChild(this.firstChild, this);
normalize();
}
}).end();
};
This plug-in works pretty easily.
If I wanted to highlight all instances of the word "Farm" within the following element...(cont.)
<div id="#myDiv">Farmers farm at Farmer's Market</div>
...(cont.) all I would need to do is use:
$("#myDiv").highlight("farm");
And then it would highlight the first four characters in "Farmers" and "Farmer's", as well as the entire word "farm" within the div#myDiv
No problem there, but I would like it to use this:
$("#myDiv").highlight("Farmers");
And have it highlight both "Farmers" AND "Farmer's". The problem is, of course, that I don't know the value of the search term (The term "Farmers" in this example) at runtime. So I would need to detect all possibilities of no more than one apostrophe at each index of the string. For instance, if I called $("#myDiv").highlight("Farmers"); like in my code example above, I would also need to highlight each instance of the original string, plus:
'Farmers
F'armers
Fa'rmers
Far'mers
Farm'ers
Farme'rs
Farmer's
Farmers'
Instances where two or more apostrophes are found sid-by-side, like "Fa''rmers" should, of course, not be highlighted.
I suppose it would be nice if I could include (to be highlighted) words like "Fa'rmer's", but I won't push my luck, and I would be doing well just to get matches like those found in my bulleted list above, where only one apostrophe appears in the string, at all.
I thought about regex, but I don't know the syntax that well, not to mention that I don't think I could do anything with a true/false return value.
Is there anyway to accomplish what I need here?
Things You May Want To Know:
The highlight plug-in takes care of all the case insensitive requirements I need, so no need to worry about that, at all.
Syntax provided in JavaScript, jQuery, or even C# is acceptable, considering the hidden input fields I use the values from, client-side, are populated, server-side, with my C# code.
The C# code that populates the hidden input fields uses Razor (i.e., I am in a C#.Net Web-Pages w/ WebMatrix environment. This code is very simple, however, and looks like this:
for (var n = 0; n < searchTermsArray.Length; n++)
{
<input class="highlightTerm" type="hidden" value="#searchTermsArray[n]" />
}
I'm copying this answer from your earlier question.
I think after reading the comments on the other answers, I've figured out what it is you're going for. You don't need a single regex that can do this for any possible input, you already have input, and you need to build a regex that matches it and its variations. What you need to do is this. To be clear, since you misinterpreted in your question, the following syntax is actually in JavaScript.
var re = new RegExp("'?" + "farmers".split("").join("'?") + "'?", "i")
What this does is take your input string, "farmers" and split it into a list of the individual characters.
"farmers".split("") == [ 'f', 'a', 'r', 'm', 'e', 'r', 's' ]
It then stitches the characters back together again with "'?" between them. In a regular expression, this means that the ' character will be optional. I add the same particle to the beginning and end of the expression to match at the beginning and end of the string as well.
This will create a regex that matches in the way you're describing, provided it's OK that it also matches the original string.
In this case, the above line builds this regex:
/'?f'?a'?r'?m'?e'?r'?s'?/
EDIT
After looking at this a bit, and the function you're using, I think your best bet will be to modify the highlight function to use a regex instead of a straight string replacement. I don't think it'll even be that hard to deal with. Here's a completely untested stab at it.
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var matchResult = pat.exec(node.data); // exec the regex instead of toUpperCase-ing the string
var pos = matchResult !== null ? matchResult.index : -1; // index is the location of where the matching text is found
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(matchResult[0].length); // matchResult[0] is the last matching characters.
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
What I'm attempting to do here is keep the existing logic, but use the Regex that I built to do the finding and splitting of the string. Note that I'm not doing the toUpper call anymore, but that I've made the regex case insensitive instead. As noted, I didn't test this at all, but it seems like it should be pretty close to a working solution. Enough to get you started anyway.
Note that this won't get you your hidden fields. I'm not sure what you need those for, but this will (if it's right) take care of highlighting the string.
Last night I was messing around with Piglatin using Arrays and found out I could not reverse the process. How would I shift the phrase and take out the Char's "a" and "y" at the end of the word and return the original word in the phrase.
For instance if I entered "piggy" it would come out as "iggypay" shifting the word piggy so "p" is at the end of the word and "ay" is appended.
Here is the example code so you can try it as well.
public string ay;
public string PigLatin(string phrase)
{
string[] pLatin;
ArrayList pLatinPhrase = new ArrayList();
int wordLength;
pLatin = phrase.Split();
foreach (string pl in pLatin)
{
wordLength = pl.Length;
pLatinPhrase.Add(pl.Substring(1, wordLength - 1) + pl.Substring(0, 1) + "ay");
}
foreach (string p in pLatinPhrase)
{
ay += p;
}
return ay;
}
You will notice that is example is not programmed to find vowels and append them to the end along with "ay". Just simply a basic way of doing it.
If you where wondering how to reverse the above try this example of uPiglatinify
public string way;
public string uPigLatinify(string word)
{
string[] latin;
int wordLength;
// Using arrraylist to store split words.
ArrayList Phrase = new ArrayList();
// Split string phrase into words.
latin = word.Split(' ');
foreach (string i in latin)
{
wordLength = i.Length;
if (wordLength > 0)
{
// Grab 3rd letter from the end of word and append to front
// of word chopping off "ay" as it was not included in the indexing.
Phrase.Add(i.Substring(wordLength - 3, 1) + i.Substring(0, wordLength - 3) + " ");
}
}
foreach (string _word in Phrase)
{
// Add words to string and return.
way += _word;
}
return way;
}
Please don’t take this the wrong way, but although you can probably get people here to give you the C# code to implement the algorithm you want, I suspect this is not enough if you want to learn how it works. To learn the basics of programming, there are some good tutorials to delve into (whether websites or books). In particular, if you aspire to be a programmer, you will need to learn not just how to write code. In your example:
You should first write a specification of what your PigLatin function is supposed to do. Think about all the corner-cases: What if the first letter is a vowel? What if there are several consonants at the beginning? What if there are only consonants? What if the input starts with a number, a parenthesis, or a space? What if the input string is empty? Write down exactly what should happen in all of these cases — even if it’s “throw an exception”.
Only then can you implement the algorithm according to the specification (i.e. write the actual C# code). While doing this, you may find that the specification is incomplete, in which case you need to go back and correct it.
Once your code is finished, you need to test it. Run it on several testcases, especially the corner-cases you came up with above: For example, try PigLatin("air"), PigLatin("x"), PigLatin("1"), PigLatin(""), etc. In each case, make yourself aware first what behaviour you expect, and then see if the behaviour matches your expectation. If it doesn’t, you need to go back and fix the code.
Once you have implemented the forward PigLatin algorithm and it works (read: passes all your testcases), then you will already have the skills needed to write the reverse function youself. I guarantee you that you will feel achieved and excited then! Whereas, if you just copy the code from this website, you are setting yourself up for feeling dumb because you will think other people can do it and you can’t.
Of course, we are nonetheless happy to help you with specific technical questions, for example “What is the difference between ArrayList and List<string>?” or “What does the scope of a local variable mean?” (but search first — these may have already been asked before) — but you probably shouldn’t ask to have the code fully written and finished for you.
The work to split the phrase into words and recombine the words after transforming them is the same as in the original case. The difficulty is in un-pig-latin-ifying an individual word. With some error checking, I imagine you could do this:
string UnPigLatinify(string word)
{
if ((word == null) || !Regex.IsMatch(word, #"^\w+ay$", RegexOptions.IgnoreCase))
return word;
return word[word.Length - 3] + word.Substring(0, word.Length - 3);
}
The regular expression just checks to make sure the word is at least 3 letters long, composed of characters, and ends with "ay".
The actual transform takes the third to last letter (the original first letter) and appends the rest of the word minus the "ay" and the original letter.
Is this what you meant?