C# :: Aufgabe #198
3 Lösungen
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.
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:
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; } }
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); } } }
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)); } } } } }