Looping through a large array and adding the values together C# - c#

I'm trying to loop through an array of 180 elements and add the first 60 elements together and store it in a list. Then add the next 60 elements together and store them in the list and repeat that for the final 60. So far my code will only add the first 60 and store them in the list. the problem seems to be the "i % 60 == 0" in the else if statement but I'm not sure why
Random r = new Random();
int[] arr = new int[180];
List<int> MyList = new List<int>();
int[] array2 = new int[2];
//intialize random numbers in 60 length array
for (int i = 0; i < arr.Length; i++)
{
arr[i] = r.Next(1, 10);
}
int score = 0;
//looping through arr
for (int i = 0; i < arr.Length; i++)
{
if (i % 60 != 0 || i == 0 )
{
score = score + arr[i];
i++;
}
else if (i % 60 == 0 && i != 0)
{
//adding the values to a list
MyList.Add(score);
//resetting score after score is added to the list
score = 0;
}
}
// converting list to my second array
array2 = MyList.ToArray();
//printing values in array
for (int i = 0; i < array2.Length; i++)
{
Console.WriteLine(array2[i]);
}

Your original loop and conditions have several problems and actually need to be:
int score = 0;
for (int i = 0; i < arr.Length; i++)
{
score = score + arr[i];
if ((i + 1) % 60 == 0)
{
MyList.Add(score);
score = 0;
}
}
But I strongly advise you to use much simpler LINQ approach (instead of doing all the stuff manually):
var array2 = new[]
{
arr.Take(60).Sum(),
arr.Skip(60).Take(60).Sum(),
arr.Skip(120).Sum()
};

Related

Count the number of occurrences in an array with random numbers without methods or list in C#

I am trying to solve an exercise in C# as follows:
Write a program that generates 20 random integers between 0 and 9 and displays the count for each number.
Use an array of ten integers, say counts, to store the counts for the number of 0s, 1s, ..., 9s.)
This is what i come up with which kind of work but i have a problem with the 0's counting 1 extra all the time.
using System.Collections.Generic;
using System.Text;
namespace ArrayExercises
{
class TaskFive
{
public static void FindNumberCount()
{
int c0=0,c1=02,c2=0,c3=0,c4=0,c5=0,c6=0,c7=0,c8=0,c9=0;
int[] arr = new int[20];
Random rand = new Random();
Console.WriteLine("Numbers generated ");
for (int i = 0; i < 19; i++)
{
arr[i] = rand.Next(0, 10);
Console.WriteLine(arr[i]);
}
foreach(int number in arr)
{
if (number == 0) { c0++; }
else if (number == 1) { c1++; }
else if (number == 2) { c2++; }
else if (number == 3) { c3++; }
else if (number == 4) { c4++; }
else if (number == 5) { c5++; }
else if (number == 6) { c6++; }
else if (number == 7) { c7++; }
else if (number == 8) { c8++; }
else if (number == 9) { c9++; }
}
Console.WriteLine
(
$"Number of 0's: {c0} \n" +
$"Number of 1's: {c1} \n" +
$"Number of 2's: {c2} \n" +
$"Number of 3's: {c3} \n" +
$"Number of 4's: {c4} \n" +
$"Number of 5's: {c5} \n" +
$"Number of 6's: {c6} \n" +
$"Number of 7's: {c7} \n" +
$"Number of 8's: {c8} \n" +
$"Number of 9's: {c9}"
);
}
}
}
Thanks in advance :)
You could shorten it like this
public static void FindNumberCount()
{
int[] count = new int[10];
Random rand = new Random();
int[] arr = new int[20];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = rand.Next(0, 10);
Console.WriteLine(arr[i]);
count[arr[i]]++;
}
for (int i = 0; i < count.Length; i++)
{
Console.WriteLine($"Number of {i}'s: {count[i]}");
}
}
If you want draw 20 numbers you should for (int i = 0; i < 20; i++) not 19.
int[] counts = new int[10];
int[] numbers = new int[20];
var random = new Random();
for (int i = 0; i < numbers.Length; i++)
{
// Generate random numbers
numbers[i] = random.Next(0, 9);
// Increment the count of the generated number
counts[numbers[i]]++;
}
the for loop you use loops only 19 times.
You must change the "i < 19" to "i < 20".
In your program, the for loop leaves the last int in the array at it's default value (0),
this also explains, why you always have one more zero.
Hope this helped.
The issues is in this line
for (int i = 0; i < 19; i++)
You initialized an array with 20 int and set only value to 19 of them.
If you don't set the value int defaults to Zero and hence you always get one extra zero
Change your code as below
for (int i = 0; i <= 19; i++)
The halting condition of the first for loop should be i<20. Then your program should work.
This is how I would solve it:
static void Main(string[] args)
{
Random random = new Random();
//Fill array with random numbers
int[] array = new int[20];
for (int i = 0; i < array.Length; i++)
array[i] = random.Next(0, 10);
//Count how many times a number occurs
int[] numberCounts = new int[10];
for (int i = 0; i < array.Length; i++)
numberCounts[array[i]]++;
//Print the count of the numbers
for(int i = 0; i < numberCounts.Length; i++)
Console.WriteLine("Number of " + i + "'s: " + numberCounts[i]);
//Keep the console open
Console.ReadLine();
}

