How to create a 3D List in C# - c#

I have a list which is made up of 2 lists with the following numbers:
list(1) = (2,3,5,3)
list(2) = (1,3,9,2).
Now I have to create two matrix:
The first matrix 4x4 should have all the elements of list(1) on the diagonal, the rest of the numbers should be zero.
The second matrix 4x4 should have all the elements of list(2) on the diagonal. The rest of the numbers should be zero.
I want to do this with a for loop.
Could you please help me? I don't know how to start, I'm new in C# and I can't find references in which it's clear how to work with 3D matrix as I did with Matlab.
Thanks a lot!

Create a regular List<int> for the first list.
List<int> list = new List<int>() { 2, 3, 5, 3 };
Then your 'matrix'(which really is a 2D array):
int[,] matrix = new int[4, 4];
Now, the diagonal means column == row, so using two loops you can enter the value only when that condition is met.
for (int row = 0; row < list.Count; row++)
{
for (int col = 0; col < list.Count; col++)
{
if (col == row)
matrix[row, col] = list[row];
else
matrix[row, col] = 0;
}
}
Confirmation:
And do the same thing for the 2nd list. You could easily write a function that would do this.
EDIT
Here it is put into a function, and how to use it.
static int[,] CreateMatrix(List<int> list)
{
int[,] matrix = new int[list.Count, list.Count];
for (int row = 0; row < list.Count; row++)
{
for (int col = 0; col < list.Count; col++)
{
if (col == row)
matrix[row, col] = list[row];
else
matrix[row, col] = 0;
}
}
return matrix;
}
Calling:
var list1 = new List<int>() { 2, 3, 5, 3 };
var list2 = new List<int>() { 1, 3, 9, 2 };
var matrix1 = CreateMatrix(list1);
var matrix2 = CreateMatrix(list2);

Related

c# - trying to randomize a 2d array

I am trying to make a 2d array that has shuffled elements in each row. For example, in a 3x5 array, each row will have 1, 2, and 3, but the order of the elements will be different:
what I want:
1 3 2
2 1 3
2 3 1
3 1 2
1 2 3
code I've tried:
//initialize a matrix
int[,] matrix = new int[3, 5];
Random rnd = new Random();
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i,j] = rnd.Next(1,3);
Console.WriteLine(matrix[i,j]);
}
Console.ReadLine();
}
It seems fairly easy, but as a newbie, I've been struggling for days over this problem.
Any help or lead will be appreciated!
You can make an List containing 1, 2, and 3, and then shuffle it for each row. Then just copy the shuffled values over:
public static void Main(string[] args)
{
int[,] matrix = new int[5, 3];
Random rnd = new Random();
var values = Enumerable.Range(1, 3).ToList();
for (int row = 0; row < matrix.GetLength(0); row++)
{
values = values.OrderBy(x => rnd.NextDouble()).ToList();
for (int col = 0; col < matrix.GetLength(1); col++)
{
matrix[row, col] = values[col];
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
Console.WriteLine("Press Enter to Quit.");
Console.ReadLine();
}
Sample Output:
2 3 1
3 1 2
3 2 1
1 3 2
2 1 3
Press Enter to Quit.

How to find 3x3 square matrix with maximum sum in bigger rectangular matrix in C#?

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;
}

Fill 1D array from matrix

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;
}

How can I delete rows and columns from 2D array in C#?

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...

Initiate jagged list

I am trying to make a jagged list. It gets filled with values depending on two variable int's: rows, and cols.
The pattern is to have the list filled like this when rows = 4 and cols = 3:
00,
10,
20,
01,
11,
21,
02,
12,
22,
03,
13,
23
Each double digit is a sub-list containing column, and then row.
This is what i have:
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
defineCellPositionsList();
displayCellPositionsList();
}
int rows = 4;
int cols = 3;
private List<List<int>> CellPositionsList = new List<List<int>>();
private void defineCellPositionsList()
{
for (int i = 0; i < (rows * cols); i++)
{
List<int> sublist = new List<int>();
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
sublist.Add(col);
sublist.Add(row);
}
}
CellPositionsList.Add(sublist);
}
}
private void displayCellPositionsList()
{
for (int i = 0; i < CellPositionsList.Count; i++)
{
label1.Text += CellPositionsList[i][0];
label1.Text += CellPositionsList[i][1] + "\n";
}
}
}
}
The jagged list should have 12 sub-lists. The sub-lists should have 2 values. This is working. However each value is 0. Clearly i am slightly off with my logic. Any help appreciated. Thanks.
The problem is not that each of your sublists is { 0, 0 }, but rather that each one is a sublist of the full 24 items, which happens to begin with the numbers 0, 0. You can verify this by checking CellPositionsList[i].Count.
The bug is due to too much looping when the lists are created. You don't need three loops, two are correct:
private void defineCellPositionsList()
{
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
CellPositionsList.Add(new List<int> { col, row });
}
}
}
And there is also no need to write all of this longhand, as LINQ provides an IMHO better alternative:
CellPositionsList = Enumerable.Range(0, rows)
.SelectMany(r => Enumerable.Range(0, cols).Select(c => new List<int> {c,r}))
.ToList();
defineCellPositionsList() seems to be using the same sublist for every iteration. The first two elements in sublist are 0, 0, but there are a total of 24 eventually added.
To fix this, move the declaration of sublist inside the first loop.
I do see plenty of non-zero values in the sublists. It may be worth noting that you appear to be putting all the values into a single label in displayCellPositionsList.
I was totally wrong about that stuff.
But this stuff is right. I've executed and it works. (assuming I understand what you're trying to do, it's still a little vague)
If you have a list of rows, and a list of columns, and then finally a 2-list of coordinates, then you really have 3 sets of nested lists. I'm not sure exactly what you're doing or why you want it that way, but if that's what you really want, then your CellPositionsList really needs to be List<List<List<int>>>. If you do that, you can use this code:
for (int row = 0; row < rows; row++) {
CellPositionsList.Add(new List<List<int>>());
for (int col = 0; col < cols; col++) {
CellPositionsList[row].Add(new List<int> {row, col});
}
}

Categories

Resources