Comparing the data - c#

I am trying to compare a set of integers (say alpha) with the result i am getting (say result)
if result is in alpha i should be able to get the output as mentioned in example below
alpha = 0,1,2,3,4,5,6,7
result = 0,5,6
Final answer should be ABBBBAAB
and what i am getting is ABBBBBBB BBBBBABB BBBBBBAB
As per code
public static int[] alpha = new int[8]
{
0,1,2,3,4,5,6,7
};
public static void Main(string[] args)
{
// Lines of code
foreach (var jagged in manager.JaggedList)
{
// Lines of code
foreach (var item in Items)
{
Console.Write(item.Number); //For Ex output here is (0,5,6)
List<int> result = new List<int>();
result.Add(item.Number);
foreach (var Var in result)
{
for (int i = 0; i < alpha.Length; i++)
{
if (result.Contains(alpha[i]))
{
Console.Write(alpha[A]);
}
else
{
Console.Write(alpha[B]);
}
}
}
Console.WriteLine();
}
}
Final answer should be ABBBBAAB
and what i am getting is ABBBBBBB BBBBBABB BBBBBBAB

If Linq is acceptable then just use
alpha
.Select(a => result.Contains(a) ? "A" : "B")
.ToList()
.ForEach(x => Console.Write(x));
using foreach loops
foreach(var a in alpha) {
var found = false;
foreach(var r in result) {
if(a == r) {
found = true;
}
}
Console.Write(found ? "A" : "B");
}

Related

Find count of each consecutive characters

Need to find the count of each consecutive characters in a row.
Ex: aaaabbccaa
output: 4a2b2c2a
Character may repeat but need to count only consecutive ones. I also need to maintain original sequence.
I tried following but it groups all characters so was not useful.
str.GroupBy(c => c).Select(g => new { g.Key, Count = g.Count() }).ToList().ForEach(x => str+= x.Count + "" + x.Key)
Regular expression to the rescue ?
var myString = "aaaabbccaa";
var pattern = #"(\w)\1*";
var regExp = new Regex(pattern);
var matches = regExp.Matches(myString);
var tab = matches.Select(x => String.Format("{0}{1}", x.Value.First(), x.Value.Length));
var result = String.Join("", tab);
Here is a LINQ solution:
var input = "aaaabbccaa";
var result = string.IsNullOrEmpty(input) ? "" : string.Join("",input.Skip(1)
.Aggregate((t:input[0].ToString(),o:Enumerable.Empty<string>()),
(a,c)=>a.t[0]==c ? (a.t+c,a.o) : (c.ToString(),a.o.Append(a.t)),
a=>a.o.Append(a.t).Select(p => $"{p.Length}{p[0]}")));
Here is the iterator solution:
var result = RleString("aaaabbccaa");
private static IEnumerable<(char chr, int count)> Rle(string s)
{
if (string.IsNullOrEmpty(s)) yield break;
var lastchar = s.First(); // or s[0]
var count = 1;
foreach (char letter in s.Skip(1))
{
if (letter != lastchar)
{
yield return (lastchar, count);
lastchar = letter;
count = 0;
}
count++;
}
if (count > 0)
yield return (lastchar, count);
}
private static string RleString(string s)
{
return String.Join("",Rle(s).Select(z=>$"{z.count}{z.chr}"));
}
Non-LINQ solution (dotnetfiddle):
using System;
using System.Text;
public class Program
{
public static void Main()
{
// produces 4a2b2c2a
Console.WriteLine(GetConsecutiveGroups("aaaabbccaa"));
}
private static string GetConsecutiveGroups(string input)
{
var result = new StringBuilder();
var sb = new StringBuilder();
foreach (var c in input)
{
if (sb.Length == 0 || sb[sb.Length - 1] == c)
{
sb.Append(c);
}
else
{
result.Append($"{sb.Length}{sb[0]}");
sb.Clear();
sb.Append(c);
}
}
if (sb.Length > 0)
{
result.Append($"{sb.Length}{sb[0]}");
}
return result.ToString();
}
}
This small program will do the trick, but it's not a single line nice linq statement. Just my two cents.
using System;
using System.Linq;
using System.Collections.Generic;
public class Simple {
public static void Main() {
var text = "aaaabbccaa"; //output: 4a3b2c2a
var lista = new List<string>();
var previousLetter = text.Substring(1,1);
var item = string.Empty;
foreach (char letter in text)
{
if (previousLetter == letter.ToString()){
item += letter.ToString();
}
else
{
lista.Add(item);
item = letter.ToString();
}
previousLetter = letter.ToString();
}
lista.Add(item);
foreach (var i in lista)
Console.WriteLine(i.Substring(1,1) + i.Select(y => y).ToList().Count().ToString());
}
}
Here is my non-LINQ version that is quite fast compared to LINQ or Regex:
var prevChar = str[0];
var ct = 1;
var s = new StringBuilder();
var len = str.Length;
for (int j2 = 1; j2 < len; ++j2) {
if (str[j2] == prevChar)
++ct;
else {
s.Append(ct);
s.Append(prevChar);
ct = 1;
prevChar = str[j2];
}
}
s.Append(ct);
s.Append(prevChar);
var final = s.ToString();
}
My LINQ version looks like this, but uses a couple of extension methods I already had:
var ans = str.GroupByRuns().Select(s => $"{s.Count()}{s.Key}").Join();
var chars = "aaaabbccaa".ToCharArray();
int counter = 1;
for (var i = 0; i < chars.Count(); i++)
{
if (i + 1 >= chars.Count() || chars[i] != chars[i + 1])
{
Console.Write($"{counter}{chars[i]}");
counter = 1;
}
else
{
counter++;
}
}
You could have a character var and a counter var outside your Linq scope to keep track of the previous character and the current count and then use linq foreach, but I am just as curious as the rest to why you insist on doing this. Even if you do, the Solution may not be as easy to read as an iterative version and readability and maintenance overhead is very import if anyone else is ever going to read it.