Trying to find Frequency of elements in array

I am trying to count how many times a number appears in an array 1 (a1) and then trying to print out that number by storing it in array 2 (a2) just once and then try to print array 2. But first using for loop and a function, I will check that if a number already exist in array 2 then move to next index in array 1, unfortunateley this code is not working; can someone please help me in trying to fix it, I don't need some complex solutions like dictionaries or lists athe moment, although it might be helpful too. thanks, I am not an expert in programming and I try to practise it in my free time, so please help me.
I just want this code to be fixed for my understanding and knowledge
class Program
{
static void Main(string[] args)
{
int i, j;
int[] a1 = new int[10];
int[] a2 = new int[10];
int[] a3 = new int[10];
//takes an input
for (i = 0; i < a1.Length; i++)
{
a1[i] = Convert.ToInt32(Console.ReadLine());
}
for (i = 0; i < a1.Length; i++)
{
Cn(a1, a2); //calls in function
i++; //increments is if true
int count = 0;
for (j = 0; j < a1.Length; j++)
{
//if a number matches with a number in second array
if (a1[i] == a1[j])
{
//do count ++
count++;
// store that number into second array
a2[i] = a1[i];
}
}
//store the number of counts in third array
a3[i] = count;
}
for (i = 0; i < a2.Length; i++)
{
if (a2[i] != 0)
{
Console.WriteLine(a2[i]);
}
}
Console.ReadLine();
}
//function to check if element at current index of array 1 exists in array 2 if yes than break
public static void Cn (int[] aa1, int [] aa2)
{
int k, j;
for ( k = 0; k < aa1.Length; k++)
{
for (j = 0; j < aa2.Length; j++)
{
if (aa1[k] == aa2[j])
break;
}
}
}
}
You probably want to do a group by count:
int[] a1 = new int[10];
var rnd = new Random();
//takes an input
for (int i = 0; i < a1.Length; i++)
{
a1[i] = Convert.ToInt32(rnd.Next(0, 11)); // or Console.ReadLine()
}
var grouped = a1
.GroupBy(x => x)
.Select(g => new
{
Item = g.Key,
Count = g.Count()
}).ToList(); // ToList() is optional, materializes the IEnumerable
foreach (var item in grouped)
{
Console.WriteLine($"number: {item.Item}, count: {item.Count}");
}
This uses a Hash algorithm internally.
You can solve this without a Hash or Dictionary but it wouldn't be very efficient because you need to do lots of linear searches through the arrays.
The advantage of a Hash algorithm is that your lookups or groupings are much faster than if you loop over a complete array to find / increment an item.

Random number in loop

