當前位置:編程學習大全網 - 編程語言 - 設計壹數據結構可存儲四則混合運算表達式

設計壹數據結構可存儲四則混合運算表達式

// Soln6_5ANSI.cpp

// A program to implement a calculator accepting parentheses

#include <iostream> // For stream input/output

#include <cstdlib> // For the exit() function

#include <cctype> // For the isdigit() function

#include <cstring> // For the strcpy() function

#include <cmath> // For the pow() function

using std::cin;

using std::cout;

using std::endl;

void eatspaces(char* str); // Function to eliminate blanks

double expr(char* str); // Function evaluating an expression

double term(char* str, int& index); // Function analyzing a term

double number(char* str, int& index); // Function to recognize a number

char* extract(char* str, int& index); // Function to extract a substring

void error(char* str, int index); // Function to identify an error

double doOperation(char* op, double value); // Execute math function

const int MAX = 80; // Maximum expression length,including '\0'

const double degToRad = 57.295779; // Conversion factor, degrees to radians

int main()

{

char buffer[MAX] = {0}; // Input area for expression to be evaluated

cout << endl

<< "Welcome to your friendly calculator."

<< endl

<< "Enter an expression, or an empty line to quit."

<< endl;

for(;;)

{

cin.getline(buffer, sizeof buffer); // Read an input line

eatspaces(buffer); // Remove blanks from input

if(!buffer[0]) // Empty line ends calculator

return 0;

cout << "\t= " << expr(buffer) // Output value of expression

<< endl << endl;

}

}

// Function to eliminate spaces from a string

void eatspaces(char* str)

{

int i = 0; // 'Copy to' index to string

int j = 0; // 'Copy from' index to string

while((*(str + i) = *(str + j++)) != '\0') // Loop while character

// copied is not \0

if(*(str + i) != ' ') // Increment i as long as

i++; // character is not a space

return;

}

// Function to evaluate an arithmetic expression

double expr(char* str)

{

double value = 0.0; // Store result here

int index = 0; // Keeps track of current character position

value = term(str, index); // Get first term

for(;;) // Indefinite loop, all exits inside

{

switch(*(str + index++)) // Choose action based on current character

{

case '\0': // We're at the end of the string

return value; // so return what we have got

case '+': // + found so add in the

value += term(str, index); // next term

break;

case '-': // - found so subtract

value -= term(str, index); // the next term

break;

default: // If we reach here the string

cout << endl // is junk

<< "Arrrgh!*#!! There's an error"

<< endl;

error(str, index-1);

exit(1);

}

}

}

// Function to get the value of a term

double term(char* str, int& index)

{

double value = 0.0; // Somewhere to accumulate

// the result

value = number(str, index); // Get the first number in the term

// Loop as long as we have a good operator

while((*(str + index) == '*') || (*(str + index) == '/') || (*(str + index) == '^'))

{

if(*(str + index) == '*') // If it's multiply,

value *= number(str, ++index); // multiply by next number

if(*(str + index) == '/') // If it's divide,

value /= number(str, ++index); // divide by next number

if(*(str + index)=='^')

value = pow(value, number(str, ++index));

}

return value; // We've finished, so return what

// we've got

}

// Function to recognize a number in a string

double number(char* str, int& index)

{

double value = 0.0; // Store the resulting value

// Look for a math function name

char op[6];

int ip = 0;

while (isalpha(*(str+index))) // Copy the function name

op[ip++] = *(str+index++);

op[ip] = '\0'; // Append terminator

if(*(str + index) == '(') // Start of parentheses

{

char* psubstr = 0; // Pointer for substring

psubstr = extract(str, ++index); // Extract substring in brackets

value = expr(psubstr); // Get the value of the substring

// If we have a math operation saved, go and do it

if(op[0])

value = doOperation(op, value);

delete[]psubstr; // Clean up the free store

return value; // Return substring value

}

while(isdigit(*(str + index))) // Loop accumulating leading digits

value = 10*value + (*(str + index++) - '0');

// Not a digit when we get to here

if(*(str + index) != '.') // so check for decimal point

return value; // and if not, return value

double factor = 1.0; // Factor for decimal places

while(isdigit(*(str + (++index)))) // Loop as long as we have digits

{

factor *= 0.1; // Decrease factor by factor of 10

value = value + (*(str + index) - '0')*factor; // Add decimal place

}

return value; // On loop exit we are done

}

// Function to extract a substring between parentheses

// (requires cstring)

char* extract(char* str, int& index)

{

char buffer[MAX]; // Temporary space for substring

char* pstr = 0; // Pointer to new string for return

int numL = 0; // Count of left parentheses found

int bufindex = index; // Save starting value for index

do

{

buffer[index - bufindex] = *(str + index);

switch(buffer[index - bufindex])

{

case ')':

if(numL == 0)

{

size_t size = index - bufindex;

buffer[index - bufindex] = '\0'; // Replace ')' with '\0'

++index;

pstr = new char[index - bufindex];

if(!pstr)

{

cout << "Memory allocation failed,"

<< " program terminated.";

exit(1);

}

strcpy_s(pstr, index-bufindex, buffer); // Copy substring to new memory

return pstr; // Return substring in new memory

}

else

numL--; // Reduce count of '(' to be matched

break;

case '(':

numL++; // Increase count of '(' to be

// matched

break;

}

} while(*(str + index++) != '\0'); // Loop - don't overrun end of string

cout << "Ran off the end of the expression, must be bad input."

<< endl;

exit(1);

return pstr;

}

// Function to identify an error

void error(char* str, int index)

{

cout << str << endl;

for (int i=0; i<index; i++)

cout << ' ';

cout << '^' << endl;

}

// Execute math function

double doOperation(char* op, double value)

{

if (!_stricmp(op, "sin"))

return sin(value);

else if (!_stricmp(op, "sind"))

return sin(value/degToRad);

else if (!_stricmp(op, "cos"))

return cos(value);

else if (!_stricmp(op, "cosd"))

return cos(value/degToRad);

else if (!_stricmp(op, "tan"))

return tan(value);

else if (!_stricmp(op, "tand"))

return tan(value/degToRad);

else if (!_stricmp(op, "sqrt"))

return sqrt(value);

else

{

cout << "Error: unknown operation '" << op << "'" << endl;

exit(1);

}

return 0;

}

  • 上一篇:小米手機無法開機,米兔修理屏幕上的機器人。發生了什麽事?
  • 下一篇:面向切面編程和面向接口編程的區別
  • copyright 2024編程學習大全網