I am having a bit of trouble with my program which holds student names and grades in a 2D string array. Basically, I have a second (1D) array that will hold average grade for each student.
code so far:
class Program
{
static void Main(string[] args)
{
// Create a 2D array for names, and their grades, and an array for average grades
string[,] studentGrades = new string[5, 8];
int[] average = new int[studentGrades.GetLength(0)];
// Set student names/grades manually
studentGrades[0, 0] = "Steve";
studentGrades[0, 1] = "69";
studentGrades[0, 2] = "80";
studentGrades[0, 3] = "66";
studentGrades[0, 4] = "75";
studentGrades[0, 5] = "90";
studentGrades[0, 6] = "69";
studentGrades[0, 7] = "98";
studentGrades[1, 0] = "Bob";
studentGrades[1, 1] = "73";
studentGrades[1, 2] = "67";
studentGrades[1, 3] = "65";
studentGrades[1, 4] = "91";
studentGrades[1, 5] = "48";
studentGrades[1, 6] = "33";
studentGrades[1, 7] = "94";
studentGrades[2, 0] = "Lewis";
studentGrades[2, 1] = "67";
studentGrades[2, 2] = "80";
studentGrades[2, 3] = "66";
studentGrades[2, 4] = "75";
studentGrades[2, 5] = "90";
studentGrades[2, 6] = "69";
studentGrades[2, 7] = "63";
studentGrades[3, 0] = "Sara";
studentGrades[3, 1] = "55";
studentGrades[3, 2] = "58";
studentGrades[3, 3] = "63";
studentGrades[3, 4] = "70";
studentGrades[3, 5] = "55";
studentGrades[3, 6] = "55";
studentGrades[3, 7] = "76";
studentGrades[4, 0] = "Xavier";
studentGrades[4, 1] = "22";
studentGrades[4, 2] = "27";
studentGrades[4, 3] = "25";
studentGrades[4, 4] = "19";
studentGrades[4, 5] = "42";
studentGrades[4, 6] = "18";
studentGrades[4, 7] = "32";
// Loop the array dimensions and output/format output the names/grades
for (int name = 0; name < studentGrades.GetLength(0); name++)
{
for (int grade = 0; grade < studentGrades.GetLength(1); grade++)
{
Console.WriteLine(studentGrades[name, grade]);
}
Console.WriteLine("");
}
for (int i = 0; i < studentGrades.GetLength(0); i++)
{
for (int j = 0; j < studentGrades.GetLength(1); j++)
{
average[j] += int.Parse(studentGrades[i, j]);
}
}
}
}
I get an un-handled exception in regards to the input string not being in the correct format where the average is set.
All help is appreciated!
Update
I've reviewed the solutions of code so far below, and I'm still having issues with getting the grade average to work as intended. I have 5 students with 7 grades. I want the program to output the average of each persons grades below their column.
Code:
static void Main(string[] args)
{
// Create a 2D array for names, and their grades, and an array for average grades
string[,] studentGrades = new string[5, 8];
int[] average = new int[studentGrades.GetLength(1)];
// Set student names/grades manually
//As done above, excluded for brevity reasons
// Loop the array dimensions and output/format output the names/grades
for (int grade = 0; grade < studentGrades.GetLength(1); grade++)
{
for (int name = 0; name < studentGrades.GetLength(0); name++)
{
// Composite formatting is used to align names/grades in grid -- specifically the alignment component.
// Making the value higher (more neg) will increase spacing between elements
// Positive number would right align elements instead
Console.Write("{0, -15}", studentGrades[name, grade]);
}
// Moves each printed grade to a new line
Console.WriteLine("");
}
for (int i = 0; i < studentGrades.GetLength(0); i++)
{
for (int j = 1; j < studentGrades.GetLength(1); j++)
{
average[j] += int.Parse(studentGrades[i, j]);
}
average[i] /= studentGrades.GetLength(1) - 1;
}
for (int i = 0; i <= average.GetLength(0) - 1; i++)
{
Console.Write("{0, -15}", i);
}
Console.WriteLine("");
}
Update 2
It seems that the average array is not being properly populated. It seems to just print out 1, 2, 3, 4, 5, 6, 7 if I remove the average division. Furthermore, if I change averages' length to 5 -- or the length of the amount of names since there will only be 5 values, it breaks. This is likely because it's trying to add 7 items to a 5 item array.
Every studentGrages[*, 0] element is not integer so you can't parse it to int
Skip the first elements
for (int i = 0; i < studentGrades.GetLength(0); i++)
{
for (int j = 1; j < studentGrades.GetLength(1); j++)
{
average[j] += int.Parse(studentGrades[i, j]);
}
}
You have to change this part of code:
// Store the average as a double array, otherwise you can't have averages with decimal values.
double[] average = new double[studentGrades.GetLength(0)];
for (int i = 0; i < studentGrades.GetLength(0); i++)
{
// Start from j = 1, as j = 0 would get a name instead of a grade.
for (int j = 1; j < studentGrades.GetLength(1); j++)
{
// Here use average[i] instead of average[j], because you want
// the average grade for each student.
average[i] += int.Parse(studentGrades[i, j]);
}
// Finish calculating the average.
// GetLength(0) - 1 because the first item is a name, not a grade.
average[i] /= studentGrades.GetLength(1) - 1;
}
for (int i = 0; i <= average.GetLength(0) - 1; i++)
{
// Show at most 2 decimal digits.
Console.Write("{0, -15:#.##}", average[i]);
}
Your trying to include the string of the names (on the 0 index) with the average. e.g int.Parse("Steve") which is causing the exception, just skip on the first element on each colum.
for (int j = 1; j < studentGrades.GetLength(1); j++)
As other have rightly pointed out, you need to change the 0 to a 1 in the following line:
for (int j = 1; j < studentGrades.GetLength(1); j++)
Otherwise you're going to try to parse the name as an integer.
Also you need to change the index on average inside the loop to i rather than j.
average[i] += int.Parse(studentGrades[i, j]);
The other issue that you're going to have is that you're using integer mathematics - so when you do something like 7 / 2 you get an answer of 3 and not 3.5.
If I were you, and you don't want to change your data structure, I would do it this way:
var results =
studentGrades
.Cast<string>()
.Select((x, n) => new { x, n })
.GroupBy(xn => xn.n / studentGrades.GetLength(1), xn => xn.x)
.Select(xs => new
{
student = xs.First(),
average = xs.Skip(1).Select(x => int.Parse(x)).Average(),
})
.ToArray();
That gives me:
Alternatively, I would suggest that you change your data structure to this:
var studentGrades = new []
{
new { student = "Steve", grades = new [] { 69, 80, 66, 75, 90, 69, 98, } },
new { student = "Bob", grades = new [] { 73, 67, 65, 91, 48, 33, 94, } },
new { student = "Lewis", grades = new [] { 67, 80, 66, 75, 90, 69, 63, } },
new { student = "Sara", grades = new [] { 55, 58, 63, 70, 55, 55, 76, } },
new { student = "Xavier", grades = new [] { 22, 27, 25, 19, 42, 18, 32, } },
};
Then this should work for you:
var results =
studentGrades
.Select(sg => new
{
sg.student,
average = sg.grades.Average(),
})
.ToArray();
Related
Maybe it's a basic question, but I am not reaching the correct method to get the value of a tridimensional array item or get three separate single arrays from a tridimensional array.
For a given float[,,] array3d as : {[a0,b0,c0], [a1,b1,c1], [a2,b2,c2]...}
I need to get three arrays as: a{a0 , a1, a2}, b{b1, b2, b3} and c{c1, c2, c3}
If it's not a direct method, I am trying to access to each element as array3d[row, column], but it's not working...
a = new float[length];
b = new float[length];
c = new float[length];
for (int i = 0; i < length; i++)
{
a[i] = array3d[i, 0]; //how can I access to that row, column element?
b[i] = array3d[i, 1];
c[i] = array3d[i, 2];
}
For 3D you have to provide 3 indexes to access a particular element. If i understand your question the following code should work for you
int[, ,] array3d = new int[2, 2, 3]{
{ { 1, 2, 3}, {4, 5, 6} },
{ { 7, 8, 9}, {10, 11, 12} }
};
List<float> a = new List<float>;
List<float> b = new List<float>;
List<float> c = new List<float>;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
a.Add(array3d[i, j, 0]);
b.Add(array3d[i, j, 1]);
c.Add(array3d[i, j, 2]);
}
}
let say I have this array
[0,0] = A
[0,1] = B
[0,2] = C
[1,0] = D
[1,1] = E
[1,2] = F
[2,0] = G
[2,1] = H
[2,2] = I
[3,0] = J
[3,1] = K
[3,2] = L
I want them to be written on a text file like this:
A B C
D E F
G H I
J K L
what am I supposed to do?
static void Main(string[] args)
{
var array = new string[4, 3];
array[0, 0] = "A";
array[0, 1] = "B";
array[0, 2] = "C";
array[1, 0] = "D";
array[1, 1] = "E";
array[1, 2] = "F";
array[2, 0] = "G";
array[2, 1] = "H";
array[2, 2] = "I";
array[3, 0] = "J";
array[3, 1] = "K";
array[3, 2] = "L";
using (var sw = new StreamWriter("outputText.txt"))
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
sw.Write(array[i,j] + " ");
}
sw.Write("\n");
}
sw.Flush();
sw.Close();
}
}
Jagged arrays are often more convenient than 2D ones.
public static class ArrayExtensions {
// In order to convert any 2d array to jagged one
// let's use a generic implementation
public static T[][] ToJagged<T>(this T[,] value) {
if (Object.ReferenceEquals(null, value))
return null;
// Jagged array creation
T[][] result = new T[value.GetLength(0)][];
for (int i = 0; i < value.GetLength(0); ++i)
result[i] = new T[value.GetLength(1)];
// Jagged array filling
for (int i = 0; i < value.GetLength(0); ++i)
for (int j = 0; j < value.GetLength(1); ++j)
result[i][j] = value[i, j];
return result;
}
}
so in your case you can convert 2d array into jagged and then use Linq:
var array = new string[,] {
{"A", "B", "C"},
{"D", "E", "F"},
{"G", "H", "I"},
{"J", "K", "L"},
};
File.WriteAllLines(#"C:\MyFile.txt", array
.ToJagged()
.Select(line => String.Join(" ", line));
Assume two dimensions x and y.
and an array to be like [x,y]
initiate x and y to 0
increment y one by one [x,y++]
at the end of y(when all y's have been consumed for an X), print a
new line character
increment x by one
continue
I dont't have any code for this, but I do want to know how I could do this. I use visual studio 2010 C# if that matters.
Thanks
Jason
public static void Print2DArray<T>(T[,] matrix)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write(matrix[i,j] + "\t");
}
Console.WriteLine();
}
}
you can print it all on one line
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
Console.WriteLine(String.Join(" ", array2D.Cast<int>()));
output
1 2 3 4 5 6 7 8
You should read MSDN:Using foreach with Arrays
int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };
// Or use the short form:
// int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } };
foreach (int i in numbers2D)
{
System.Console.Write("{0} ", i);
}
// Output: 9 99 3 33 5 55
//The following are three ways to print any 2d arrays to console:
int[,] twoDArray = new int[3, 4]{ {2,5,55,44},{10,45,5,22 },{ 67,34,56,77} };
Console.WriteLine("Array Code Out Method:1");
int rows = twoDArray.GetLength(0); // 0 is first dimension, 1 is 2nd
//dimension of 2d array
int cols = twoDArray.GetLength(1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
Console.Write("\t" + twoDArray[i, j]);
//output: 2 5 55 44 10 45 5 22 67 34 56 77
}
}
Console.WriteLine("Array Code Out Method: 2");
for (int x = 0; x <= twoDArray.GetUpperBound(0); x++)
{
for (int y = 0; y <= twoDArray.GetUpperBound(1); y++)
{
Console.Write("\t"+ twoDArray[x,y]);
//output: 2 5 55 44 10 45 5 22 67 34 56 77
}
}
Console.WriteLine("Array Code Out Method:3");
foreach (int items in twoDArray)
{
Console.Write(""+ "\t" +items);
//output: 2 5 55 44 10 45 5 22 67 34 56 77
}
//string example
string[,] friendNames = new string[,] { {"Rosy","Amy"},
{"Peter","Albert"}
};
foreach (string str in friendNames)
{
Console.WriteLine(str);
}
The following is an example...
static void Main()
{
// A. 2D array of strings.
string[,] a = new string[,]
{
{"ant", "aunt"},
{"Sam", "Samantha"},
{"clozapine", "quetiapine"},
{"flomax", "volmax"},
{"toradol", "tramadol"}
};
// B. Get the upper bound to loop.
for (int i = 0; i <= a.GetUpperBound(0); i++)
{
string s1 = a[i, 0]; // ant, Sam, clozapine...
string s2 = a[i, 1]; // aunt, Samantha, quetiapine...
Console.WriteLine("{0}, {1}", s1, s2);
}
Console.WriteLine();
}
int[,] matrix = new int[2, 2] { {2, 2}, {1, 1} };
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int k = 0; k < matrix.GetLength(1); k++ )
{
//put a single value
Console.Write(matrix[i,k]);
}
//next row
Console.WriteLine();
}
private int[,] MirrorH(int[,] matrix)
{
int[,] MirrorHorizintal = new int[4, 4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j ++)
{
MirrorHorizintal[i, j] = matrix[i, 3 - j];
}
}
return MirrorHorizintal;
}
Try like this..
int[,] matrix = new int[3, 3]
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
};
int rowLength = matrix.GetLength(0);
int colLength = matrix.GetLength(1);
for (int i = 0; i < rowLength; i++)
{
for (int j = 0; j < colLength; j++)
{
Console.Write(string.Format("{0} ", matrix[i, j]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
Console.Read();
Below is multiple solution to how to implement multidimentional array, I think it is pretty straight forward in c#.
using System;
using System.Collections.Generic;
namespace DataStructure
{
class Program : SortedZeros
{
static void Main(string[] args)
{
// Two-Dimensional Array
int[,] numbers2D = new int[3, 2]
{
{ 9, 99 },
{ 3, 33 },
{ 5, 55 }
};
// 3 * 3
int[,] dataTest2D = new int[3, 3]
{
{3, 5, 7},
{4, 3, 8},
{9, 6, 9},
};
// A similar array with string elements.
int[,] matrix = new int[4, 4]
{
{1, 2, 3, 6},
{4, 5, 6, 4},
{7, 8, 9, 6},
{7, 8, 9, 2},
};
int rowLength = matrix.GetLength(0);
int colLength = matrix.GetLength(0);
for (int i = 0; i < rowLength; i++)
{
for (int j = 0; j < colLength; j++)
{
Console.Write(string.Format("{0} ", matrix[i, j]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
// using foreach to print out the 2 * 2 in one straightline
foreach (int i in numbers2D)
{
Console.Write("{0} ", i);
}
Console.WriteLine();
Console.WriteLine();
for (int i = 0; i < dataTest2D.GetLength(0); i++)
{
for (int j = 0; j < dataTest2D.GetLength(1); j++)
{
Console.Write(string.Format("{0} ", dataTest2D[i, j]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
}
}
}
Explanation:
1. create an array
2. Create 2 for loops (one inside the other)
3. In "j" loop, pass matrix (roomString in our case) as parameter.
4. Add a "+" symbol (concatenate) it with a " " (empty space)
5. In "i" loop, have a "cw tab tab" --> Console.WriteLine();
Code:
string[,] roomString = new string[4, 4]
{
{"0","0","0","0" },
{"0","0","0","0" },
{"0","0","0","0" },
{"0","0","0","0" }
};
for (int i = 0; i < roomString.GetLength(0); i++)
{
for (int j = 0; j < roomString.GetLength(1); j++)
{
Console.Write(roomString[i,j]+" ");
}
Console.WriteLine();
}
Helper function to get any row:
public static int[] GetRow(int[,] mat, int rowNumber)
=> Enumerable.Range(0, mat.GetLength(1))
.Select(i => mat[rowNumber, i])
.ToArray();
Print row values in new line:
int[,] mat = new int[2,2];
for (int i =0; i < mat.GetLength(0); i++)
{
Console.WriteLine(string.Join(",", GetRow(mat, i)));
}
Do it like this:
static public void Print2DArray(int[][] A)
{
foreach (int[] row in A)
{
foreach (int element in row)
{
Console.Write(element.ToString() + " ");
}
Console.WriteLine();
}
}
I have a matrix of 50 rows and 2 columns and I want to sort them based on the comparison of the value of the second column filed. Here what I mean, if my matrix as:
[00][01]
[10][11]
[20][21]
[30][31]
[40][41]
[50][51]
I want to compare [01] and [11] and if [01] lesser than [11] I want to exchange the entire second row with the first row, to be like this (for example):
[10][11]
[00][01]
[20][21]
[30][31]
[40][41]
[50][51]
I tried using C# and came up with this algorithm but it didn't work:
int temp1, temp2;
for (int i = 0; i < 50; i++)
{
for (int j = i + 1; j < 2; j++)
{
if (rating[i, j] < rating[i + 1, j])
{
temp1 = rating[i + 1, j - 1];
temp2 = rating[i + 1, j];
rating[i + 1, j - 1] = rating[i, j - 1];
rating[i + 1, j] = rating[i, j];
rating[i, j - 1] = temp1;
rating[i, j] = temp2;
}
}
}
Can someone tell me a key to workout this problem or if you have the answer in c,c++ or another language please share it with us.
Thank you.
I believe you are trying to sort the matrix in descending order of second column. Give this code a try.
int[][] mat = new[] { new[] { 4, 4 }, new[] { 5, 1 }, new[] { 3, 2 }, new[] { 6, 1 } };
var ordered = mat.OrderByDescending(i => i[1]);
Your implementation of sort algorithm is wrong. The inner loop should not run from i+1 to 1.
Try implementing the simple bubble sort:
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 49-i; j++)
{
if (rating[j, 1] < rating[j + 1, 1]) // column 1 entry comparison
{
temp1 = rating[j, 0]; // swap both column 0 and column 1
temp2 = rating[j, 1];
rating[j, 0] = rating[j+1, 0];
rating[j, 1] = rating[j+1, 1];
rating[j+1, 0] = temp1;
rating[j+1, 1] = temp2;
}
}
}
I've got the following arrays:
int[,] myArray1 = new int[2, 3] { { 1, 2, 3 }, { 4, 6, 8 } };
int[,] myArray2 = new int[2, 3] { { 6, 4, 3 }, { 8, 2, 8 } };
What I'd like to know how to do is:
Create a new array with the sum of myArray1 and myArray2
Create a new array with the subtraction of myArray1 and myArray2
Create a new array with the multiplication of myArray1 and myArray2
Result of sum would be:
int[,] myArray3 = new int[2, 3] { { 7, 6, 0 }, { -4, 4, 0 } };
Result of subtraction would be:
int[,] myArray3 = new int[2, 3] { { 5, 2, 6 }, { 12, 8, 16 } };
Result of multiplication would be:
int[,] myArray3 = new int[2, 3] { { 6, 8, 9 }, { 32, 12, 64 } };
Can this be done similar to printing out the arrays, with for loops? I tried looking for examples but found none that I could use for my specific problem.
int[,] a3 = new int[2,3];
for(int i = 0; i < myArray1.GetLength(0); i++)
{
for(int j = 0; j < myArray1.GetLength(1); j++)
{
a3[i,j] = myArray1[i,j] + myArray2[i,j];
a3[i,j] = myArray1[i,j] - myArray2[i,j];
a3[i,j] = myArray1[i,j] * myArray2[i,j];
}
}
need to store a3 before doing a new calculation obviously
For Sum:
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
myArray3[i, j] = myArray1[i, j] + myArray2[i, j];
}
}
For Subtraction:
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
myArray3[i, j] = myArray2[i, j] - myArray1[i, j];
}
}
For Multiplication:
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
myArray3[i, j] = A[i, j] * B[i, j];
}
}
Yes this would be done exactly like printing out the arrays with for loops
c# has foreach loops which would be even easier to use
Note: I get the idea this is for homework so I'm not going to give a 100% conclusive end all be all answer.
int[,] myArray1 = new int[2, 3] { { 1, 2, 3 }, { 4, 6, 8 } };
int[,] myArray2 = new int[2, 3] { { 6, 4, 3 }, { 8, 2, 8 } };
foreach (int[] a1 in myArray1)
{
foreach(int i in a1)
{
//operation here
//you get the idea
}
}
If you want to do array manipulation faster use the C# Parallel.For loop from System.Threading.Tasks:
For simple arithmetic parallelizing the outer loop is much faster than not on a modern PC processor. For more complex operations, or for small array sizes, the parallel version can be slower for various reasons.
Thus, use a stopwatch to time your matrix operations, and use the fastest solution. Parallelization makes doing array / image processing in C# much faster if implemented right.
Beware of overflowing your datatypes after arithmetic operations and also sharing variables between multiple threads (see System.Threading.Interlocked for help with that)...
Subtraction below. Similar for addition and multiplication:
Parallel.For(0, array.GetLength(1), y=>
{
for (int x = 0; x < array.GetLength(0); x++)
{
difference[x,y] = minuend[x,y] - subtrahend[x,y];
}
}
});
If you want to use a for loop, you can iterate through the rows/columns of the multi-d array as follows:
for (int i = 0; i < myArray1.GetLength(0); i++)
{
for (int j = 0; j < myArray1.GetLength(1); j++)
{
// Here, you can access the array data by index, using i and j.
// Ex, myArray1[i, j] will give you the value of 1 in the first iteration.
}
}
Note: When you pass a value into the Array's GetLength method, it represents the dimension of the array. See http://msdn.microsoft.com/en-us/library/system.array.getlength.aspx