C# :: Aufgabe #198 :: Lösung #1

3 Lösungen Lösungen öffentlich
#198

Logische Ausdrücke 'ausklammern'

Fortgeschrittener - C# von polie - 25.01.2018 um 19:12 Uhr
Schreibe ein Programm welches aus dem Ausdruck

A&(B|C)&(D|E)

den folgenden erzeugt:

A&B&D|A&B&E|A&C&D|A&C&E

Hier ist das & ein logisches UND und das | das logische ODER. Die Klammern sind wie bei der Multipikation/Division zu behandeln.
#1
vote_ok
von schnurly (60 Punkte) - 07.05.2018 um 08:23 Uhr
Quellcode ausblenden C#-Code
        public string convert(string input)
        {
            return convert(input, null);
        }
        private string convert(string input, List<List<string>> innerBracketList)
        {
            bool isFirstRecursion = innerBracketList == null;
            string currentSign = "";
            string retVal = "";

            List<List<string>> orList = new List<List<string>>();
            List<string> andList = new List<string>();
            List<List<List<string>>> bracketList = new List<List<List<string>>>();
            orList.Add(andList);
            for (int index = 0; index < input.Length; index++)
            {
                bool operatorFound = false;
                if (input[index] == '&')
                {
                    operatorFound = true;
                }
                else if (input[index] == '|')
                {
                    operatorFound = true;
                    if (bracketList.Count > 0)
                    {
                        orList.Remove(andList);
                        UseDistributivLaw(bracketList, 0, andList).ForEach(x => orList.Add(x));
                        bracketList.Clear();
                    }
                    andList.Add(currentSign);
                    currentSign = "";
                    andList = new List<string>();
                    orList.Add(andList);
                }
                else if (input[index] == '(')
                {
                    operatorFound = true;
                    List<List<string>> tmpList = new List<List<string>>();
                    bracketList.Add(tmpList);
                    int closingPosition = findClosingParen(input.ToArray(), index);
                    convert(input.Substring(index + 1, closingPosition - index - 1), tmpList);
                    index = closingPosition + 1;
                }
                else
                {
                    currentSign = currentSign + input[index];
                }
                if (operatorFound)
                {
                    if (currentSign.Length > 0)
                    {
                        andList.Add(currentSign);
                        currentSign = "";
                    }
                }
            }
            if (currentSign.Length > 0)
                andList.Add(currentSign);

            if (bracketList.Count > 0)
            {
                orList.Remove(andList);
                UseDistributivLaw(bracketList, 0, andList).ForEach(x => orList.Add(x));
                bracketList.Clear();
            }

            if (innerBracketList == null)
            {
                foreach (List<string> tmpAnd in orList)
                {
                    retVal += String.Join("&", tmpAnd) + "|";
                }
                retVal = retVal.Remove(retVal.Length - 1);
            }
            else
            {
                orList.ForEach(x => innerBracketList.Add(x));
            }

            return retVal;
        }


        private List<List<string>> UseDistributivLaw(List<List<List<string>>> bracketList, int level, List<string> outerBracketData)
        {
            List<List<string>> retVal = new List<List<string>>();

            foreach (List<string> bracket in bracketList[level])
            {
                List<string> tmpList = new List<string>();
                bracket.ForEach(x => tmpList.Add(x));
                outerBracketData.ForEach(x => tmpList.Add(x));
                if (bracketList.Count - 1 > level)
                {
                    UseDistributivLaw(bracketList, level + 1, tmpList).ForEach(x => retVal.Add(x));
                }
                else
                {
                    retVal.Add(tmpList);
                }
            }
            return retVal;
        }


        private int findClosingParen(char[] text, int openPos)
        {
            int closePos = openPos;
            int counter = 1;
            while (counter > 0)
            {

                char c = text[++closePos];
                if (c == '(')
                {
                    counter++;
                }
                else if (c == ')')
                {
                    counter--;
                }
            }
            return closePos;
        }
    }

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben