⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p2.c

📁 一个表达式计算器的算法,编译后运行,输出output.txt
💻 C
📖 第 1 页 / 共 2 页
字号:
					}
				}
				else
				{
					return 0;						// ERROR IN INFIX NOTATION
				}
			}
			chTmp = chCurrent;
			PushOperatorWithProcess(chTmp, pOperatorsStack, pOperandsStack);
			break;
		case ')':
			/* An operand directly after a ')' or a ')' as the first character is forbidden. */
			if (IsDigitalChar(chNext) || chNext == '.' || chNext == '(' || chLast == '\0')
			{
				return 0;					// ERROR IN INFIX NOTATION
			}
			chTmp = chCurrent;
			PushOperatorWithProcess(chTmp, pOperatorsStack, pOperandsStack);
			break;
		default:
			if (IsDigitalChar(chCurrent) || chCurrent == '.')
			{
				ptrTmp = ptrCur;
				tmpOperand = strtod(ptrTmp, &ptrCur);
				if (ptrCur == ptrTmp)
				{
					return 0;	// ERROR IN INFIX NOTATION
				}
				else
				{
					elem.d = tmpOperand;
					Push(elem, pOperandsStack);
					ptrCur--;
				}
			}
			else
			{
				return 0;	// ERROR IN INFIX NOTATION
			}
			break;
		}
		chLast = *ptrCur++;
	}
	
	while (!IsEmpty(pOperatorsStack))
	{
		Pop(pOperatorsStack, &elem);
		if (IsOperator(elem.ch))
		{
			if (elem.ch == 'p' || elem.ch == 'n')
			{
				if (Pop(pOperandsStack, &elemOperand1))
				{
					atomElems.chOperator = elem.ch;
					atomElems.dOperand1 = elemOperand1.d;
					if (DoAtomCalc(atomElems, &result) != 0)
					{
						return 0;
					}
					elemOperand1.d = result;
					Push(elemOperand1, pOperandsStack);
				}
				else
				{
					return 0;
				}
			}
			else
			{
				if (Pop(pOperandsStack, &elemOperand2) && Pop(pOperandsStack, &elemOperand1))
				{
					atomElems.chOperator = elem.ch;
					atomElems.dOperand1 = elemOperand1.d;
					atomElems.dOperand2 = elemOperand2.d;
					if (DoAtomCalc(atomElems, &result) != 0)
					{
						return 0;
					}
					elemOperand1.d = result;
					Push(elemOperand1, pOperandsStack);
				}
				else
				{
					return 0;
				}
			}
		}
		else
		{
			return 0;
		}
	}

	if (!IsEmpty(pOperandsStack))
	{
		Pop(pOperandsStack, &elem);
		if (IsEmpty(pOperandsStack))
		{
			result = elem.d;
			*out_result = result;
			return 1;
		}
		else
		{
			return 0;
		}
	}
	else
	{
		return 0;
	}
}

