Zásobníkový automat

johan

Zásobníkový automat
« kdy: 07. 01. 2018, 13:29:04 »
Zdravim,
potřeboval bych pomoct s implementací zásobníkového automatu v C#.
Učím se nový jazyk, C#, a docela s ním bojuji.
Mám vstupní řetezec, matematický výraz pkný závorek. A potřebuji vypsat obsah jednotlivých závorek včetně těch závorek.
jak na to??
Mám tady kus kódu, který nevím jestli dobře popisuje ten automat...stavový automat vim jak napsat, ale ne zásobníkový...

kód:
Kód: [Vybrat]
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Text.RegularExpressions;

namespace Parsovani_5

{
    class Program

    {

        static void Main(string[] args)

        {

           // List<string> obsah = new List<string>();
 

            string vstup = "2*((a+b)-t)";

            int stav = 0;

            int i, size;

            //size = obsah.Count;

            string obsah = string.Empty; 

            string result = string.Empty;

            foreach (char c in vstup)

            {

                for (i = 0; i < obsah.Length; i++)

                {

                    if (stav == 0)

                    {

                        if (c == '(')

                        {

                            result = result + c;                                                 

                        }

                        else if (c == ')')

                        {

                            stav--;

                        }                       

                    }

                    else

                    {

                        stav++;

                        if (c == '(')

                        {
                            result = result + c;

                        }

                        else if (c == ')')

                        {

                            stav--;

                        }

                    }                     

                }               

            }

        }

    }

 

}


gll

Re:Zásobníkový automat
« Odpověď #1 kdy: 07. 01. 2018, 14:26:37 »
jestli ten regex engine umí rekurzivní matche, tak by to mělo být easy.

gll

Re:Zásobníkový automat
« Odpověď #2 kdy: 07. 01. 2018, 14:27:56 »
(?<rec>\((?:[^()]++|(?&rec))*\))

johan

Re:Zásobníkový automat
« Odpověď #3 kdy: 07. 01. 2018, 14:52:40 »
(?<rec>\((?:[^()]++|(?&rec))*\))

Díky za odpověď, přiznám se, že to nevim, to zjistim až zítra, teď to dělám v nějakém online IDE,, které křičí při té třídě REGEX.
Jinak, kdyby to ta třída neuměla, tak jak postupovat??
tady jsem splodil nějaký kus kódu, ale nevim jestli postupuju dobře nebo ne...

Kód: [Vybrat]
using System;

public class Program
{
public static void Main()
{
string vstup = "(2*(a-b)+t)";
int stav = 0;
int count = 0;
string obsah = string.Empty;

foreach (char c in vstup)
{
if (stav == 0)
{
if (c == '(')
{
obsah = obsah + c;
stav = 0;
//count++;
}
else
{

stav++;

}

}
else if (stav == 1)
{
if (c == ')')
{

stav = 0;

}

}

}
}

}

gll

Re:Zásobníkový automat
« Odpověď #4 kdy: 07. 01. 2018, 15:19:19 »
Kód: [Vybrat]
public class Program
    {
        public static void Main(string[] args)
        {
            string s = "(2) + (1 + 1 + (2 + 3))";
            var stack = new Stack<int>();
            for (int i = 0; i < s.Length; i++){
                if (s[i] == '('){
                    stack.Push(i);
                }
                if (s[i] == ')'){
                    int start = stack.Pop();
                    Console.WriteLine(s.Substring(start, i - start + 1));
                }
            }
        }
    }


johan

Re:Zásobníkový automat
« Odpověď #5 kdy: 07. 01. 2018, 15:23:50 »
Mockrát děkuji!!
Já na Přírodovědný fakultě neměl Teoretickou informatiku, jen c a c++ a hlavně studium mám teď víc zaměřený na HW, programování mikrokontrolerů.
Moc díky!


Kód: [Vybrat]
public class Program
    {
        public static void Main(string[] args)
        {
            string s = "(2) + (1 + 1 + (2 + 3))";
            var stack = new Stack<int>();
            for (int i = 0; i < s.Length; i++){
                if (s[i] == '('){
                    stack.Push(i);
                }
                if (s[i] == ')'){
                    int start = stack.Pop();
                    Console.WriteLine(s.Substring(start, i - start + 1));
                }
            }
        }
    }

gll

Re:Zásobníkový automat
« Odpověď #6 kdy: 07. 01. 2018, 19:31:04 »
tak jsem zjistil, že regex v c# neumí rekurzi, ale umí balancing groups.

https://docs.microsoft.com/en-us/dotnet/standard/base-types/grouping-constructs-in-regular-expressions#balancing_group_definition

Kód: [Vybrat]
    public class Program
    {
        public static void Main(string[] args)
        {
            var s = "(2) + (1 + (1 + 1))";
            var rg = new Regex(@"(?:[^()]|(?<Open>[(])|(?<Content-Open>[)]))*");
            foreach (var match in rg.Match(s).Groups[2].Captures) {
                Console.WriteLine(match);
            }
        }
    }

mikrom

Re:Zásobníkový automat
« Odpověď #7 kdy: 07. 01. 2018, 22:37:13 »
Kód: [Vybrat]
public class Program
    {
        public static void Main(string[] args)
        {
            string s = "(2) + (1 + 1 + (2 + 3))";
            var stack = new Stack<int>();
            for (int i = 0; i < s.Length; i++){
                if (s[i] == '('){
                    stack.Push(i);
                }
                if (s[i] == ')'){
                    int start = stack.Pop();
                    Console.WriteLine(s.Substring(start, i - start + 1));
                }
            }
        }
    }
SUPER +1