Почему мой C# стек не выводит содержимое даже после того, как я использую peek и pu sh? - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь получить мой стек с именем rpnstack для вывода его содержимого из файла xml, который выглядит следующим образом:

<mrow>
<apply>
  <eq/>
  <apply>
    <plus/>
    <apply>
      <power/>
      <ci>5</ci>
      <cn>2</cn>
    </apply>
    <apply>
      <times/>
      <cn>4</cn>
      <ci>2</ci>
    </apply>
    <cn>4</cn>
  </apply>
  <cn>0</cn>
</apply>
</mrow>

Мой стек rpn ниже ничего не выведет, я не работает в ifs? Я пытаюсь разобрать теги mathml и пытаюсь сохранить все значения уравнения, например: 5 ^ 2 + 4 * 2 + 4 = 0

using System;
using System.Collections.Generic;
    using System.Xml;
    using UnityEngine;
    using UnityEngine.UI;

    namespace ParseXML
    {
        class PARSEMATH : MonoBehaviour
        {
            Stack<string> stacknums = new Stack<string>();
            Stack<string> stacktags = new Stack<string>();
            Stack<string> stacknumandtags = new Stack<string>();

            Stack<string> rpnstack = new Stack<string>();

            void Start()
            {
                XmlDocument xmlDoc = new XmlDocument();
                TextAsset textAsset = (TextAsset)Resources.Load("testing");
                xmlDoc.LoadXml(textAsset.text);

                foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
                {
                    string text = node.InnerText;
                    stacknums.Push(text);

                    char[] values = text.ToCharArray();

                    string tags = node.OuterXml;
                    stacktags.Push(tags);

                    string numtag = node.OuterXml;
                    stacknumandtags.Push(numtag);

                    Debug.Log(text);
                    Debug.Log(tags);
                    Debug.Log(numtag);

                    int count = 0;

                    foreach(var obj in stacknumandtags)
                    {
                        if(obj == "<eq/>")
                        {
                            // pass over and place = in RPN stack
                            rpnstack.Push("=");
                        }
                        else if (obj == "<plus/>")
                        {
                            // pass over and place = in RPN stack
                            rpnstack.Push("+");

                        }
                       else if (obj == "<power/>")
                        {
                            // pass over and place = in RPN stack
                            rpnstack.Push("^");

                        }
                        else if (obj == "<ci>" || obj == "<cn>")
                        {
                            char num = values[count];

                            string num_ = num.ToString();

                                // pass over and place = in RPN stack
                             rpnstack.Push(num_);

                                // counter
                             count++;


                        }
                        else if(obj == "<times/")
                        {
                            rpnstack.Push("*");

                        }

                        Debug.Log(rpnstack.Peek());
                        Debug.Log(rpnstack.Pop());


                    }
                }
            }
        }
    }

1 Ответ

0 голосов
/ 12 февраля 2020

Проблема с вашим кодом в том, что вы не перемещаетесь вниз по элементам. Вот метод, который будет анализировать mathml с помощью рекурсии вместо стеков. Метод стека не работает хорошо, когда оператор может быть применен к нескольким операндам, что имеет место с плюсом, который применяется к 5 ^ 2 и 4 * 2 и к окончательному 4.

public string ReadMathXml(XElement element)
{
    switch(element.Name.LocalName)
    {
        // There should be one apply inside of a row
        case "mrow":
            return ReadMathXml(element.Element("apply"));
        // The apply should have one operator followed by multiple operands
        case "apply":
            var elements = element.Elements();
            var op = ReadMathXml(elements.First());
            var operands = elements.Skip(1).Select(x => ReadMathXml(x));
            return string.Join(op, operands);
        // Add more operators as needed.
        case "plus": return "+";
        case "power": return "^";
        case "eq": return "=";
        case "times" : return "*";
        // Add any other operand names here.
        case "ci" :
        case "cn" : return element.Value;
    }

    // we should not get here.
    return null;
}

Тогда, если вы позвоните с этим кодом

var doc = XDocument.Parse(@"<mrow>
<apply>
  <eq/>
  <apply>
    <plus/>
    <apply>
      <power/>
      <ci>5</ci>
      <cn>2</cn>
    </apply>
    <apply>
      <times/>
      <cn>4</cn>
      <ci>2</ci>
    </apply>
    <cn>4</cn>
  </apply>
  <cn>0</cn>
</apply>
</mrow>");

var result = ReadMathXml(doc.Root);

Результат будет

5 ^ 2 + 4 * 2 + 4 = 0

Обратите внимание, что вам понадобится using System.Xml.Linq;, чтобы использовать XDocument и XElement.

...