Reputation: 187
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.
Upvotes: 1
Views: 79262
Reputation: 1
int number = 0;
int[] arr = {1,7,8,8,8,8,1,1,2,1,5,1,2,5,5,5,5,5,};
bool containsNumber = false;
List<int> existingElements = new List<int>();
for(int i = 0; i < arr.Length; i++)
{
for(int j = 0; j < existingElements.Count; j++){
if(arr[i] == existingElements[j]) {
containsNumber = true;
break;
}
}
if(containsNumber)
{
containsNumber = false;
continue;
}
for(int k = 0; k < arr.Length; k++)
{
if(arr[i] == arr[k])
{
number++;
}
}
existingElements.Add(arr[i]);
Console.WriteLine ("The number "+ arr[i] +" appears "+ number +" Times");
number = 0;
}
Upvotes: -1
Reputation: 11
I think the question hasn't been answered without using lists, LINQ or Dictionary so here is my suggestion:
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
class Program
{
static void Main()
{
int n = int.Parse(Console.ReadLine()); // the size of the array
int[] ints = new int[n]; //an array to store the items, integers in this case
int[] freq = new int[n]; //an array to store the frequency of each element with the same index
for (int i = 0; i < n; i++) // a loop that takes each element on a new row
{
ints[i] = int.Parse(Console.ReadLine());
}
for (int j = 0; j < n; j++) // loops to iterate through the ints array and pick up the
// frequencies and store them in the freq array
{
for (int k = 0; k < n; k++)
{
if (ints[j] == ints[k] && k != n)
{
freq[j]++;
}
}
}
int indexAtMax = freq.ToList().IndexOf(freq.Max()); //this picks up the index of the first maximum count
int mostFrequentNumber = ints[indexAtMax]; // the actual number behind the same inex in the ints array
int frequencyOfRepeating = freq[indexAtMax]; // the actual number of the frequency
Console.WriteLine($"The most frequent number is:{mostFrequentNumber} and it repeats {frequencyOfRepeating} times)");
}
}
Upvotes: 0
Reputation: 5596
static void Main(string[] args)
{
int[] arr = new int[] { 45, 34, 23, 67, 10, 99,99,10 };
foreach(int i in arr.Distinct())
{
int count = occurance(arr,i);
Console.WriteLine(i + "-Occurred For :" + count);
}
Console.ReadLine();
}
public static int occurance(int[] arr,int x)
{
int count = 0;
foreach(int num in arr)
{
if(x==num)
{
count++;
}
}
return count;
}
}
Upvotes: 0
Reputation: 31
This is the naive Solution for finding " Counting the number of times a value appears in an array " Idea : Build a Hash map in Array Solution :
using System.Collections.Generic;
using System.Text;
namespace GetArrEleFrequency
{
class Program
{
static int[] Arr = new int[5] { 3, 3, 0, 2, 0 };
static int[] Key = new int[5];
static int[] value = new int[5];
static void Main(string[] args)
{
int keyItr = -1, ValueItr = -1, tempIndex = 0, tempValue = 0;
for (int i=0; i <= Arr.Length-1;i++) {
if (!(isPresent(Arr[i]))) {
keyItr += 1;ValueItr += 1;
Key[keyItr] = Arr[i];
value[ValueItr] = 1;
} else {
value[tempIndex] = value[getIndex(Arr[i])] + 1;
}
}
for (int i=0;i<=Key.Length-1;i++) {
Console.WriteLine(Key[i] + "-" + value[i]);
}
Console.ReadKey();
}
public static Boolean isPresent(int num) {
Boolean temp = false;
for (int i=0; i <= Key.Length-1;i++) {
if (Key[i] == num) {
temp = true;
break;
} else {
temp = false;
}
}
return temp;
}
public static int getIndex(int num) {
int temp = 0;
for (int i=0;i<=Key.Length-1;i++) {
if (Key[i] == num) {
break;
} else {
temp += 1;
}
}
return temp;
}
}
}
Output :
3 - 2
0 - 2
2 - 1
0 - 0
0 - 0
Upvotes: 0
Reputation: 1144
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.
Upvotes: 0
Reputation: 50189
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
Upvotes: 8
Reputation: 13207
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.
Upvotes: 4
Reputation: 10257
your count array has 4 fields ...
one with the index 0, 1, 2 and 3
so what will happen if a number like 4 (or greater) happens to be counted? yor code tries to access index 4 ... which does not exist ...
Upvotes: 0