Multi-operator calculator in C++?

Status
Not open for further replies.

lordjox

Solid State Member
Messages
8
Hi I need to write a multi-operator calculator in c++. For example,
input: 57+72-4%19=
output: 125
or
input: 125%20*3-6+82=
output: 91

There's no limit to the number of operators used (though I doubt more than 8 would be used. The only operators that this calculator needs to be able to handle is +,-,*, and %. Exponents, division, and parenthesis are not used and only integers will be entered in (no floats or doubles.) Anyway, I got it to where I get an array to read in all the numbers and another array that reads in all the operators. For example the arrays for the above problem are:
num[0]=125
oper[0]='%'
num[1]=20
oper[1]='*'
etc...

My only problem is taking the stored integers and operators and actually calculating it the value. I could use a bunch of if statements but that would take forever and would be a pain in the ass to debug. Thanx in advance :)
 
basically what you need to do is write two classes, one for analyzing the input statement, re-write the statement in the order that easier for evaluation, save the values during the process on a mocked stack created by the second class. Then use a series of loops to evaluate. It's pretty much like how CPU does calculations. I have a sample code in VB, it's long but if you run it line after line in debug mode, you'll find out how it works.
 

Attachments

  • eval.zip
    13.8 KB · Views: 67
Thanks for the response. I haven't learned about classes yet (I am still a begginer at this) but you gave me an idea on how to do it with a bunch of for loops. Hopefully it will works.
 
Here's a C# version. It wouldn't be hard at all to translate into C++ code.
I haven't run it yet, so there may be some index out of bounds crap to deal with. But those are easy to fix. Keep in mind this was just something I threw together really fast, and didn't spend a whole lot of time on it. :)

EDIT: See below code
 
