I have a C# midterm review question that is getting the best of me. The question is: "Use a method, and on the click of a button, call the method to sort through a 2 dimensional array (globally declared) and return the average of the first diagonal using a SINGLE for loop."
My 2 dimensional array looks like this
int[,] A = new int[,] { { -16, 19, 8, -3 },
{-17, -5, 9, 33 },
{-2, 15, -13, 29 },
{25, 39, -23, 8 } };
And my code thus far looks like this:
private void btnAverageQVI_Click(object sender, EventArgs e)
{
arrayAverage(A);
}
`public static void arrayAverage(int[,] array)
{
int total = 0;
int count = 0;
int rows = array.GetLength(0);
int cols = array.GetLength(1);
for (rows = 0; rows < array.Length; rows++)
{
total = array[0, 0] + 1;
count++;
}
double average = total / 4;
MessageBox.Show("Total: " + average);
}`
Someone please help, I feel like it's easy, but I am missing something.
public static void arrayAverage(int[,] array)
{
int total = 0;
//Get number of rows
int rows = Math.Min(array.GetLength(0),array.GetLength(1));
//Iterate through diagonal elements
for (int i= 0; i < rows; i++)
{
total += array[i, i];
}
//Multiple 1.0 to prevent data lost.
double average = 1.0*total / rows;
Console.WriteLine("Total: " + average);
}
Related
the input is like this
100 5
0 10
0 5
75 95
12 17
13 14
and the output is 65
so i want the program to count which numbers from 0-100 are not in the array.
this is how i started
static void Main(string[] args)
{
string input1 = Console.ReadLine();
int roadlength = Convert.ToInt32(input1.Split(" ")[0]);
int stagecnt = Convert.ToInt32(input1.Split(" ")[1]);
int[] startpoint = new int[stagecnt];
int[] endpoint = new int[stagecnt];
int km = 0;
for (int i = 0; i < stagecnt; i++)
{
string input2 = Console.ReadLine();
startpoint[i] = Convert.ToInt32(input2.Split(' ')[0]);
endpoint[i] = Convert.ToInt32(input2.Split(' ')[1]);
}
for (int i = 0; i < stagecnt; i++)
{
Let's count distinct numbers that are in 0..100 range and then subtract from total number in 0..100 range:
using System.Linq;
...
int[] data = new int[] {
100, 5, 0, 10, 0, 5, 75, 95, 12, 17, 13, 14,
};
...
int min = 0;
int max = 100;
int result = max - min + 1 - data
.Where(item => item >= min && item <= max)
.Distinct()
.Count();
you are complicating the problem, it's very simple.
Initialize an array/list with the given range.
and check all your input items one by one whether they are present in the first carry. and if not present then just increment the count.
though complexity is high but its simplest solution.
int[] items = ;
int start = 1;
int end = 100;
int[] arr = Enumerable.Range(start, end - start).ToArray();
int count = 0;
for(int i = 0; i < arr.Length; i++)
{
if (!items.Contains(arr[i]))
{
count++;
}
}
If you want to count missing integers in your array, compared to all between 1 and 100:
int[] array = {1,2,3,4,5};
HashSet<int> allBetween1And100 = Enumerable.Range(1, 100).ToHashSet();
allBetween1And100.ExceptWith(array); // removes all from the set which are not in array
int countMissing = allBetween1And100.Count; // 95
The advantage of this approach is that you even have a collection with the missing. Of course this needs some memory, so if you don't need them, prefer a simple loop.
So, I needed to find all the index of elements from an array whose sum is equal to N.
For example : Here I want to find indexes whose sum should be equal to 10.
Input : int[] arr = { 2, 3, 0, 5, 7 }
Output: 0,1,3
If you add indexes arr[0] + arr[1] + arr[3] then 2 + 3 + 5 = 10.
I have tried this, but I am running 3 for loops and 3 if conditions, Can we write this in less code, I want to reduce code complexity.
PS: Post suggestions, not codes..
public static void Check1()
{
int[] arr = { 2, 3, 0, 5, 7 };
int target = 10; int total = 0;
bool found = false;
List<int> lst = new List<int>();
for (int i = 0; i < arr.Length; i++)
{
if (!found)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (!found)
{
total = arr[j] + arr[i];
for (int k = j + 1; k < arr.Length; k++)
{
if (total + arr[k] == target)
{
found = true;
Console.WriteLine($"{i}, {i + 1}, {k}");
break;
}
}
}
}
}
}
Console.ReadLine();
}
The extension :
public static T[,] SubArray<T>(this T[,] values, int row_min, int row_max, int col_min, int col_max)
{
int num_rows = row_max - row_min + 1;
int num_cols = col_max - col_min + 1;
T[,] result = new T[num_rows, num_cols];
int total_cols = values.GetUpperBound(1) + 1;
int from_index = row_min * total_cols + col_min;
int to_index = 0;
for (int row = 0; row <= num_rows - 1; row++)
{
Array.Copy(values, from_index, result, to_index, num_cols);
from_index += total_cols;
to_index += num_cols;
}
return result;
}
work well for 2D arrays arrays whose GetLowerBound(0) and GetLowerBound(1) are equal to zero. For instance if
int[,] arr1 = new int[5, 4];
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 4; ++j)
{
arr1[i, j] = i + j;
}
}
var arr1sub = arr1.SubArray(2, 3, 1, 3);
Then arr1sub is the 2d array with 2 rows and 3 colums (boths with indexes starting at 0)
3 4 5
5 6 7
Now if I look at the case where the initial array as indexes not starting at zero :
int[,] arr2 = (int[,])Array.CreateInstance(typeof(int), new int[] { 5, 4 }, new int[] { 3, 1 });
for (int i = arr2.GetLowerBound(0); i <= arr2.GetUpperBound(0); ++i)
{
for (int j = arr2.GetLowerBound(1); j <= arr2.GetUpperBound(1); ++j)
{
arr2[i, j] = i - arr2.GetLowerBound(0) + j - arr2.GetLowerBound(1);
}
}
var arr2sub = arr2.SubArray(5, 6, 2, 4);
the last line of previous code snippet will trigger an exception in the SubArray extension function at the line
Array.Copy(values, from_index, result, to_index, num_cols);
for row equal to zero.
I understand of the 2d array arr1 (with zero based indexes) is layed out in memory but not how the 2d array arr2 (with non-zero-based indexes) is layed out in memory, hence my use of Array.Copy must be wrong in this case, but I don't see why.
You are not calculating total_cols and from_index correctly.
public static T[,] SubArray<T>(this T[,] values, int row_min, int row_max, int col_min, int col_max)
{
int num_rows = row_max - row_min + 1;
int num_cols = col_max - col_min + 1;
T[,] result = new T[num_rows, num_cols];
int total_cols = values.GetLength(1);
int from_index = (row_min - values.GetLowerBound(0)) * total_cols + (col_min - values.GetLowerBound(1)) + values.GetLowerBound(0);
int to_index = 0;
for (int row = 0; row <= num_rows - 1; row++)
{
Array.Copy(values, from_index, result, to_index, num_cols);
from_index += total_cols;
to_index += num_cols;
}
return result;
}
total_cols is the obvious one; as for from_index, I cannot find any documentation on that, but it would appear that sourceIndex in Array.Copy starts counting from sourceArray.GetLowerBound(0) and not from zero, which is not necessarily immediately obvious given that this index keeps growing across rows and columns.
What i want to do is get the average of each row of what the user inputs. I'm able to display the input, but not sure how to calculate an average of the three numbers in each row. What would be a solution? I'm new to C# so still learning.
Here's my code:
class Program
{
static void Main(string[] args)
{
int[,] number = new int[3, 5];
for (int i = 0; i < 3; i++)
{
for (int x = 0; x < 3; x++)
{
Console.WriteLine("Please enter number");
number[x, i] = int.Parse(Console.ReadLine());
}
}
for (int i = 0; i < 3; i++)
{
for (int x = 0; x < 3; x++)
{
Console.Write(number[x, i] + " ");
}
Console.WriteLine(" ");
Console.ReadLine();
}
}
}
You can do it something like this
for(int i = 0; i < 3; i++)
{
int Avg = 0;
for(int x = 0; x < 3; x++)
{
Console.Write(number[x, i] + " ");
Avg += number[x, i];
}
Avg = Avg / 3;
Console.Write("Average is" + Avg);
Console.WriteLine(" ");
Console.ReadLine();
}
I think you have to create a method like the following, that will accept a two dimensional array as input and iterate through its rows and further iteration will performed through its cols to find the sum of all elements in each rows and then it will be divided with number of cols, to get the average. Take a look into the method
public static void rowWiseAvg(int[,] inputArray)
{
int rows = inputArray.GetLength(0);
int cols = inputArray.GetLength(1);
for (int i = 0; i < rows; i++)
{
float rowAvg = 0;
for (int x = 0; x < cols; x++)
{
rowAvg += inputArray[i,x];
}
rowAvg = rowAvg / cols;
Console.Write("Average of row {0} is :{1}", i,rowAvg);
}
}
An additional note for you : When you are reading values for a multi-dimensional array, use outer loop to read values for the rows and inner loop for reading columns. in your case you are actually reads the columns first then gets values for each rows in a column. One more, use float / double to store the average
Here's a (mostly) LINQ solution:
var array = new int[,]
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
int count = 0;
var averages = array.Cast<int>()
.GroupBy(x => count++ / array.GetLength(1))
.Select(g => g.Average())
.ToArray();
// [2.5, 6.5, 10.5]
The simplest way is to use for loops, as described in other answers.
You can also utilize LINQ and use Enumerable.Range to make it another way:
public static class MultidimensionalIntArrayExtensions
{
// Approach 1 (using Select and Average)
public static double[] RowAverages(this int[,] arr)
{
int rows = arr.GetLength(0);
int cols = arr.GetLength(1);
return Enumerable.Range(0, rows)
.Select(row => Enumerable
.Range(0, cols)
.Select(col => arr[row, col])
.Average())
.ToArray();
}
// Approach 2 (using Aggregate)
public static double[] RowAverages(this int[,] arr)
{
int rows = arr.GetLength(0);
int cols = arr.GetLength(1);
return Enumerable.Range(0, rows)
.Select(row => Enumerable
.Range(0, cols)
.Aggregate(0.0, (avg, col) => avg + ((double)arr[row, col] / cols)))
.ToArray();
}
}
// Usage:
int[,] arr =
{
{ 1, 2, 3 },
{ 2, 3, 4 },
{ 3, 4, 5 },
{ 6, 7, 8 },
{ 1, 1, 1 }
};
double[] rowSums = arr.RowAverages(); // [2, 3, 4, 7, 1]
This code may look unreadable and non-OOP for some developers; and may seem good and laconic for others. If your belongs to the second group, use this code.
This is my code:
I am trying to get the maximum per line, everything is going ok until the last row. It shows me 8, but should be 4.
int[,] vek = new int[,] { { 2, 5 }, { 4, 5 }, { 8, 5 }, { 4, 2 } };
int sumL=0;
double media = 0;
int maxL = 0;
maxL = vek [0,0];
Console.WriteLine("\tL1\tL2\tTotal\tMedia");
Console.WriteLine();
for (int row = 0; row < vek.GetLength(0); row++)
{
Console.Write("{0}.\t", row + 1);
for (int col = 0; col < vek.GetLength(1); col++) {
Console.Write(vek[row, col] + "\t");
sumL += vek[row, col];// SUMA
media = (double)sumL / vek.GetLength(1); //Media
if (maxL < vek[row,col])
{
maxL = vek[row, col];
}
}
Console.WriteLine(sumL + "\t" + media + "\t" + maxL);
Console.WriteLine();
}
Console.ReadKey();
}
You need to set maxL back to 0 (or, better yet, int.MinValue) at the start of each row. Simply moving its declaration into the outer for loop would be a good way to do this.
Your code gets 5, 5, 8, 8 for the maximum because, without reseting maxL, it's taking the maximum of the rows so far instead of the maximum of each row independently.