My function return the same number sequence.
When i give on input list with first list[0] all 0 and second list[1] all 1, i get on the output list e.g:
1 1 1 1 0 1 1
1 1 1 1 0 1 1
And all the time generate sequence on the output is the same.
I mean temp[0] and temp[1] have the same sequence
public List<float[][][]> rozmnarzanie(List<nur> list,Random dnd)
{
float[][][] ftemp=net.wagi;
List<float[][][]> temp = new List<float[][][]>();
for (int i = 0; i < 2; i++)
{
for (int a = 0; a < net.wagi.Length; a++)
{
for (int j = 0; j < net.wagi[a].Length; j++)
{
for (int k = 0; k < net.wagi[a][j].Length; k++)
{
if(dnd.Next(0,100)<=50)
{
ftemp[a][j][k] = list[0].listawagi[a][j][k];
}
else
{
ftemp[a][j][k] = list[1].listawagi[a][j][k];
}
}
}
}
temp.Add(ftemp);
}
return temp;
}
I mean temp[0] and temp[1] have the same sequence
Correct. You add the same array twice, temp[0] and temp[1] are both references to the same location in memory. What you see are the results of the last run. The same result will show up in net.wagi .
Your question isn't about random numbers but about arrays being reference types.
I don't know what net.wagi is but the solution could look something like:
//float[][][] ftemp=net.wagi;
List<float[][][]> temp = new List<float[][][]>();
for (int i = 0; i < 2; i++)
{
float[][][] ftemp = new float[a][b][c]; // pseudo code
...
temp.Add(ftemp);
}
You figure out the a, b and c.

Strand sort in c# using arrays only