Ok, I appologize for anyone that tried to use my code. It sucked :p
I got home and tested it and was horrified to see what I had written. I don't know what I was thinking. Here is a better version, may still have a few bugs, because I haven't tested a ton of calculations, but it's MUCH better than the previous one. Also I haven't updated the comments, so I'll edit this post once I do...enjoy
Code:
public static void Main(string[] args)
{
	//
	// First we will get the calculation to be done. Then we will set up some
	// of the variables we are going to need.
	//
	Console.WriteLine("Welcome to the Console Caclulator");
	Console.WriteLine("---------------------------------");
	Console.WriteLine("Valid Operators:");
	Console.WriteLine("\t\t1. *");
	Console.WriteLine("\t\t2. +");
	Console.WriteLine("\t\t3. -");
	Console.WriteLine("\t\t4. %");
	Console.WriteLine("---------------------------------");
	Console.Write("Enter a calculation: ");
	string totCalc = Console.ReadLine();
	
	string currCalc = "";  			// Holds the current calculation or part of one
						// that we are working on

	char[] legalOps = {'*','+','-','%'};	// Holds all the legal operators
	
	int i;					// The iterator variable. The reason it is
						// is created outside of the loop is because
						// we need to access it later on in the
						// method

	int opPos = -1;				// The index of the operator		
	string tempCalc;			// The portions of the total calculation
	int fOpBack;				// The First Operator index back from the
						// the current operator index
		
	int fOpFore;				// Same as above, only foreward
	int n1,n2;				// The two numbers on either side of						
						// the operator (i.e. n1 + n2)

	int ans;				// The ingteger form of the answer
	int len;				// the length of one index to the next

	//
	// A potentially infinite loop. We will break out of it when we are done
	//
	while(true)
	{	
		//
		// We reset the operator position every go around, so we don't bring in
		// baggage from our last go around
		//
		opPos = -1;
		for( i = 0; opPos == -1; i ++) 
		{	
			//
			// Now we are just iterating over the array trying
			// to see if it contains one of our legal operators.
			// If it does, or if we try them all (meaning we are
			// done), we end the loop.
			//

			// if we have gone through all the legal ops, we break out of
			// the loop. This means we are done with our calculation
			if(i > (legalOps.Length - 1))
			{
				i = -1;
				break;
			}
			opPos = totCalc.IndexOf(legalOps[i]);
			
			//
			// Here we are just checking to see if we have a negative number
			// or the minus operator. If it's a negative operator, then we
			// we ignore it, if it's a minus operator then we pay attention
			// to it. The way we tell the differences is to check the previous
			// character. A subtraction operator will have a digit before it,
			// a negative operator will have another operator before it.
			//
			if(opPos != -1)
				if((legalOps[i] == '-') && (!Char.IsDigit(totCalc[opPos - 1])))
					opPos = -1;
		}
		// if we are done with the calculation...break out of the loop 
		if(i == -1)
			break;
		
		//
		// The way we are going to do this is to spit the calculation into
		// parts. And calculate each one separatly, then replace that part
		// part of the full calculation with our answer.
		// example:
		// If we have the calculation 20+30*8%3 and we are on the * operator
		// we only need the 30*8 part of the calculation. So we will get
		// value, then get the two numbers from that (remember n1 and n2)
		// which in our example are 30 and 8 respectivly. Then we will do
		// the actual calculation (30*8) which ends up being 240. Then 
		// we will replace the 30*8 portion of our total calculation with
		// the result. So the end result will look like 20+240%8 and we 
		// will start it all over again.
		//

		//				
		// we are getting the first half of the calculation
		// if you recall our example, the result of this operations would
		// look like 20+30*
		//
		tempCalc = totCalc.Substring(0,opPos); 
		
		//
		// Now we are getting the index of the + in our calculation because
		// it's the begining of the part we are interested in (30*) In a 
		// longer calculation it may have been several operators later
		//
		fOpBack = tempCalc.LastIndexOfAny(legalOps);

		//
		// Now we are getting the index of the modulos in our calculation
		// because it is the end of the portion we are interested in (*8)
		// but first we need to check if we have a negative operator or a 
		// subtraction operator. we could have done this with a bool var,
		// but I haven't changed it yet. 
		//
		//
		// [ TODO: Change to a bool operation ]
		//
		if(Char.IsDigit(totCalc[opPos + 1]))
			fOpFore = totCalc.IndexOfAny(legalOps,opPos + 1);
		else
			fOpFore = totCalc.IndexOfAny(legalOps,opPos + 2);
		

		//
		// We are checking to see if this is the last operator in our full 
		// calculation. If it is, we need to do a different method of findign
		// the last part
		//	
		if(fOpFore != -1)
			currCalc = totCalc.Substring(fOpBack + 1, fOpFore - (fOpBack + 1));
		else
			currCalc = totCalc.Substring(fOpBack + 1);
		
		
		//
		// Again, if it's a negative number, it changes how we do things.
		//
		len = currCalc.IndexOfAny(legalOps);
		if(len == 0)
			len = currCalc.IndexOfAny(legalOps,1);
		if(len != -1)
			n1 = Int32.Parse(currCalc.Substring(0,len));
		else
			n1 = Int32.Parse(currCalc.Substring(0));
		n2 = Int32.Parse(currCalc.Substring(len + 1));
		ans = 0;
		
		//
		// this is where we actually perform the calculation (or the part
		// we are currently working on)
		//
		switch(legalOps[i-1])
		{
			case '*':
				ans = n1 * n2;
				break;
			case '+':
				ans = n1 + n2;
				break;
			case '-':
				ans = n1 - n2;
				break;
			case '%':
				ans = n1 % n2;
				break;
		} 

		//
		// we are now just getting ready to re-enter the result of our calculation
		// back into total calculation to start all over again
		//
		tempCalc = ans.ToString();
	
		//
		// this is where we actually replace the 30*8 with 240 so that we
		// can start this whole thing over again.
		//
		totCalc = totCalc.Replace(currCalc,tempCalc);
	}	
	// output the result
	Console.Write("Result: " + totCalc);
	Console.WriteLine("\nPress enter to continue");
	// Just waiting so the user has time to read the results.
	Console.ReadLine();
}

EDIT: I just fixed some bugs in it (like when part of the equation equals a negative number. And a few other things. So far everything is working greate, I just need to update the comments. I'll probably do that tomorrow.

EDIT: I fixed some of the code (not much) and I redid some of the comments. Still need to do more though
 
i don't know code but would i just copy and paste that in notepad and it would work, i'm confused. ne help???
 
Status
Not open for further replies.
Back
Top Bottom