Counting the number of times a value appears in an array
Solution 1
You're getting an index out of bounds error because of this section:
for (i = 0; i < SIZE - 1; i++)
{
if (numbers[i] > 0 && numbers[i] < SIZE)
{
x = Count[i];
Notice that you're iterating through 0
to SIZE - 1
(11
) when Count
only has a size of 4
.
You can do this task pretty easily with LINQ though.
int[] numbers = new int[SIZE] { 5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1 };
var count = numbers
.GroupBy(e => e)
.Where(e => e.Count() == 4)
.Select(e => e.First());
So it groups the numbers by their value, we then refine the list to only include groups of 4, then select the first of each to be left with a collection of int
s.
Here is a non-LINQ based solution using a Dictionary to store the count of numbers.
int[] numbers = new int[SIZE] { 5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1 };
var dictionary = new Dictionary<int, int>();
var numbersWithFour = new List<int>();
foreach (var number in numbers)
{
if (dictionary.ContainsKey(number))
dictionary[number]++;
else
dictionary.Add(number, 1);
}
foreach (var val in dictionary)
{
if (val.Value == 4)
{
numbersWithFour.Add(val.Key);
}
}
With a little modification to your program you can get some results.
int[] numbers = new int[SIZE] { 5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1 };
string[] letters = new string[SIZE] { "m", "m", "s", "m", "s", "s", "s", "m", "s", "s", "s", "s" };
int[] values = new int[SIZE] { 15, 22, 67, 45, 12, 21, 24, 51, 90, 60, 50, 44 };
string[] status = new string[SIZE] { "f", "m", "f", "a", "m", "f", "f", "f", "m", "f", "m", "f" };
// Set the size of Count to maximum value in numbers + 1
int[] Count = new int[9 + 1];
int x = 0;
int i = 0;
for (i = 0; i < SIZE - 1; i++)
{
if (numbers[i] > 0 && numbers[i] < SIZE)
{
// Use value from numbers as the index for Count and increment the count
Count[numbers[i]]++;
}
}
for (i = 0; i < Count.Length; i++)
{
// Check all values in Count, printing the ones where the count is 4
if (Count[i] == 4)
Console.WriteLine("{0}", i);
}
Output:
7
9
Solution 2
Use LINQ
to do the work
using System.Linq;
var numQuery =
from num in numbers
where num == 5
select num;
Console.WriteLine("Count of 5: " + numQuery.Count);
Or use the method syntax
var numQuery = numbers.Where(num => num == 5);
Console.WriteLine("Count of 5: " + numQuery.Count);
See here for the overview and here for query vs method
-syntax.
Found a sample for GroupBy
, look here.
Solution 3
I used Regex for my solution since I only had three values.
String results = "" + one.ToString() + " " + two.ToString() + " " + three.ToString();
int count1 = Regex.Matches(results, @one.ToString()).Count;
int count2 = Regex.Matches(results, @two.ToString()).Count;
int count3 = Regex.Matches(results, @three.ToString()).Count;
Seems 'hacky', but worked for me. It'll work with strings or numbers but only if you're working with a few values. Pretty efficient in that case. If not, I think the other answer would be a better option.
Sabotenderizer
Updated on January 13, 2022Comments
-
Sabotenderizer over 2 years
So what's a good, simple algorithm to create a loop in C# where every time a certain value appears in an array it adds 1 to a counter in another array?
For example I have this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication22 { class Program { const int SIZE = 12; static void Main(string[] args) { int[] numbers = new int[SIZE] {5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1}; string[] letters = new string[SIZE] { "m", "m", "s", "m", "s", "s", "s", "m", "s", "s", "s", "s" }; int[] values = new int[SIZE] {15, 22, 67, 45, 12, 21, 24, 51, 90, 60, 50, 44}; string[] status = new string[SIZE] { "f", "m", "f", "a", "m", "f", "f", "f", "m", "f", "m", "f" }; int[] Count = new int[4]; int x = 0; int i = 0; for (i = 0; i < SIZE - 1; i++) { if (numbers[i] > 0 && numbers[i] < SIZE) { x = Count[i]; Count[x]++; } } for (i = 0; i < 4; i++) { Console.WriteLine("{0}", Count[4]); } } } }
I am only counting the number of times 4 numbers appear in the numbers array. Someone suggested I use the method in the first loop but it doesn't seem to be working and creates an error that the index is out of bounds in the array. I want to display the number of times each of those numbers(5, 7,9 and 1) appear in 4 rows.
EDIT: Without using LINQ or any other fancy thing like Dictionary or whatever.
-
Matthew Watson about 11 yearsThis is for research/homework, so you must use a loop? If so, better say so else you'll get a million answers all about using Linq.
-
-
Destrictor about 11 yearsThis would only show the number of times one number would appear. He wants to see them all at once, so use
GroupBy
for that. -
Sabotenderizer about 11 yearsI'm not allowed to use those yet. )=
-
Sabotenderizer about 11 yearsI put 4 because there are only 4 different numbers. I would like to display how many times each number appears.
-
Sabotenderizer about 11 yearsPrinting the ones where the count is 4? Hmm how about printing how many times each number appears?
-
Daniel Imms about 11 yearsThen change it to
Console.WriteLine("{0}", Count[i]);
you would need to remove theif (Count[i] == 4)
for them all to show up though. -
Daniel Imms about 11 yearsThe best would be combining both:
Console.WriteLine("{0}: {1}", i, Count[i]);
-
Sabotenderizer about 11 yearsThanks, but one more thing =). Exactly how does Count[numbers[i]]++; work? How are the arrays entangled together in that way to count the number of times a value appears?
-
Daniel Imms about 11 yearsWe use
numbers[i]
as an index forCount[]
and then add one to the value inCount[]
using the post-increment operator++
. It could also be done like thisCount[numbers[i]] += 1