如何在没有数组实现的情况下调用链表?

时间:2017-09-17 05:33:29

标签: java arrays linked-list stack call

对于这个作业,我编写了一个程序,它将计算用户提供的反向波兰表达式的结果。

我必须使用链表来维护此程序的堆栈(堆栈的数组实现不会获得完全信用)。

我必须处理以下情况(错误):     操作员太多(+ - / *)     操作数太多(双打)     除以零

程序将采用波兰语表达式,将运算符和操作数分隔为单个空格,并使用等号终止表达式。 程序将继续采用和计算表达式,直到用户在一行上输入零(0),然后是新行。 我的示例输出应显示所有错误条件的处理以及使用所有运算符。但是,当我执行该程序时,它说 错误:在类program1.Program1中找不到主要方法,请将main方法定义为:    public static void main(String [] args) Java结果:1 我不知道如何在没有数组实现的情况下调用链表。也 RefObject类和TryparseHelper位于同一个包中。 TNX

 package program1;
 import java.util.*;
 import java.lang.IllegalStateException;


  public class Program1 {


 public class Node<T>
 {
public T Data;
public Node<T> Next;
 }

  public class Stack<T>
  {
    private Node<T> top = null;

public final void Push(T value)
{
    top = new Node<T>();
    top.Data = value;
    top.Next = top;
}

public final T Pop()
{
    if (top == null)
    {
        throw new IllegalStateException("Cannot pop if the stack is empty.");
    }

    T topValue = top.Data;
    top = top.Next;

    return topValue;
}

public final boolean IsEmpty()
{
    return top == null;
}

public final void Clear()
{
    top = null;
}
   }

     public class ReversePolishCalculator
     {


public final void Calculator()
{
    String expression = "";
    while (!expression.equals("0"))
    {
        System.out.print("Enter expression: ");
        expression = new Scanner(System.in).nextLine();

        try
        {
            System.out.println(" = " + Calculate(expression));
        }
        catch (RuntimeException ex)
        {
            System.err.println(ex.getMessage());
        }
    }
}

private Stack<Double> stack = new Stack<Double>();

private double Calculate(String expression)
{
    double result = 0.0;
    stack.Clear();

    String[] tokens = expression.split("[ ]", -1);

    for (String token : tokens)
    {
        double value = 0;
        RefObject<Double> tempRef_value = new RefObject<Double>(value);
        if (TryParseHelper.tryParseDouble(token, tempRef_value))
        {
        value = tempRef_value.argValue;
            stack.Push(value);
        }
        else
        {
        value = tempRef_value.argValue;
            DoOperation(token);
        }
    }

    if (!stack.IsEmpty())
    {
        result = stack.Pop();
    }

    if (!stack.IsEmpty())
    {
        throw new IllegalStateException("Too many operands.");
    }

    return result;
}

private void DoOperation(String token)
{
    if (stack.IsEmpty())
    {
        throw new IllegalStateException("Too many operators.");
    }

    double rhs = stack.Pop();

    if (stack.IsEmpty())
    {
        throw new IllegalStateException("Too many operators.");
    }

    double lhs = stack.Pop();

    switch (token)
    {
        case "+":
            stack.Push(lhs + rhs);
            break;
        case "-":
            stack.Push(lhs - rhs);
            break;
        case "*":
            stack.Push(lhs * rhs);
            break;
        case "/":
            if (rhs == 0.0)
            {
                throw new IllegalStateException("Divide by zero.");
            }

            stack.Push(lhs / rhs);
            break;
        default:
            throw new IllegalStateException("Unexpected operator: " + token);
    }
}
  }


  }

包程序1; TryParseHelper

  /**
  *
 * @author David
   */
 public final class TryParseHelper
   {
public static boolean tryParseInt(String s, RefObject<Integer> result)
{
    try
    {
        result.argValue = Integer.parseInt(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

public static boolean tryParseShort(String s, RefObject<Short> result)
{
    try
    {
        result.argValue = Short.parseShort(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

public static boolean tryParseLong(String s, RefObject<Long> result)
{
    try
    {
        result.argValue = Long.parseLong(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

public static boolean tryParseByte(String s, RefObject<Byte> result)
{
    try
    {
        result.argValue = Byte.parseByte(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

public static boolean tryParseDouble(String s, RefObject<Double> result)
{
    try
    {
        result.argValue = Double.parseDouble(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

public static boolean tryParseFloat(String s, RefObject<Float> result)
{
    try
    {
        result.argValue = Float.parseFloat(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

public static boolean tryParseBoolean(String s, RefObject<Boolean> result)
{
    try
    {
        result.argValue = Boolean.parseBoolean(s);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}
   }

包程序1; RefObj

/ **     *     * @author David      * /

 public final class RefObject<T>
 {
public T argValue;
public RefObject(T refArg)
{
    argValue = refArg;
}
}

1 个答案:

答案 0 :(得分:0)

正如您所粘贴的错误消息所示:要运行您的程序,请使用此签名Program1public static void main(String[] args)类添加一个方法。在其中写下您要运行的代码,例如System.out.println("hi");或其他。

更新:正如我从您的评论中所理解的那样,您的问题似乎是尝试从Calculator()调用非静态方法main(...)。首先,你需要一个关于class vs object和static vs non-static的背景知识。

类是模板或蓝图。对象是该蓝图的实例化。例如,汽车的描述是一个类,任何汽车都是一个对象。另一个例子是您的Stack类和您用来计算表达式的Stack<Double> stack = new Stack<Double>()对象。

当你致电pop()时,需要运行一个特定的堆栈。一个特定的对象。例如,您可以同时拥有2个堆栈,并且在其中一个堆栈上调用pop()不应该影响另一个堆栈。这就是方法pop()是非静态的原因。

现在,让我们想一下Program1类:你真的在考虑创建多个program1并在你的代码中运行它们/调用它们的方法吗?并且每个程序1的状态是否与另一个不同?每个堆栈可以随时具有不同的内容,但program1实际上没有任何内容或状态

如果您的方法不依赖于任何特定对象或特定状态,则将其标记为静态。例如,添加2个数字的方法应该是静态的。您的Calculator()方法也是如此。

所以,回到你的问题,要从Calculator()调用非静态方法main(...),你必须要:

(1)将Calculator()转换为静态方法。你需要问问自己&#34;这种方法只与特定的实例,特定的对象有关吗?&#34;。例如,pop()的{​​{1}}方法与某个堆栈对象非常相关。如果你在2个堆栈对象上调用它,它会给出不同的结果。这就是为什么它应该是一种非静态方法,即依赖于特定实例的方法 但是,Stack似乎是一种并非真正依赖于其他任何东西的方法。它使用名为Calculator()的成员变量这一事实是偶然的。您可以在stack内移动stack变量。或者您也可以将Calculator()设为静态。

(2)你可以,虽然它没有多大意义,但可以创建stack的实例,然后在其上调用Program1

我知道类和对象之间的区别,静态和非静态,在开始时可能会令人困惑。阅读更多内容,随着时间的推移,您会对此感到满意。

对于无阵列问题:如果我理解正确,则Calculator()中的数组存在问题。这里的数组是程序运行的必要条件,与堆栈的实现无关。所以,我不希望老师介意它。

最后,请注意,我认为代码存在一些问题,所以不要期望它从第一次开始运行。这绝对正常,您需要知道如何跟踪代码。祝你好运!