i have a homework using strand sort and i must take the growing sequence of numbers from the initial array and merge them together in the array that represents our result (C#)
Like this one http://imgur.com/nQFzJw7
So far i did something like that
public static int[] Str(int[] a)
{
int i, j, x ,temp,k=0,count=1;
int size = a.Length;
int len = a.Length;
Strand = new int[size];
Merged = new int[size];
for (i = k; i < size; i++)
{
x = a[i];
Strand[0] = x;
for (i = k; i < size; i++) //checking if there's a bigger int than the first one
{
if (a[i] > x)
{
x = a[i];
}
}
for (i = k; i < len; i++)
{
if (a[i] == x) // checking if the max appears more than 1 time
{
temp = a[i];
a[i] = a[len];
a[len] = temp;
len--; //swaps the max numbers to the last position
Strand[count] = x;
count++;
}
}
for (i = 0; i < count; i++) // cant find a way to put in the final merged and sorted array
{
}
count = 1;
k++;
}
Any suggestions?
You always need to extract the first element into strand
strand[0] = a[0]
count = 1
Then you need to extract suitable elements into strand, shifting the rest of array
for i = 1 to size - 1
if a[i] >= strand[count - 1]
strand[count++] = a[i]
else
a[i - count] = a[i]
size = size - count
Then you need merge current strand and merged - look for Merge procedure from MergeSort
Repeat these steps until size becomes 0

Order an array in a specific order

I have this array of integers:-
int[] numbers = new int[] { 10, 20, 30, 40 };
I am trying to create an array which will have first element, last element, second element, second-last element and so on..
So, my resulting output will be:-
int[] result = {10,40,20,30};
This was my approach, in one loop start from first and go till the middle & in second loop start from last and get to the middle and select items accordingly, but I totally messed it up. Here is my attempted code:-
private static IEnumerable<int> OrderedArray(int[] numbers)
{
bool takeFirst = true;
if (takeFirst)
{
takeFirst = false;
for (int i = 0; i < numbers.Length / 2; i++)
{
yield return numbers[i];
}
}
else
{
takeFirst = true;
for (int j = numbers.Length; j < numbers.Length / 2; j--)
{
yield return numbers[j];
}
}
}
Need Help.
You might try this:
int[] result = numbers.Zip(numbers.Reverse(), (n1,n2) => new[] {n1, n2})
.SelectMany(x =>x)
.Take(numbers.Length)
.ToArray();
Explanation: This approach basically pairs up the elements of the original collection with the elements of its reverse ordered collection (using Zip). So you get a collection of pairs like [first, last], [second, second from last], etc.
It then flattens those collection of pairs into a single collection (using SelectMany). So the collection becomes [first, last, second, second from last,...].
Finally, we limit the number of elements to the length of the original array (n). Since we are iterating through twice as many elements (normal and reverse), it works out that iterating through n elements allow us to stop in the middle of the collection.
As a different approach, this is a modification on your existing method:
private static IEnumerable<int> OrderedArray(int[] numbers)
{
var count = (numbers.Length + 1) / 2;
for (int i = 0; i < count; i++)
{
yield return numbers[i];
int reverseIdx = numbers.Length - 1 - i;
if(i != reverseIdx)
yield return numbers[reverseIdx];
}
}
ok,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var length = source.Count;
var limit = length / 2;
for (var i = 0; i < limit; i++)
{
yield return source[i];
yield return source[length - i - 1];
}
if (length % 2 > 0)
{
yield return source[limit];
}
}
}
Which you could use like this,
var result = numbers.EndToEnd().ToArray();
more optimally,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var c = source.Count;
for (int i = 0, f = 0, l = c - 1; i < c; i++, f++, l--)
{
yield return source[f];
if (++i == c)
{
break;
}
yield return source[l];
}
}
}
no divide or modulus required.
With a simple for;
int len = numbers.Length;
int[] result = new int[len];
for (int i = 0, f = 0, l = len - 1; i < len; f++, l--)
{
result[i++] = numbers[f];
if (f != l)
result[i++] = numbers[l];
}
Based on Selman22's now deleted answer:
int[] numbers = new int[] { 10, 20, 30, 40 };
int[] result = numbers
.Select((x,idx) => idx % 2 == 0
? numbers[idx/2]
: numbers[numbers.Length - 1 -idx/2])
.ToArray();
result.Dump();
(The last line is LinqPad's way of outputting the results)
Or in less LINQy form as suggested by Jeppe Stig Nielsen
var result = new int[numbers.Length];
for (var idx = 0; idx < result.Length; idx++) {
result[idx] = idx % 2 == 0 ? numbers[idx/2] : numbers[numbers.Length - 1 -idx/2];
}
The principle is that you have two sequences, one for even elements (in the result) and one for odd. The even numbers count the first half of the array and the odds count the second half from the back.
The only modification to Selman's code is adding the /2 to the indexes to keep it counting one by one in the right half while the output index (which is what idx basically is in this case) counts on.
Came up with this
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 10, 20, 30, 40, 50, 60, 70};
List<int> numbers2 = new List<int>();
int counter1 = 0;
int counter2 = numbers.Count - 1;
int remainder = numbers.Count % 2 == 0 ? 1: 0;
while (counter1-1 < counter2)
{
if (counter1 + counter2 % 2 == remainder)
{
numbers2.Add(numbers[counter1]);
counter1++;
}
else
{
numbers2.Add(numbers[counter2]);
counter2--;
}
}
string s = "";
for(int a = 0; a< numbers2.Count;a++)
s+=numbers2[a] + " ";
Console.Write(s);
Console.ReadLine();
}
This late answer steals a lot from the existing answers!
The idea is to allocate the entire result array at once (since its length is known). Then fill out all even-indexed members first, from one end of source. And finally fill out odd-numbered entries from the back end of source.
public static TElement[] EndToEnd<TElement>(this IReadOnlyList<TElement> source)
{
var count = source.Count;
var result = new TElement[count];
for (var i = 0; i < (count + 1) / 2; i++)
result[2 * i] = source[i];
for (var i = 1; i <= count / 2; i++)
result[2 * i - 1] = source[count - i];
return result;
}
Came up with this
public int[] OrderedArray(int[] numbers)
{
int[] final = new int[numbers.Length];
var limit=numbers.Length;
int last = numbers.Length - 1;
var finalCounter = 0;
for (int i = 0; finalCounter < numbers.Length; i++)
{
final[finalCounter] = numbers[i];
final[((finalCounter + 1) >= limit ? limit - 1 : (finalCounter + 1))] = numbers[last];
finalCounter += 2;
last--;
}
return final;
}

Categories

Resources