C# :: Aufgabe #198

3 Lösungen Lösungen öffentlich

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.

Lösungen:

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;
        }
    }

vote_ok
von hollst (9460 Punkte) - 07.05.2018 um 11:03 Uhr
Quellcode ausblenden C#-Code
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
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. 
*/

namespace aufgabe_198
{
    class Program
    {
        static string NL = Environment.NewLine;
        static void Main()
        {
            //string input = "A*(B+C)*(D+E)";
            string input = "(B+C)*(D+E)*A";
            WriteLine("input: " + NL + input);

            Dictionary<string, string> output = Substituts(input);
            List<string> init_strings = plus_token(output["all"]);
            List<string> expanded = expand(init_strings, output);

            StringBuilder sb = new StringBuilder();
            for (var i = 0; i < expanded.Count; i++)
                sb.Append(expanded[i] + "+");
            string result = sb.ToString();
            WriteLine("result:" + NL + result.Remove(result.Length - 1));

            ReadKey(true);
        }

        static string eliminate_brackets(string token, string sub, 
            ref int subi, ref Dictionary<string, string> dic)
        {
            string ssub = sub + subi.ToString();
            subi++;
            char[] c = token.ToCharArray();
            char[] ct = new char[c.Length - 2];
            Array.Copy(c, 1, ct, 0, ct.Length);
            dic.Add(ssub, new string(ct));
            return ssub;
        }

        static Dictionary<string, string> Substituts(string input)
        {
            //step 0: remove spaces
            Char LZ = ' ';
            string result = string.Empty;
            for (var i = 0; i < input.Length; i++)
                if (input[i] != LZ)
                    result += input[i].ToString();
            
            int kmax = int.MaxValue;
            string sub = "sub";
            int subi = 0;

            Dictionary<string, string> dic = new Dictionary<string, string>();

            //step 1: substitute brackets
            while (kmax > 1)
            {
                int[] klammer = new int[result.Length];
                int[] ebene = new int[result.Length];
                int ka = 0;
                kmax = 0;

                for (var i = 0; i < result.Length; i++)
                {
                    if (result[i] == '(')
                        { klammer[i] = ka++; if (ka > kmax) kmax = ka; };
                    ebene[i] = ka;
                    if (result[i] == ')')
                        { klammer[i] = ka; ka--; };
                }

                string token = result[0].ToString();
                int index = ebene[0];

                string ohne_klammer = string.Empty;

                for (var i = 1; i < result.Length; i++)
                {
                    if (ebene[i] == index)
                        token += result[i].ToString();
                    else
                    {
                        if (token[0] == '(' && token[token.Length - 1] == ')')
                            token = eliminate_brackets(token, sub, ref subi, ref dic);
                        ohne_klammer += token;

                        index = ebene[i];
                        token = result[i].ToString();
                    }
                }

                if (token[0] == '(' && token[token.Length - 1] == ')')
                    token = eliminate_brackets(token, sub, ref subi, ref dic);
                ohne_klammer += token;

                result = ohne_klammer;
            }//while
            dic.Add("all", result);
            return dic;
        }

        static List<string> plus_token(string input)
        {
            string[] inputs = input.Split('+');
            List<string> result = new List<string>();
            for (var i = 0; i < inputs.Length; i++)
                result.Add(inputs[i]);
            return result;
        }

        static List<string> expand(List<string> input, Dictionary<string, string> substitutes)
        {
            List<string> result = new List<string>();
            for(var i = 0; i < input.Count; i++)
            {
                string mult_token = input[i];
                string[] factors = mult_token.Split('*');
                string new_mult_token = string.Empty;
                bool bo_key = false;
                for (var j = 0; j < factors.Length; j++)    {
                    if (substitutes.Keys.Contains(factors[j]))  {
                        bo_key = true;
                        string plus_factor = substitutes[factors[j]];
                        List<string> Lplus_factor = plus_token(plus_factor);
                        for (var k = 0; k < Lplus_factor.Count; k++)    {
                            string new_mult_token_temp = new_mult_token;

                            new_mult_token_temp += Lplus_factor[k] + "*";
                            for (var kk = j + 1; kk < factors.Length; kk++)
                                new_mult_token_temp += factors[kk] + "*";
                            new_mult_token_temp = 
                                new_mult_token_temp.Remove(new_mult_token_temp.Length - 1);
                            result.Add(new_mult_token_temp);
                        }
                    }
                    else
                        new_mult_token += factors[j] + "*";

                    if (bo_key)
                        break;//j
                }//j
                if (!bo_key)
                    result.Add(new_mult_token.Remove(new_mult_token.Length - 1));
            }//i

            if (result.Count == input.Count)
                return result;
            else
                return expand(result, substitutes);
        }
    }
}
1 Kommentar
vote_ok
von jigga (3400 Punkte) - 13.10.2018 um 10:34 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;

namespace Aufgabe176
{
    class Program
    {
        static void Main(string[] args)
        {
            List<List<int>> array = new List<List<int>>();
            List<int> pre_array = new List<int>();
            Int32 n;
            while (true)
            {
                try
                {
                    Console.Write("Zahl eingeben: ");
                    string eing = Console.ReadLine();
                    Int32.TryParse(eing, out n);
                    break;
                }
                catch
                {
                    Console.WriteLine("Keine Zahl eingegeben! Bitte nochmal!\n");
                }
            }

            Int32 i = 1;
            Int32 j = 1;
            Int32 k = 0;

            while (true)
            {
                if (i < n)
                {
                    while (i < n)
                    {
                        pre_array.Add(i);
                        i += k + j;
                        k += 1;
                    }
                }
                else if (i == n)
                {
                    pre_array.Add(i);
                    array.Add(pre_array);
                    break;
                }
                else
                {
                    List<int> c_array = new List<int>(pre_array);
                    array.Add(c_array);
                    i = array[j - 1][0] + j + 1;
                    j += 1;
                    k = 0;
                    pre_array.Clear();
                }
            }
            for(int l = 0; l < array.Count; l++)
            {
                if (array[l].Contains(n))
                {
                    Console.WriteLine("ZN = " + l + ", SN = " + array[l].IndexOf(n));
                }
            }
        }
    }
}