【问题标题】:Stack Calculator Complex and Negative Numbers Not Working堆栈计算器复数和负数不起作用
【发布时间】:2021-03-31 19:58:48
【问题描述】:

我无法排除故障并找出我的 RPN 计算器无法正常运行的原因。我可以毫无问题地进行加法、减法和乘法运算,但我无法正确计算负数或复数。我将提供我的代码以及失败的测试用例。

/*calculator.cpp*/
#include <iostream>
#include <string>
#include <sstream>
#include "functions.h"
using std::cin, std::cout, std::endl, std::string, std::istringstream;

string string_values;
int int_values;
Stack new_stack;
double double_val;
double right;
double left;
double result;

int main() {
  // prompt user input
  cout << "Type RPN expression (end with '=')." << endl;
  cout << "> ";

  while (cin >> string_values)
  {

    if (string_values.at(0) == '.')
    {
        double_val = stod(string_values);
        push(new_stack, double_val);
    }
    else if (isdigit(string_values[0]))
    {
        double_val = stod(string_values);
        push(new_stack, double_val);
    }
    else if (string_values[0] == '=')
    {
        result = pop(new_stack);
      cout << "Ans: " << result << endl;
    }
    else 
    {
        right = pop(new_stack);
      left = pop(new_stack);
      if (string_values[0] == '+')
      {
          result = (right + left);
          push(new_stack, result);
      }
      else if (string_values[0] == '-')
      {
        result = (left - right);
        push(new_stack, result);
      }
      else if (string_values[0] == '*')
      {
        result = (right * left);
        push(new_stack, result);
      }
      else if (string_values[0] == '/')
      {
        result = (left / right);
        push(new_stack, result);
      }
      else 
      {
        cout << "[ERROR] invalid operator: " << string_values << endl;
        break;
      }
    }
  }
  
  //TODO: create a command-line interface for calculator GUI

  return 0;
}
/*functions.cpp*/
#include "functions.h"
using std::cin, std::cout, std::endl, std::ostream, std::string;

#define INFO(X)  cout << "[INFO] ("<<__FUNCTION__<<":"<<__LINE__<<") " << #X << " = " << X << endl;
#define INFO_STRUCT(X) cout << "[INFO] ("<<__FUNCTION__<<":"<<__LINE__<<") " << #X << " count = " << X.count << endl;

/**
 * ----- REQUIRED -----
 * Pushes number to top of stack. If stack is full, then resize stack's array.
 * @param   stack   Target stack.
 * @param   number  Number to push to stack.
 */
void push(Stack& stack, int number) {
  // TODO: implement push function for stack
  //INFO_STRUCT(stack);
  //INFO(number);
  if (stack.capacity == stack.count)
  {
    stack.capacity = stack.capacity * 2;
    int *new_array = new int[stack.capacity];
    for (int i = 0; i < stack.count; ++i)
    {
        new_array[i] = stack.numbers[i];
    }
    delete[] stack.numbers;
    stack.numbers = new_array;
  }
    stack.numbers[stack.count] = number;
    stack.count++;
}

/**
 * ----- REQUIRED -----
 * Pops number from top of stack. If stack is empty, return INT32_MAX.
 * @param   stack   Target stack.
 * @return          Value of popped number.
 */
int pop(Stack& stack) {
  // TODO: implement pop function for stack
    //INFO_STRUCT(stack);
  
    if (stack.count != 0)
    {
        int top_number = stack.numbers[stack.count - 1];
        stack.count--;
        return top_number;
    }

    else
      {
        return (INT32_MAX);
    }
}

/**
 * ----- OPTIONAL -----
 * Returns the number at top of stack without popping it. If stack is empty, return INT32_MAX.
 * @param   stack   Target statck.
 * @return          Number at top of stack.
 */
int peek(const Stack& stack) {
  // TODO (optional): implement peek function for stack
  INFO_STRUCT(stack);
  return 0;
}
/*functions.h*/
#ifndef STACK_H
#define STACK_H

#include <iostream>
#include <string>
#include <sstream>

/**
 * The stack data type that is initially empty and has a singleton capacity.
 */
struct Stack {
    int* numbers = new int[1] {};   // array of numbers
    int capacity    = 1;            // capacity of array
    int count       = 0;            // number of elements in array
};

/**
 * ----- REQUIRED -----
 * Pushes number to top of stack. If stack is full, then resize stack's array.
 * @param   stack   Target stack.
 * @param   number  Number to push to stack.
 */
void push(Stack& stack, int number);

/**
 * ----- REQUIRED -----
 * Pops number from top of stack. If stack is empty, return INT32_MAX.
 * @param   stack   Target stack.
 * @return          Value of popped number.
 */
int pop(Stack& stack);

/**
 * ----- OPTIONAL -----
 * Returns the number at top of stack without popping it. If stack is empty, return INT32_MAX.
 * @param   stack   Target statck.
 * @return          Number at top of stack.
 */
int peek(const Stack& stack);

#endif

测试用例: 反例: 输入:

-5 -7 -9 * - =

我的代码输出:

Type RPN expression (end with '=').
> Ans: 2.14748e+09

预期输出:

Type RPN expression (end with '=').
> Ans: -68

复杂示例: 输入:

10 10 10 * * 59 + 1024 8 * * 9 - 1000000 - =

我的代码输出:

Type RPN expression (end with '=').
> Ans: 7.67532e+06

预期输出:

Type RPN expression (end with '=').
> Ans: 7675319

我可以看到复杂示例中句点的放置存在问题,但我不知道我在反例中做错了什么。任何指针将不胜感激。感谢您的时间和精力!

【问题讨论】:

  • 您是否尝试过在调试器中逐句逐句执行代码?
  • 可能希望从-1 = 之类的测试用例开始。您没有正确解析负数(if 块句柄 -1 的前 3 种情况都没有。它不是以 . 开头,它不是以数字开头,也不是 @ 987654335@。您可能想将值-1 压入堆栈,对吗?必须解决这个问题。
  • 我尝试了10 10 10 * * 59 + 1024 8 * * 9 - 1000000 - = 的测试用例输入,它计算出正确的值 7675319,只是它以默认格式将其输出到流中。考虑阅读如何使用std::fixedprevent scientific notation
  • 我会投赞成票,因为你发布了所有代码和测试用例、预期和实际输出,但我投反对票,因为你没有使用调试器。
  • @500-InternalServerError: 中缀表示法应该是(-5) - ((-7) * (-9))

标签: c++ arrays class


【解决方案1】:

对负数的修复将检查一个数字是否以- 开头,并且还有更多字符可以理解(长度> 1)。

    else if (isdigit(string_values[0]) || string_values[0] == '-' && string_values.size() > 1)

科学记数法的修复方法是使用来自 iomanip 的 std::setprecision。 (见reference

#include <iomanip>

// ...

      cout << "Ans: " << std::setprecision(std::numeric_limits<long double>::digits10 + 1) 
        << result << endl;

【讨论】:

  • 你认为有办法在不使用iomanip 的情况下做到这一点吗?我只被允许使用当前的包含,我不能再添加了。谢谢你的建议!
  • 你可以做printf("Ans: %.19g\n", result);
猜你喜欢
  • 1970-01-01
  • 2011-01-04
  • 2020-02-22
  • 2017-03-29
  • 1970-01-01
  • 2012-10-26
  • 2010-12-14
  • 2012-06-26
  • 2018-11-13
相关资源
最近更新 更多