Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: johan 07. 01. 2018, 13:29:04

Název: Zásobníkový automat
Přispěvatel: johan 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--;

                        }

                    }                     

                }               

            }

        }

    }

 

}
Název: Re:Zásobníkový automat
Přispěvatel: gll 07. 01. 2018, 14:26:37
jestli ten regex engine umí rekurzivní matche, tak by to mělo být easy.
Název: Re:Zásobníkový automat
Přispěvatel: gll 07. 01. 2018, 14:27:56
(?<rec>\((?:[^()]++|(?&rec))*\))
Název: Re:Zásobníkový automat
Přispěvatel: johan 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;

}

}

}
}

}
Název: Re:Zásobníkový automat
Přispěvatel: gll 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));
                }
            }
        }
    }
Název: Re:Zásobníkový automat
Přispěvatel: johan 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));
                }
            }
        }
    }
Název: Re:Zásobníkový automat
Přispěvatel: gll 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);
            }
        }
    }
Název: Re:Zásobníkový automat
Přispěvatel: mikrom 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