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