/*------------------------------------------------------------------------------------------------------------*/
/* Push the operator to Operators' Stack and calculate the generated part of the postfix expression as well.  */
/* return value:                                                                                              */
/*    1: succeeded                                                                                            */
/*    0: failed                                                                                               */
/*------------------------------------------------------------------------------------------------------------*/
int PushOperatorWithProcess(char ch, Stack *pOperatorsStack, Stack *pOperandsStack)
{
	data elemOperator, elemOperatorPrev, elemOperatorBeforePrev;
	data elemOperand1, elemOperand2;
	atomCalcElems atomElems;
	double dAtomResult;
	int i;

	if (Fetch(pOperatorsStack, &elemOperatorPrev) && elemOperatorPrev.ch != '(')
	{
		if (ch == '(')
		{
			elemOperator.ch = ch;
			Push(elemOperator, pOperatorsStack);
		}
		else if (ch == ')')				/* the character ')' will not be pushed. */
		{
			Pop(pOperatorsStack, &elemOperator);
			do 
			{
				if (elemOperatorPrev.ch == 'p' || elemOperatorPrev.ch == 'n')		/* unary operators */
				{
					if (Pop(pOperandsStack, &elemOperand1))
					{
						atomElems.chOperator = elemOperatorPrev.ch;
						atomElems.dOperand1 = elemOperand1.d;
						if (DoAtomCalc(atomElems, &dAtomResult) != 0)
						{
							return 0;
						}
						elemOperand1.d = dAtomResult;
						Push(elemOperand1, pOperandsStack);
					}
					else
					{
						return 0;
					}
				}
				else
				{
					if (Pop(pOperandsStack, &elemOperand2) && Pop(pOperandsStack, &elemOperand1))
					{
						atomElems.chOperator = elemOperatorPrev.ch;
						atomElems.dOperand1 = elemOperand1.d;
						atomElems.dOperand2 = elemOperand2.d;
						if (DoAtomCalc(atomElems, &dAtomResult) != 0)
						{
							return 0;
						}
						elemOperand1.d = dAtomResult;
						Push(elemOperand1, pOperandsStack);
					}
					else
					{
						return 0;
					}
				}
				if (!Pop(pOperatorsStack, &elemOperatorPrev))
				{
					return 0;			// ERROR IN INFIX NOTATION
				}
			} while(elemOperatorPrev.ch != '(');
		}
		else
		{
			switch(CompareOperatorPrecedence(ch, elemOperatorPrev.ch))
			{
			case 0:										/* equal precedence */
				if (ch == 'n' || ch == 'p')				/* indicates elemOperatorPrev.ch is 'n' or 'p' */
				{
					elemOperator.ch = ch;
					Push(elemOperator, pOperatorsStack);
				}
				else if (ch == '^')						/* indicates elemOperatorPrev.ch is '^' */
				{
					elemOperator.ch = ch;
					Push(elemOperator, pOperatorsStack);
				}
				else
				{
					Pop(pOperatorsStack, &elemOperator);
					if (Pop(pOperandsStack, &elemOperand2) && Pop(pOperandsStack, &elemOperand1))
					{
						atomElems.chOperator = elemOperatorPrev.ch;
						atomElems.dOperand1 = elemOperand1.d;
						atomElems.dOperand2 = elemOperand2.d;
						if (DoAtomCalc(atomElems, &dAtomResult) != 0)
						{
							return 0;
						}
						elemOperand1.d = dAtomResult;
						Push(elemOperand1, pOperandsStack);
					}
					else
					{
						return 0;
					}
					elemOperator.ch = ch;
					Push(elemOperator, pOperatorsStack);
				}
				break;
			case 1:				/* ch has the higher precedence */
				if (Pop(pOperatorsStack, &elemOperator))
				{
					if (Fetch(pOperatorsStack, &elemOperatorBeforePrev))
					{
						if (ch == '^' && (elemOperatorPrev.ch == 'p' || elemOperatorPrev.ch == 'n') && elemOperatorBeforePrev.ch == '^')
						{
							if (Pop(pOperandsStack, &elemOperand1))
							{
								atomElems.chOperator = elemOperatorPrev.ch;
								atomElems.dOperand1 = elemOperand1.d;
								if (DoAtomCalc(atomElems, &dAtomResult) != 0)
								{
									return 0;
								}
								elemOperand1.d = dAtomResult;
								Push(elemOperand1, pOperandsStack);
							}
							else
							{
								return 0;
							}
							if (Pop(pOperatorsStack, &elemOperatorBeforePrev))
							{
								if (Pop(pOperandsStack, &elemOperand2) && Pop(pOperandsStack, &elemOperand1))
								{
									atomElems.chOperator = elemOperatorPrev.ch;
									atomElems.dOperand1 = elemOperand1.d;
									atomElems.dOperand1 = elemOperand2.d;
									if (DoAtomCalc(atomElems, &dAtomResult) != 0)
									{
										return 0;
									}
									elemOperand1.d = dAtomResult;
									Push(elemOperand1, pOperandsStack);
								}
								else
								{
									return 0;
								}
							}
							else
							{
								return 0;			/* unreasoned error */
							}
						} 
						else
						{
							Push(elemOperator, pOperatorsStack);
						}
					}
					else
					{
						Push(elemOperator, pOperatorsStack);
					}
				}
				else
				{
					return 0;			/* unreasoned error */
				}
				elemOperator.ch = ch;
				Push(elemOperator, pOperatorsStack);
				break;
			case -1:			/* elemOperatorPrev.ch has the higher precedence */
				if ((ch == 'p' || ch == 'n') && elemOperatorPrev.ch == '^')
				{
					elemOperator.ch = ch;
					Push(elemOperator, pOperatorsStack);
				}
				else
				{
					do 
					{
						Pop(pOperatorsStack, &elemOperator);
						if (elemOperatorPrev.ch == 'p' || elemOperatorPrev.ch == 'n')		/* unary operators */
						{
							if (Pop(pOperandsStack, &elemOperand1))
							{
								atomElems.chOperator = elemOperatorPrev.ch;
								atomElems.dOperand1 = elemOperand1.d;
								if (DoAtomCalc(atomElems, &dAtomResult) != 0)
								{
									return 0;
								}
								elemOperand1.d = dAtomResult;
								Push(elemOperand1, pOperandsStack);
							}
							else
							{
								return 0;
							}
						}
						else
						{
							if (Pop(pOperandsStack, &elemOperand2) && Pop(pOperandsStack, &elemOperand1))
							{
								atomElems.chOperator = elemOperatorPrev.ch;
								atomElems.dOperand1 = elemOperand1.d;
								atomElems.dOperand2 = elemOperand2.d;
								if (DoAtomCalc(atomElems, &dAtomResult) != 0)
								{
									return 0;
								}
								elemOperand1.d = dAtomResult;
								Push(elemOperand1, pOperandsStack);
							}
							else
							{
								return 0;
							}
						}
					} while(Fetch(pOperatorsStack, &elemOperatorPrev) && elemOperatorPrev.ch != '\0' && elemOperatorPrev.ch != '(' 
						&& ((i = CompareOperatorPrecedence(ch, elemOperatorPrev.ch)) == 0 || i == -1));
					elemOperator.ch = ch;
					Push(elemOperator, pOperatorsStack);
				}
				break;
			case -2:			/* error occurred */
			default:
				return 0;
				break;
			}
		}
	}
	else
	{
		if (elemOperatorPrev.ch == '(' && ch == ')')
		{
			Pop(pOperatorsStack, &elemOperator);
		}
		else
		{
			elemOperator.ch = ch;
			Push(elemOperator, pOperatorsStack);
		}
	}
}

