I have array with data. Array length equals 25 elements. I would like create matrix (5X5). How I can do this in C#? Please help.
Translating a single dimension array into a multi dimension array is straight forward.
public static T getEntry<T>(this T[] array, int column, int row, int width)
{
return array[column+row*width];
}
Add wrapper classes and/or validation as desired.
Usage example:
var array=Enumerable.Range(1,25).ToArray();
for (int row = 0; row < 5; row ++)
{
for (int column = 0; column < 5; column ++)
{
Console.WriteLine("Value in column {0}, row {1} is {2}", column, row, array.getEntry(column,row));
}
}
You can use Buffer.BlockCopy
using System;
class Test
{
static double[,] ConvertMatrix(double[] flat, int m, int n)
{
if (flat.Length != m * n)
{
throw new ArgumentException("Invalid length");
}
double[,] ret = new double[m, n];
// BlockCopy uses byte lengths: a double is 8 bytes
Buffer.BlockCopy(flat, 0, ret, 0, flat.Length * sizeof(double));
return ret;
}
static void Main()
{
double[] d = { 2, 5, 3, 5, 1, 6 };
double[,] matrix = ConvertMatrix(d, 3, 2);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
Console.WriteLine("matrix[{0},{1}] = {2}", i, j, matrix[i, j]);
}
}
}
}
As #Taemyr suggest you can simply use indexing to simulate the structure of the matrix. If you need to access the element at row 2, col 3 in a 5 by 5 matrix simply access index 2*5+3 of your array. (row * # of cols + col)
If you want to split your array into a 2D array you can do so using the following code:
public static T[,] Matrix<T>(T[] arr, int rows) {
var cols = arr.Length / rows;
var m = new T[rows, cols];
for (var i = 0; i < arr.Length; i++)
m[i / cols, i % cols] = arr[i];
return m;
}
Related
I have matrix with size N x M and I want to find smaller matrix inside which has maximum sum and is of size 3 x 3. I can manually sum all the elements but wthis is imposible in bigger matrices, can you point me a better approach.
Look for Kadane 2D algorithm.
I think it is one of the best solution for this problem
If I understand the problem ¯\_(ツ)_/¯
Given
public static int FindStuff(int[,] array)
{
var largest = 0;
for (var i = 0; i < array.GetLength(0) - 2; i++)
for (var j = 0; j < array.GetLength(1) - 2; j++)
{
var sum = 0;
for (var x = i; x < i+3; x++)
for (var y = j; y < j+3; y++)
sum += array[x, y];
if (sum > largest)
largest = sum;
}
return largest;
}
Usage
var array = new[,]
{
{1, 1, 1, 1},
{1, 2, 3, 4},
{1, 1, 1, 1},
{5, 1, 1, 1},
};
Console.WriteLine(FindStuff(array));
Result
16
In pure C# you must calculate all inner matricies, you can speed up algorithms with paraller task, you can also use CUDA, and a naive solution with checking inner matrices should looks like this:
public void TestMethod(int[][] matrix)
{
int largestSum = 0;
int columnLargestIdx = 0;
int rowLargestIdx = 0;
for (int column = 0; column < matrix.Length; column++)
for (int row = 0; row < matrix[column].Length; row++)
{
if (IsBuild3x3Possible(matrix, column, row))
{
int sum = CalculateSum(matrix, column, row);
if (sum > largestSum)
{
largestSum = sum;
columnLargestIdx = column;
rowLargestIdx = row;
}
}
}
}
public bool IsBuild3x3Possible(int[][] matrix, int column, int row)
{
var columns = (matrix.Length - column) >= 3;
var rows = (matrix[column].Length - row) >= 3;
return columns && rows;
}
public int CalculateSum(int[][] matrix, int column, int row)
{
int sum = 0;
for (int i = column; i < column + 3; i++)
for (int j = row; j < row + 3; j++)
sum += matrix[i][j];
return sum;
}
I'm trying to vertically flip a 2D array, so I'm trying to turn this:
1 2 3 4 1
5 6 7 8 2
4 3 2 1 1
8 7 6 5 2
into
8 7 6 5 2
4 3 2 1 1
5 6 7 8 2
1 2 3 4 1
So far, I've got a nested for loop,
for (int i= 0; i<rows; i++)
{
for (int j = 0; j<columns; j++)
{
WillSmith[i, j] = arr[i,j];
}
}
With 'WillSmith' being the flipped array,
but I keep getting the same array as I entered back.
I can't figure out what I'm doing wrong
EDIT:
I've now swapped it to read arr[j,i], but now I get an error saying that I've overflowed the index. I need this to be able to work for non-square arrays, and since the array I'm testing isn't square, I can't just use newArray[i,j] = oldArray[j,i].
WillSmith[rows-1-i, j] = arr[i, j];
You want to keep your column index, just reverse rows column-wise. So read from start, write from end.
The fastest way to do this, and for any type of array is to use Buffer.BlockCopy() to swap rows as needed.
class Program
{
static void Main(string[] args)
{
var test = new int[,] {
{1, 2, 3, 4, 1 },
{5, 6, 7, 8, 2 },
{4, 3, 2, 1, 1 },
{8, 7, 6, 5, 2 } };
var res = ReverseRows(test);
Console.WriteLine();
PrintArray(test);
Console.WriteLine();
PrintArray(res);
}
public static void PrintArray<T>(T[,] array, int colWidth=9)
{
int n = array.GetLength(0), m = array.GetLength(1);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
Console.Write(array[i,j].ToString().PadLeft(colWidth));
}
Console.WriteLine();
}
}
public static T[,] ReverseRows<T>(T[,] array)
{
int n = array.GetLength(0), m = array.GetLength(1);
T[,] result = array.Clone() as T[,];
for (int i = 0; i < n/2; i++)
{
SwapRows(result, i, n - i - 1);
}
return result;
}
static void SwapRows<T>(T[,] array, int row1, int row2)
{
if (row1 == row2) return;
int n = array.GetLength(0), m = array.GetLength(1);
int byteLen = Buffer.ByteLength(array) / (n * m);
T[] buffer = new T[m];
// copy row1 to buffer
Buffer.BlockCopy(array, row1 * m * byteLen, buffer, 0, m * byteLen);
// copy row2 to row1
Buffer.BlockCopy(array, row2 * m * byteLen, array, row1 * m * byteLen, m * byteLen);
// copy buffer to row2
Buffer.BlockCopy(buffer, 0, array, row2 * m * byteLen, m * byteLen);
}
}
An example of fastest way to invert a 80*260 array vertically
const int ROW = 80;
const int COL = 260;
public ushort[,] FlipFrameVertical(ushort[,] frame)
{
// ushort size is 2 bytes
int byteSize = 2 * COL;
ushort[,] frame_flipped = new ushort[ROW, COL];
for (int i = 0; i < ROW; i++)
{
Buffer.BlockCopy(frame, (byteSize * (ROW-1-i)), frame_flipped,
byteSize * i, byteSize);
}
return frame_flipped;
}
Change the byte size based on your data type.
I have a matrix, my mission is to fill 1D array from my matrix.
Example:
1 2 3
1 2 3
1 2 3
I need to sum the columns and fill the sum of every column in a 1D array
Here is my code (that doesn't work), (int[,] mat) is the matrix that the function gets.
public static int sumcolumn(int[,] mat)
{
int sum = 0;
int[] sumcol = new int[mat.GetLength(0)];
for (int y = 0; y < mat.GetLength(0); y++)
{
for (int i = 0; i < mat.GetLength(0); i++)
{
for (int j = 0; j < mat.GetLength(1); j++)
{
sum = sum + mat[j, i];
}
sumcol[i] = sum;
return sum;
sum = 0;
}
return sum;
}
return sumcol;
}
How should I do this mission?
Thanks in advance.
You need only 2 for loops. For each column run through all rows and sum up the content. Write the sum at the proper col index. Then after each column reset the sum. You also need to return the array with the sums. So I changed the return value:
Also it helps if you call the index variables with meaningful names.
public static int[] sumcolumn(int[,] mat)
{
int[] sumcol = new int[mat.GetLength(1)];
for (int col = 0; col < mat.GetLength(1); col++)
{
for (int row = 0; row < mat.GetLength(0); row++)
{
// since sumcol is initially filled with zeros you can just
// sum up the values from mat onto the zeros in each cell
sumcol[col] += mat[row, col];
}
}
return sumcol;
}
In the main you can test it like this:
void Main()
{
int[,] array = {
{ 1, 2, 3 },
{ 1, 2, 3 },
{ 1, 2, 3 },};
// this is just for test display
Console.WriteLine(String.Join(" ", sumcolumn(array)));
// normally you would call it like this and catch the return value in a new array
int[] result = sumcolumn(array);
}
So you need to evaluate a 2D matrix to get the column wise sum to a 1D array. So first thing you have to do is change the return type of the method to int[] instead for int.
Let me quote Few things that you have to notice before moving to a fix:
If you execute a return during iteration of the loop rest of iterations will not be executed.
A function can return only one value in a single call.
Let i and j be two positive unequal integers then a[i,j] and a[j,i] will points to two different elements in the matrix a.
As a whole you have to modify the method signature like the following:
public static int[] sumcolumn(int[,] mat)
{
int sum = 0;
int[] sumcol = new int[mat.GetLength(1)];
for (int i= 0; i< mat.GetLength(1); i++)
{
sum = 0; // reset sum for next colomn
for (int j= 0; j< mat.GetLength(0); j++)
{
sum += mat[i, j];
}
// iteration of column completed
sumcol[i] = sum;
}
return sumcol;
}
Linq approach
int[,] array = new int[3, 3] { { 1, 2, 3 },
{ 1, 2, 3 },
{ 1, 2, 3 } };
int[] result = Enumerable.Range(0, array.GetUpperBound(1) + 1)
.Select(y => Enumerable.Range(0, array.GetUpperBound(0) + 1)
.Select(x => array[x, y]).Sum()).ToArray(); // [3,6,9]
public static int[] sumColumn(int[,] mat)
{
//int sum = 0;
int colCount = mat.GetLength(0);
int[] sumCol = new int[colCount];
for (int y = 0; y < colCount; y++)
{
int rowCount = mat.GetLength(1);
sumCol[y] = 0;
for (int x = 0; x < rowCount; x++)
{
sumCol[y] += mat[y, x];
}
//sum += sumCol[y];
}
//return sum;
return sumCol;
}
Write a Java class that has a static method named count that accepts a 2D-Array of integers and a target integer value as parameters and returns the number of occurrences of the target value in the array. For example, if a variable named list refers to an array containing values {{3,5,7,94}{5,6,3,50}} then the call of count(list, 3) should return 2 because there are 2 occurrences of the value 3 in the array.
Here is my coding and it's not giving me proper output
P.S :-I have been told to take count method as public not static
class java
{
public int count(int [,] list,int n)
{
int c = 0;
for (int i = 0; i <list.Length; i++)
{
for (int j = 0; j < list.Length; j++)
{
if (list[i, j] == n)
{
c++;
}
}
}
return c;
}
class Program
{
static void Main(string[] args)
{
java jv = new java();
int[,] arr = { { 3, 5, 7, 94 }, {5, 6, 3, 50 } };
int k=0;
jv.count(arr,k);
}
}
Iterating Multi-Dimensional arrays requires you to iterate each dimension with it's own Length, which means i and j should be 0-3 and 0-1 respectively.
as can be seen in the picture but for a different dimensioned array:
GetLength(0) would return 4.
GetLength(1) would return 3.
What you are doing is iterating them when i = (0 to Length) over j = (0 to Length) when Length = Height * Width = 8 in your case which means 8 over 8.
So your count() method should look like that:
public int count(int[,] list,int n)
{
int c = 0;
for (int i = 0; i < list.GetLength(0); i++)
{
for (int j = 0; j < list.GetLength(1); j++)
{
if (list[i, j] == n)
{
c++;
}
}
}
return c;
}
if you would like to iterate the array as an array of arrays instead of getting things complicated with "Which dimension am I iterating now?" you can use Jagged Arrays (Of course there are more things to consider about it), this will allow you to replace the whole method with this one short Linq:
public int count(int[][] list,int n)
{
return list.SelectMany(x => x).Count(x => x == n);
}
or:
public int count(int[][] list, int n)
{
return list.Sum(x => x.Count(y => y == n));
}
Note the i against j in inner for.
And do use i <list.GetLength(0) and j < list.GetLength(1) against list.Length
class java
{
public int count(int [,] list,int n)
{
int c = 0;
for (int i = 0; i < list.GetLength(0); i++)
{
for (int j = 0; j < list.GetLength(1); j++)
{
if (list[i, j] == n)
{
c++;
}
}
}
return c;
}
class Program
{
static void Main(string[] args)
{
java jv = new java();
int[,] arr = { {3,5,7,94 }, {5,6,3,50 } };
int k=5;
Console.WriteLine(jv.count(arr,k));
}
}
Since Array has implemented IEnumerable you can simply use foreach loop here (feel free to change static to instance method) :
public static int count(int[,] list, int n)
{
int c = 0;
foreach (var item in list) if (item == n) c++;
return c;
}
Usage:
static void Main()
{
var r = count(new int[,]{
{
5, 8, 7, 8
},
{
0, 8, 9, 3
}}, 8);
Console.WriteLine(r);
output : 3
P.S.
Generally if possible, it is best to use a for loop as it is faster than foreach but in these case i like that if you use foreach you don't have nested for loops nor GetLength(x) calls it's just one line of code and it has almost same performance...
Your error is in this line:
for (int j = 0; i < list.Length; j++)
It should be
for (int j = 0; j < list.Length; j++)
How to delete a specific row and column from 2D array in C#?
int[,] array= {{1,2,3},{4,5,6},{7,8,9}};
lets say I want to delete row i and column i (skipping them) ... for nXn array not just 3x3 and store the remaining array in a new array...
so the output would be:
{5,6},{8,9}
There's no built-in way to do that, you can do it yourself:
static void Main()
{
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
var trim = TrimArray(0, 2, array);
}
public static int[,] TrimArray(int rowToRemove, int columnToRemove, int[,] originalArray)
{
int[,] result = new int[originalArray.GetLength(0) - 1, originalArray.GetLength(1) - 1];
for (int i = 0, j = 0; i < originalArray.GetLength(0); i++)
{
if (i == rowToRemove)
continue;
for (int k = 0, u = 0; k < originalArray.GetLength(1); k++)
{
if (k == columnToRemove)
continue;
result[j, u] = originalArray[i, k];
u++;
}
j++;
}
return result;
}
No, arrays don't let you do that. You could make your own data structure for that, but it's not going to be exactly simple (unlike if you only wanted to be able to remove rows, for example).
For simple operations, it would be quite enough to build a class on top of an underlying array, and handle the re-indexing to map the virtual 2D array to the physical array underneath. But it's going to get a bit tricky as you combine removals and additions, and deform the array overall.
Very simple logic. Just play with the loop:
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[,] arrayskip = new int[array.GetLength(0) - 1, array.GetLength(1) - 1];
for (int i = 1; i < array.GetLength(0); i++)
{
for (int j = 1; j < array.GetLength(1); j++)
{
arrayskip[i - 1, j - 1] = array[i, j];
}
}
I created this method, have a look
public static double[,] fillNewArr(double[,] originalArr, int row, int col)
{
double[,] tempArray = new double[originalArr.GetLength(0) - 1, originalArr.GetLength(1) - 1];
int newRow = 0;
int newCol = 0;
for (int i = 0; i < originalArr.GetLength(0); i++)
{
for (int j = 0; j < originalArr.GetLength(1); j++)
{
if(i != row && j != col)
{
tempArray[newRow, newCol] = originalArr[i, j];
newRow++;
newCol++;
}
}
}
return tempArray;
}
having some out of range, It's obvious why but I'm trying to get there...