Array of string management

I have an array of string, I want to take all the string in an interval of this array until string does not contains something.
Something like:
string [] arrayReading = {
"e","x","a","takefromhere",
"keeptaking","keeptaking","dont'ttakefromhere","m","p","l","e"
};
I have tried:
List<string> result = null;
for (int i = 0; i < arrayReading.Length; i++)
{
if (arrayReading[i].Contains("takefromhere"))
{
result.Add(arrayReading[i]);
if (!arrayReading[i + 1].Contains("dont'ttakefromhere"))
{
result.Add(arrayReading[i + 1]);
if (!arrayReading[i + 2].Contains("dont'ttakefromhere"))
{
rescription.Add(arrayReading[i + 1]);
}
}
}
}
Seems working but it's not really dynamic as I want it, because maybe I need to take 20 values between "takefromhere" and "don'ttakefromhere".
When querying you can try Linq:
using System.Linq;
...
List<string> result = arrayReading
.SkipWhile(item => item != "takefromhere")
.TakeWhile(item => item != "dont'ttakefromhere")
.ToList();
Or if you want good old loop solution:
List<string> result = new List<string>();
bool taking = false;
foreach (string item in arrayReading) {
if (!taking)
taking = item == "takefromhere";
if (taking) {
if (item == "dont'ttakefromhere")
break;
result.Add(item);
}
}
Let's have a look:
Console.Write(string.Join("; ", result));
Outcome:
takefromhere; keeptaking; keeptaking

C# reference array assignment issue

I'm having a little trouble reading values in from a database and assigning them to an array. It seem to work in my unit tests, but in practice some values are missing.
Here's my database code:
private void GetParameterValuesFromDatabase()
{
this.parameterValues = (from DataRow r in this.database.RunCommand("select * from KST_PARAM_VALUES v join DM_PARM_NAME p on v.PARM_NAME_KEY = p.PARM_NAME_KEY").Rows
where (int)r["SCENARIO_KEY"] == this.scenario.ScenarioKey
select new DatabaseParameter
{
ParameterValuesKey = r.Field<int>(0),
ProfileType = r.Field<string>(1),
ScenarioKey = r.Field<int>(2),
StressEditorKey = r.Field<int>(3),
StressClassKey = r.Field<int>(4),
PeriodKey = r.Field<int>(5),
ParameterNameKey = r.Field<int>(6),
ParameterValue = r.Field<double>(7),
ActiveStress = (r.Field<string>(8) == "Y") ? true : false,
ParameterKey = (int)r["PARM_NUMBER"]
}).ToDictionary(r => r.ParameterValuesKey, r => r);
}
Not having any issues with this part of my code, just showing for completeness.
private void LoadParameters()
{
this.GetParameterValuesFromDatabase();
// TODO: Assuming 9 periods for now, change to allow for variable periods
for (int i = 1; i <= MaxNumberOfStressPeriods; i++)
{
this.parametersByPeriod.Add(i, this.parameterValues.Where(t => t.Value.PeriodKey == i).ToDictionary(t => t.Key, t => t.Value));
}
Log.Instance.LogMessage(LogLevel.Debug, "Created parameter dictionaries from database");
// For every stress editor in the dictionary of stress editors
foreach (KeyValuePair<int, ClassList> ed in this.stressParams)
{
// For every type of class selector
foreach (ClassSelector c in Enum.GetValues(typeof(ClassSelector)))
{
// For each of the classes within each class list within the editor
for (int i = 0; i < ed.Value.ClassLists[c].Count; i++)
{
string className = ed.Value.ClassLists[c][i].Name;
// For each double array in each class
foreach (KeyValuePair<int, double[]> t in ed.Value.ClassLists[c][i].ClassVariables.EditorParameters)
{
double[] values = this.GetParameterValues(t.Key, ed.Key, className);
BasicStressEditorVariables.AddParameters(values, ed.Value, className, t.Key);
}
}
}
}
}
}
Above shows the overall LoadParameters() method.
Below we have some code that selects 9 values from the dictionary constructed from the database, ready to be added to the array.
private double[] GetParameterValues(int paramKey, int editorKey, string className)
{
double[] values = new double[9];
for (int i = 1; i <= MaxNumberOfStressPeriods; i++)
{
Dictionary<int, DatabaseParameter> temp = this.parametersByPeriod[i];
foreach (KeyValuePair<int, DatabaseParameter> d in temp)
{
if (d.Value.ParameterKey == paramKey && d.Value.PeriodKey == i && d.Value.StressEditorKey == editorKey && d.Value.ProfileType == className)
{
values[i - 1] = d.Value.ParameterValue;
}
}
}
return values;
}
Below shows getting the destination array from the dictionary, as indexes cannot be passed by reference
public static void AddParameters(double[] values, ClassList editor, string className, int paramKey)
{
// TODO: Maybe search all lists to eliminate the need for the class selector as a parameter
// TODO: Will throw an exception when nothing is found. Handle it
ParameterClass p = null;
foreach (ClassSelector c in Enum.GetValues(typeof(ClassSelector)))
{
p = editor.ClassLists[c].FirstOrDefault(f => f.Name == className);
if (p != null)
{
break;
}
}
// TODO: Notify that could not be found
if (p == null)
{
Log.Instance.LogMessage(LogLevel.Error, $"Unable to find class {className}");
return;
}
double[] dest = p.ClassVariables.editorParameters[paramKey];
AddParameterValues(values, ref dest);
}
And here's the AddParameterValues() method:
private static void AddParameterValues(double[] values, ref double[] destination)
{
if (values.Length != destination.Length)
{
return;
}
for (int i = 0; i < values.Length; i++)
{
destination[i] = values[i];
}
}
Debugging shows that some values are being loaded into the destination array, but some aren't. Could anyone tell me why this is? Or if not, point me toward some material?
Thank you for your time
I'm not that C# specialist but looking to following code as a C programmer
private double[] GetParameterValues(int paramKey, int editorKey, string className)
{
double[] values = new double[9];
//...
return values;
}
I would assume that the lifetime of values is only within the function GetParameterValues and the function GetParameterValues delivers the caller with reference to a dead variable.
What if you change the prototype to something like
private void GetParameterValues(ref double[] values, int paramKey, int editorKey, string className)