/*-------------------------------------------------------------*/
/*   Do the most basic calculation.                            */
/*   Parameter:                                                */
/*   [in] elems:                                               */
/*            The elements for calculation.                    */
/*   [out] out_result:                                         */
/*            Pointer to the result of the calculation.        */
/*   Return value:                                             */
/*   0:	   succeeded;                                          */
/*   -1:   divide or mod by zero;                              */
/*   -2:   0.0 raised to the power of a negative;              */
/*   -3:   unknown error;                                      */
/*-------------------------------------------------------------*/
int DoAtomCalc(atomCalcElems elems, double* result)
{
	switch(elems.chOperator)
	{
	case '+':
		*result = elems.dOperand1 + elems.dOperand2;
		return 0;
	case '-':
		*result = elems.dOperand1 - elems.dOperand2;
		return 0;
	case '*':
		*result = elems.dOperand1 * elems.dOperand2;
	    return 0;
	case '/':
		if (elems.dOperand2 == 0.0)
		{
			return -1;
		} 
		else
		{
			*result = elems.dOperand1 / elems.dOperand2;
			return 0;
		}
	case '%':
		if (elems.dOperand2 == 0.0)
		{
			return -1;
		} 
		else
		{
			*result = (int)elems.dOperand1 % (int)elems.dOperand2;
			return 0;
		}
	case 'n':
	    *result = -elems.dOperand1;
		return 0;
	case 'p':
		*result = elems.dOperand1;
	    return 0;
	case '^':
		_set_errno(0);
		*result = pow(elems.dOperand1, elems.dOperand2);
		if (errno == ERANGE || errno == EDOM)	// has or hasn't significance ???
		{
			if (!elems.dOperand1 && elems.dOperand2 < 0)
			{
				return -2;
			}
			else
			{
				return -3;
			}
		}
		else
		{
			return 0;
		}
	default:
	    return -3;
	}
}

void DeleteBlanks(char *str)
{
	int nLen = strlen(str);
	int i, j;
	for (i = 0, j = 0; i < nLen; i++)
	{
		if (str[i] == ' ' || str[i] == '\t')
		{
			continue;
		}
		else
		{
			str[j++] = str[i];
		}
	}
	strset(&str[j], '\0');
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -