Need to find recurring values in array between two bounds - c#

I have this code to find recurring values in my array. I have 81 textboxs forming a grid, and they are in 9 rows of 9 boxes. I earlier on in my code saved them all to a one dimensional array with 81 elements. I found some of this code on another question: Finding duplicate integers in an array and display how many times they occurred, and it worked for me, but I cannot find which array element it actually was that recurred.
int[] OrigValues = new int[];//Already defined earlier, and assigned.
for (int c = 1; c <= 9; c++) //in this case, I called my int c instead of the usual i
{
Console.WriteLine("Row {0}:", c);
var dict = new Dictionary<int, int>();
foreach (var value in OrigValues.SubArray(c * 9 -9, 9))
{
if (dict.ContainsKey(value))
dict[value]++;
else
dict[value] = 1;
}
foreach (var pair in dict)
{
Console.WriteLine("Value {0} occurred {1} times.", pair.Key, pair.Value);
if (pair.Value >= 2 && pair.Key != 0)
{
//I have no way of finding which 2 array slots were the ones that had the same value in each of these rows.
}
}
}
OrigValues.SubArray is an extension method, that works like substring, except it is for arrays, taking array element starting at an index, and going for a length(there, c* 9 - 9 is my index, and 9 is my length)

You can turn this entire process into a LINQ query:
var duplicates =
OrigValues
.Select((value, index) => new
{
Coordinate = index,
Value = value
})
.GroupBy(tuple => tuple.Value)
.Where(group => group.Count() > 1)
.ToList();
foreach (var group in duplicates)
{
Console.Write($"{group.Key} appears in");
foreach (var tuple in group)
Console.Write($" {tuple.Coordinate}");
Console.WriteLine();
}

Related

C# looping through a list to find character counts

I'm trying to loop through a string to find the character, ASCII value, and the number of times the character occurs. So far, I have found each unique character and ASCII value using foreach statements, and finding if the value was already in the list, then don't add it, otherwise add it. However I'm struggling with the count portion. I was thinking the logic would be "if I am already in the list, don't count me again, however, increment my frequency"
I've tried a few different things, such as trying to find the index of the character it found and adding to that specific index, but i'm lost.
string String = "hello my name is lauren";
char[] String1 = String.ToCharArray();
// int [] frequency = new int[String1.Length]; //array of frequency counter
int length = 0;
List<char> letters = new List<char>();
List<int> ascii = new List<int>();
List<int> frequency = new List<int>();
foreach (int ASCII in String1)
{
bool exists = ascii.Contains(ASCII);
if (exists)
{
//add to frequency at same index
//ascii.Insert(1, ascii);
//get { ASCII[index]; }
}
else
{
ascii.Add(ASCII);
//add to frequency at new index
}
}
foreach (char letter in String1)
{
bool exists = letters.Contains(letter);
if (exists)
{
//add to frequency at same index
}
else
{
letters.Add(letter);
//add to frequency at new index
}
}
length = letters.Count;
for (int j = 0; j<length; ++j)
{
Console.WriteLine($"{letters[j].ToString(),3} {"(" + ascii[j] + ")"}\t");
}
Console.ReadLine();
}
}
}
I'm not sure if I understand your question but that what you are looking for may be Dictionary<T,T> instead of List<T>. Here are examples of solutions to problems i think you trying to solve.
Counting frequency of characters appearance
Dictionary<int, int> frequency = new Dictionary<int, int>();
foreach (int j in String)
{
if (frequency.ContainsKey(j))
{
frequency[j] += 1;
}
else
{
frequency.Add(j, 1);
}
}
Method to link characters to their ASCII
Dictionary<char, int> ASCIIofCharacters = new Dictionary<char, int>();
foreach (char i in String)
{
if (ASCIIofCharacters.ContainsKey(i))
{
}
else
{
ASCIIofCharacters.Add(i, (int)i);
}
}
A simple LINQ approach is to do this:
string String = "hello my name is lauren";
var results =
String
.GroupBy(x => x)
.Select(x => new { character = x.Key, ascii = (int)x.Key, frequency = x.Count() })
.ToArray();
That gives me:
If I understood your question, you want to map each char in the provided string to the count of times it appears in the string, right?
If that is the case, there are tons of ways to do that, and you also need to choose in which data structure you want to store the result.
Assuming you want to use linq and store the result in a Dictionary<char, int>, you could do something like this:
static IDictionary<char, int> getAsciiAndFrequencies(string str) {
return (
from c in str
group c by Convert.ToChar(c)
).ToDictionary(c => c.Key, c => c.Count());
}
And use if like this:
var f = getAsciiAndFrequencies("hello my name is lauren");
// result: { h: 1, e: 3, l: 3, o: 1, ... }
You are creating a histogram. But you should not use List.Contains as it gets ineffective as the list grows. You have to go through the list one item after another. Better use Dictionary which is based on hashing and you go directly to the item. The code may look like this
string str = "hello my name is lauren";
var dict = new Dictionary<char, int>();
foreach (char c in str)
{
dict.TryGetValue(c, out int count);
dict[c] = ++count;
}
foreach (var pair in dict.OrderBy(r => r.Key))
{
Console.WriteLine(pair.Value + "x " + pair.Key + " (" + (int)pair.Key + ")");
}
which gives
4x (32)
2x a (97)
3x e (101)
1x h (104)
1x i (105)
3x l (108)
2x m (109)
2x n (110)
1x o (111)
1x r (114)
1x s (115)
1x u (117)
1x y (121)

Conditionally sum values in a list of tuples

Hello what I'm trying to do is hopefully simple, I have a List<tuple>(string, decimal) and I'm trying to grab the sum of the decimal values if there are two similar strings.
My list contains the values:
("q", .5)
("w", 1.5)
("e", .7)
("r", .8)
("q", .5)
The sum of all the values would therefore be .5 + 1.5 + .7 + .8 + .5 = 4.0.
I assume the algorithm would be something like this:
newlist.select(item1 , item2).where(get the sum of first "q" up to the next "q" in list)
As for existing code, I don't have much only the declaration of the list and it's values.
**I want the sum between 'q' and 'q' + the values of 'q' and 'q', not just in-between, the answer should be '4' and not 3, I want everything between q and q including q's values, thank you.
You could use simple Linq extensions, SkipWhile and TakeWhile
List<Tuple<string,double>> items = new List<Tuple<string,double>>()
{
new Tuple<string,double>("q", .5),
new Tuple<string,double>("w", 1.5),
new Tuple<string,double>("e", .7),
new Tuple<string,double>("r", .8),
new Tuple<string,double>("q", .5)
};
var sumvalue = items.Sum(c=>c.Item2); // Calculates sum of all values
var betweensum = items.SkipWhile(x=>x.Item1 == "q") // Skip until matching item1
.TakeWhile(x=>x.Item1 != "q") // take until matching item1
.Sum(x=>x.Item2); // Sum
As asked in the comments, in case if you have multiple such sets and you want count in between those matching strings for multiple sets, do this.
int gid = 0;
items.Select(c => new { Tuple = c, gid = c.Item1=="q"? ++gid : gid })
.GroupBy(x=>x.gid)
.Where(x=>x.Key%2==1)
.SelectMany(x=>x.Skip(1))
.Sum(x=>x.Tuple.Item2);
Working Demo
You can add a new IEnumerable extension to get all values between two conditions. Note that if there is no second occurrence of the condition an empty list is returned, this can be edited based on your requirements:
public static class Extensions
{
public static IEnumerable<T> TakeBetween<T>(this IEnumerable<T> e, Func<T, bool> f)
{
bool first = false;
List<T> ret = new List<T>();
foreach (var item in e)
{
if(f(item) && !first)
{
first = true;
ret.Add(item);
continue;
}
if(first)
{
ret.Add(item);
if(f(item))
return ret;
}
}
return new List<T>();
}
}
Then it is just a matter of using this to get the sum:
var sum = list.TakeBetween(x => x.Item1 == "q").Sum(x => x.Item2);

Iterating through dictionary and doing some stuff

is it possible to iterat through dictionary like this?
I want to count all dictionary items (sum every Value),
Next, for each Key I want to take their Value
Then, I want to divide every EACH Key Value with sum
And lasty I want to multiply every output from 3
I made it so it works with 1 item, but not sure how to make it so it works with every item in dictionary.
Here is sample code for 1 item:
var dic = new Dictionary<string, int>();
//this is sum
double y = 0;
foreach (var item in dic)
{
y += item.Value;
}
//this is selected item
double x = 0;
foreach (var item in dic)
{
if (item.Key == "Smith")
{
x = item.Value;
}
}
double z = 0;
z = x / y;
Console.WriteLine("Smith/DicSum: " + z);
Now I would like to multiply the Z's (each Z's for each key in dictionary).
I was thiking about making one big loop for this like:
for (int i=0; i<y; i++) where y is the sum for all items in dictionary and multiply z's on the end of the loop
but I still don't know how to grab all seperate values and divide them while not saying the specific key for each of them.
#edit
Thanks for answears but check my edit. I have a string list, let's say
"Smith is very cool member of Smith Company"
And my program is counting the number of Smith's, so it will show x as two. Then I want to divide snumber of smiths (two) by number of all words, so it's 2/8 = 0,25. Then I want to do this with every word and multiply it so it will be 2/8*1/8*...*1/8 in this example. SO I want to multiply by a preious number from loop (from dictionary), and not by a fixed amount, that's what making this problem.
var words = "Smith is very cool member of Smith Company"
.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var dic = new Dictionary<string, double>();
foreach (string word in words)
{
if (dic.ContainsKey(word))
dic[word]++;
else
dic[word] = 1;
}
var sum = dic.Sum(x => x.Value);
var result = dic.Values.Aggregate(1.0, (current, item) => current * (item / sum));

Need to add each number 0-x to end of line?

I'm making an app and I'm almost done. I just need to know how I can streamread a txt list and foreach line, add numbers 0-x (x will be the number the user puts in the textbox) and add it to a list. So basically, it would be like this
You import a list with 'dog' on one line, 'cat' on another, and 'fish' on the third. You type '5' into the textbox. the app puts all this into a list:
dog1
dog2
dog3
dog4
dog5
cat1
cat2
cat3
cat4
cat5
fish1
fish2
fish3
fish4
fish5
thanks!
The code below should work for you. I assume you can acquire the count value on your own.
var animals = File.ReadAllLines("yourFile.txt"); //new[] {"dog", "cat", "fish"};
var count = 5;
var merged =
from a in animals
from n in Enumerable.Range(1, count)
select a + n;
foreach (var m in merged)
Console.WriteLine(m); //act on each however you want
You can read a text file with File.ReadAllLines. This gives you an array you can iterate over with foreach.
In this foreach loop you can perform another loop from 1 to the number the user entered. int.Parse comes in handy for converting the string the user entered into a number C# can do something with. For the actual iteration you can use a for loop.
You can then add each item to a list.
There is a good example for reading each line in a filestream here: http://msdn.microsoft.com/en-us/library/e4y2dch9.aspx
private List<string> GetThings(string fileName, int count)
{
string[] lines = File.ReadAllLines(fileName);
List<string> result = new List<string>();
foreach (string item in lines)
{
for (int i = 1; i <= count; i++)
result.Add(item + i.ToString());
}
return result;
}
string[] inputList = File.ReadAllLines("yourFile.txt");
List<String> listOfThings = new List<String>();
foreach (string i in inputList)
{
for (int k = 0; k < 5; k++)
{
listOfThings.Add(i + " " + k.ToString());
}
}
then after that, you can print out the list like this:
foreach (string outp in listOfThings)
{
Console.WriteLine(outp);
}
output:
some value 0
some value 1
some value 2
some value 3
some value 4
some other value 0
some other value 1
some other value 2
some other value 3
some other value 4

Looping through x number of arrays

How do I loop through x number of arrays and visit all combinations of all cells in all of the arrays? The problem here is there can be x number of arrays of some items inside. For instance,
List<List<string>> _arrays = GetArrayInformation();
I want to compare all the string inside each array with all the other arrays and the strings inside of each array. Do I use while like
while(i < _arrays.Count)
Thanks for your answer. The answer seems simple but when you think about it is kind of tricky and hard.
Update:
Thanks for your answers. I can do this with a 3 arrays like
for(int i = 0; i < _arrays[0].Count; i++) {
for(int l = 0; l < _arrays[1].Count; l++) {
for(int m = 0; m < _arrays[2].Count; m++) {
string _hello = _arrays[0][i] + "|" + _arrays[1][l] + "|" + _arrays[2][m];
}
}
}
Because I have dynamic number of arrays, it gets tricky.
foreach(var array in _arrays)
{
foreach(var s in array)
{
foreach(var otherArray in _arrays)
{
if(otherArray == array) continue;
if(otherArray.Contains(s)) {} // not sure what you want to do
}
}
}
this will loop through every single string seeing if it is in any other array.... it's the straightforward approach, but not very efficient and will duplicate work.
There is no enough information is here
If you need to find elements that exists in few array You will use something like this:
var multipleWords = _arrays
.SelectMany(items => items.Distinct())
.GroupBy(item => item)
.Select(group => new {Item = group.Key, Count = group.Count()})
.Where(item => item.Count > 1)
.Select(item => item.Item)
.ToArray();
multipleWords will contain each word from the all these arrays that exists in two or more arrays
You could use a recursive search function.
public Search<T>(object o, string comparestring)
{
if(o is List<string>)
{
//Compare to your string
}
else
{
//Call this search function with the type of the object in the list.
//Will iterate through all of your strings recursively.
Type t = o.GetType().GetGenericArguments()[0];
foreach( object osub in (T)o)
Search<t>( ((t)o),comparestring)
}
}

Categories