Set operation on a list of strings

I got a list of strings,on which I would like to do an operation which concats each item with rest of the items. The below test fails at the moment, I think the join is not the correct linq method I should be using- can you please let me know how to get this done? The pattern of the output should tell how the projection should be,if not the rule is simple:take one item and concatenate with all the other items and then move to the next item.Test below:
[Test]
public void Should_concatenate_all_items()
{
var items = new List<string> {"a", "b", "c", "d"};
var concatenatedList = items .Join(items , x => x, y => y, (x, y) => string.Concat(x, y));
foreach (var item in concatenatedList)
{
//Should output:ab
//Should output:ac
//Should output:ad
//Should output:bc
//Should output:bd
//Should output:cd
Console.WriteLine(item);
}
}
Note: I'm using .NET 3.5.
You could use something like this:
var concatenatedList =
from x in items.Select((str, idx) => new { str, idx })
from y in items.Skip(x.idx + 1)
select x.str + y;
Or in fluent syntax:
var concatenatedList =
items.Select((str, idx) => new { str, idx })
.SelectMany(x => items.Skip(x.idx + 1), (x, y) => x.str + y);
I think my solution may be overkill, but in real world situations it is probably more helpful. Also, I could not find a clean way to do it in Linq. Linq's Except does not seem suited for this.
You can use an IEnumerator to enumerate the values for you.
public class ConcatEnum : IEnumerator
{
public List<String> _values;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position1 = 0;
int position2 = 0;
public ConcatEnum(List<String> list)
{
_values = list;
}
public bool MoveNext()
{
position2 = Math.Max(position2 + 1, position1 + 1);
if (position2 > _values.Count - 1){
position1++;
position2 = position1 + 1;
}
return position1 < _values.Count - 1;
}
public void Reset()
{
position1 = 0;
position2 = 0;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public String Current
{
get
{
try
{
return _values[position1] + _values[position2];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public IEnumerator GetEnumerator()
{
this.Reset();
while (this.MoveNext())
{
yield return Current;
}
}
}
Call it like this:
var items = new List<string> { "a", "b", "c", "d" };
foreach (var i in new ConcatEnum(items))
{
//use values here
}
var concatenatedList = (from i in items
from x in items
where i != x
select string.Concat(i, x)).ToList();
For the exact output that you listed:
var concatenatedList = (from i in items
from x in items
where i != x && items.IndexOf(i) < items.IndexOf(x)
select string.Concat(i, x)).ToList();

Where can I find a _simple_, easy to understand implementation of an LR(1) parser generator?

Where can I find a simple (as much as possible, but no simpler!) implementation of an LR(1) parser generator?
I'm not looking for performance, just the ability to generate the LR(1) states (item sets).
C++, C#, Java, and Python would all work for me.
I've written a very simple one in C# and wanted to share it here.
It basically populates the action lookup table, which tells you which state to shift to or which rule to use for reduction.
If the number is nonnegative, then it denotes a new state; if it's negative, then its one's complement (i.e. ~x) denotes the rule index.
All you need now is to make a lexer and to do the actual parsing with the action table.
Note 1: It might be quite slow at generating the states for a real-world grammar, so you might want to think twice before using it in production code!
Note 2: You might want to double-check its correctness, since I've only checked it a bit.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using size_t = System.UInt32;
public class LRParser
{
private string[] symbols; // index => symbol
private IDictionary<string, size_t> interned = new SortedDictionary<string, size_t>(); // symbol => index
private int[/*state*/, /*lookahead*/] actions; // If >= 0, represents new state after shift. If < 0, represents one's complement (i.e. ~x) of reduction rule.
public LRParser(params KeyValuePair<string, string[]>[] grammar)
{
this.interned.Add(string.Empty, new size_t());
foreach (var rule in grammar)
{
if (!this.interned.ContainsKey(rule.Key))
{ this.interned.Add(rule.Key, (size_t)this.interned.Count); }
foreach (var symbol in rule.Value)
{
if (!this.interned.ContainsKey(symbol))
{ this.interned.Add(symbol, (size_t)this.interned.Count); }
}
}
this.symbols = this.interned.ToArray().OrderBy(p => p.Value).Select(p => p.Key).ToArray();
var syntax = Array.ConvertAll(grammar, r => new KeyValuePair<size_t, size_t[]>(this.interned[r.Key], Array.ConvertAll(r.Value, s => this.interned[s])));
var nonterminals = Array.ConvertAll(this.symbols, s => new List<size_t>());
for (size_t i = 0; i < syntax.Length; i++) { nonterminals[syntax[i].Key].Add(i); }
var firsts = Array.ConvertAll(Enumerable.Range(0, this.symbols.Length).ToArray(), s => nonterminals[s].Count > 0 ? new HashSet<size_t>() : new HashSet<size_t>() { (size_t)s });
int old;
do
{
old = firsts.Select(l => l.Count).Sum();
foreach (var rule in syntax)
{
foreach (var i in First(rule.Value, firsts))
{ firsts[rule.Key].Add(i); }
}
} while (old < firsts.Select(l => l.Count).Sum());
var actions = new Dictionary<int, IDictionary<size_t, IList<int>>>();
var states = new Dictionary<HashSet<Item>, int>(HashSet<Item>.CreateSetComparer());
var todo = new Stack<HashSet<Item>>();
var root = new Item(0, 0, new size_t());
todo.Push(new HashSet<Item>());
Closure(root, todo.Peek(), firsts, syntax, nonterminals);
states.Add(new HashSet<Item>(todo.Peek()), states.Count);
while (todo.Count > 0)
{
var set = todo.Pop();
var closure = new HashSet<Item>();
foreach (var item in set)
{ Closure(item, closure, firsts, syntax, nonterminals); }
var grouped = Array.ConvertAll(this.symbols, _ => new HashSet<Item>());
foreach (var item in closure)
{
if (item.Symbol >= syntax[item.Rule].Value.Length)
{
IDictionary<size_t, IList<int>> map;
if (!actions.TryGetValue(states[set], out map))
{ actions[states[set]] = map = new Dictionary<size_t, IList<int>>(); }
IList<int> list;
if (!map.TryGetValue(item.Lookahead, out list))
{ map[item.Lookahead] = list = new List<int>(); }
list.Add(~(int)item.Rule);
continue;
}
var next = item;
next.Symbol++;
grouped[syntax[item.Rule].Value[item.Symbol]].Add(next);
}
for (size_t symbol = 0; symbol < grouped.Length; symbol++)
{
var g = new HashSet<Item>();
foreach (var item in grouped[symbol])
{ Closure(item, g, firsts, syntax, nonterminals); }
if (g.Count > 0)
{
int state;
if (!states.TryGetValue(g, out state))
{
state = states.Count;
states.Add(g, state);
todo.Push(g);
}
IDictionary<size_t, IList<int>> map;
if (!actions.TryGetValue(states[set], out map))
{ actions[states[set]] = map = new Dictionary<size_t, IList<int>>(); }
IList<int> list;
if (!map.TryGetValue(symbol, out list))
{ map[symbol] = list = new List<int>(); }
list.Add(state);
}
}
}
this.actions = new int[states.Count, this.symbols.Length];
for (int i = 0; i < this.actions.GetLength(0); i++)
{
for (int j = 0; j < this.actions.GetLength(1); j++)
{ this.actions[i, j] = int.MinValue; }
}
foreach (var p in actions)
{
foreach (var q in p.Value)
{ this.actions[p.Key, q.Key] = q.Value.Single(); }
}
foreach (var state in states.OrderBy(p => p.Value))
{
Console.WriteLine("State {0}:", state.Value);
foreach (var item in state.Key.OrderBy(i => i.Rule).ThenBy(i => i.Symbol).ThenBy(i => i.Lookahead))
{
Console.WriteLine(
"\t{0}: {1} \xB7 {2} | {3} → {0}",
this.symbols[syntax[item.Rule].Key],
string.Join(" ", syntax[item.Rule].Value.Take((int)item.Symbol).Select(s => this.symbols[s]).ToArray()),
string.Join(" ", syntax[item.Rule].Value.Skip((int)item.Symbol).Select(s => this.symbols[s]).ToArray()),
this.symbols[item.Lookahead] == string.Empty ? "\x04" : this.symbols[item.Lookahead],
string.Join(
", ",
Array.ConvertAll(
actions[state.Value][item.Symbol < syntax[item.Rule].Value.Length ? syntax[item.Rule].Value[item.Symbol] : item.Lookahead].ToArray(),
a => a >= 0 ? string.Format("state {0}", a) : string.Format("{0} (rule {1})", this.symbols[syntax[~a].Key], ~a))));
}
Console.WriteLine();
}
}
private static void Closure(Item item, HashSet<Item> closure /*output*/, HashSet<size_t>[] firsts, KeyValuePair<size_t, size_t[]>[] syntax, IList<size_t>[] nonterminals)
{
if (closure.Add(item) && item.Symbol >= syntax[item.Rule].Value.Length)
{
foreach (var r in nonterminals[syntax[item.Rule].Value[item.Symbol]])
{
foreach (var i in First(syntax[item.Rule].Value.Skip((int)(item.Symbol + 1)), firsts))
{ Closure(new Item(r, 0, i == new size_t() ? item.Lookahead : i), closure, firsts, syntax, nonterminals); }
}
}
}
private struct Item : IEquatable<Item>
{
public size_t Rule;
public size_t Symbol;
public size_t Lookahead;
public Item(size_t rule, size_t symbol, size_t lookahead)
{
this.Rule = rule;
this.Symbol = symbol;
this.Lookahead = lookahead;
}
public override bool Equals(object obj) { return obj is Item && this.Equals((Item)obj); }
public bool Equals(Item other)
{ return this.Rule == other.Rule && this.Symbol == other.Symbol && this.Lookahead == other.Lookahead; }
public override int GetHashCode()
{ return this.Rule.GetHashCode() ^ this.Symbol.GetHashCode() ^ this.Lookahead.GetHashCode(); }
}
private static IEnumerable<size_t> First(IEnumerable<size_t> symbols, IEnumerable<size_t>[] map)
{
foreach (var symbol in symbols)
{
bool epsilon = false;
foreach (var s in map[symbol])
{
if (s == new size_t()) { epsilon = true; }
else { yield return s; }
}
if (!epsilon) { yield break; }
}
yield return new size_t();
}
private static KeyValuePair<K, V> MakePair<K, V>(K k, V v) { return new KeyValuePair<K, V>(k, v); }
private static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
var parser = new LRParser(
MakePair("start", new string[] { "exps" }),
MakePair("exps", new string[] { "exps", "exp" }),
MakePair("exps", new string[] { }),
MakePair("exp", new string[] { "INTEGER" })
);
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
LRSTAR 9.1 is a minimal LR(1) and LR(*) parser generator. You can use it to verify that your parser generator is giving the correct states, by using option '/s'. LRSTAR has been tested against HYACC and found to be giving the correct LR(1) states. 20 grammars are provided with LRSTAR and 6 Microsoft Visual Studio projects.

Categories

Resources