how multiply two dimensional array aka matrix [duplicate] - c#

This question already has answers here:
How to multiply a matrix in C#?
(2 answers)
Closed 6 years ago.
I want to know how to multiply 2D arrays (matrices) and show them as a matrix.
The current output is
1 1 1
1 1 1
1 1 1
which is not the correct result.
The code is below:
static void Main(string[] args)
{
int[,] metrix1 = new int[3, 3] { { 2, 0, 2 }, { 0, 1, 2 }, { 1, 2, 1 } };
int[,] metrix2 = new int[3, 3] { { 1, 1, 1 }, { 0, 1, 0 }, { 0, 0, 1 } };
int[,] result = new int[3, 3];
int m1 =0;
int m2 =0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
m1 = metrix1[i, j];
}
}
// metrix 2
for (int y = 0; y < 3; y++)
{
for (int z = 0; z < 3; z++)
{
m2 = metrix2[y, z];
}
}
//m
for (int a = 0; a < 3; a++)
{
for (int b = 0; b < 3; b++)
{
result[a, b] = m1 *m2;
Console.Write(result[a, b] );
}Console.WriteLine();
}Console.ReadLine();
}
}
}

You're approaching this incorrectly.
for (int y = 0; y < 3; y++)
{
for (int z = 0; z < 3; z++)
{
m2 = metrix2[y, z];
}
}
After this, m2 will contain the lower right-hand value of the array (matrix[2, 2]). You're literally multiplying the same value over and over again for your multiplication. You need to put all of this in one for loop.
Also, that's not the correct way to do matrix multiplication. To begin with, your code will only work for a 3x3 matrix; not only can you have other sizes of matrices (4x4, 5x5, etc.), matrices don't even have to be square to be able to multiply them (as long as the number of columns of one equals the number of rows of the other). Even if they are both 3x3 matrices, the calculation would still be wrong. Wikipedia has some good examples of the proper way to do this.
2 0 2 1 1 1 (2*1)+(0*0)+(2*0) (2*1)+(0*1)+(2*0) ...
0 1 2 x 0 1 0 = (0*1)+(1*0)+(2*0) (0*1)(1*1)(2*0) ...
1 2 1 0 0 1 ..

Related

How to vertically flip the integers in a 2D array C#

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.

Get sum of parallel diagonals in matrix

There is a square matrix nxn. The task is to determine the maximum among the sums of elements of diagonals which are parallel to the main diagonal of the matrix. I have managed already to loop throught matrix in proper way and output these elements. So how can I find the sum of every diagonal separately? Or at least how to extract every diagonal separately while looping throught matrix? Thanks in advance!
//Reverse rows of matrix
static int[,] Reverse2DimArray(int[,] theArray)
{
for (int rowIndex = 0; rowIndex <= (theArray.GetUpperBound(0)); rowIndex++)
{
for (int colIndex = 0; colIndex <= (theArray.GetUpperBound(1) / 2); colIndex++)
{
int tempHolder = theArray[rowIndex, colIndex];
theArray[rowIndex, colIndex] = theArray[rowIndex, theArray.GetUpperBound(1) - colIndex];
theArray[rowIndex, theArray.GetUpperBound(1) - colIndex] = tempHolder;
}
}
return theArray;
}
static void Main(string[] args)
{
int[,] reversed = Reverse2DimArray(matrix);
MatrixOutput(reversed, size);
for (int y = 0; y < 2 * size; y++)
{
for (int x = 0; x < size; x++)
{
if (0 <= y - x && y - x < size)
Console.WriteLine(reversed[y - x, x]);
}
}
}
What I have now:
3 6 2 9 5 1 8 4 7
What I need is:
1 2 3
4 5 6
7 8 9
Diadonals: 3; 6,2; 9,5,1; 8,4; 7
Sums: 3; 8; 15; 19
Output: 19

How would you create n nested loops for math?

So, I am trying to wrap my head around understanding how you can use a variable to denote how many times a loop is nested.
Here is an example I write up to simulate the output of dimensions = 4:
static void Main(string[] args)
{
int dimensions = 4; // e.g. for (1, 2, 3, 4), dimensions = 4
Console.WriteLine($"{addNumbers(dimensions)}");
Console.ReadKey();
}
static long addNumbers(int dimensions)
{
long number = 0;
// hard coded to be dimensions = 4
for (int h = 0; h <= dimensions; h++)
for (int i = 0; i <= dimensions; i++)
for (int j = 0; j <= dimensions; j++)
for (int k = 0; k <= dimensions; k++)
number += h + i + j + k; // just some random math
return number;
}
This will present the expected output of:
5000
So to readdress the problem, how can I code to allow this for n dimensions? Thanks for your help!
For arbitrary n dimensions you can loop with a help of array int[] address which represents n dimensions:
static long addNumbers(int dimensions) {
int[] address = new int[dimensions];
// size of each dimension; not necessary equals to dimensions
// + 1 : in your code, int the loops you have i <= dimensions, j <= dimensions etc.
int size = dimensions + 1;
long number = 0;
do {
//TODO: some math here
// i == address[0]; j = address[1]; ... etc.
number += address.Sum();
// next address: adding 1 to array
for (int i = 0; i < address.Length; ++i) {
if (address[i] >= size - 1)
address[i] = 0;
else {
address[i] += 1;
break;
}
}
}
while (!address.All(index => index == 0)); // all 0 address - items're exhausted
return number;
}
Finally, let's add some Linq to look at the results:
int upTo = 5;
string report = string.Join(Environment.NewLine, Enumerable
.Range(1, upTo)
.Select(i => $"{i} -> {addNumbers(i),6}"));
Console.Write(report);
Outcome:
1 -> 1
2 -> 18
3 -> 288
4 -> 5000 // <- We've got it: 5000 for 4 dimensions
5 -> 97200

How to get all the numbers from 2d array that pass the if condition into 1d array

sorry for noob question :). I've got 2d array 3x3 filled with random numbers (-5,5)
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
{
dPole[i, j] = nc.Next(-10, 10);
I want all the numbers that are positive and then save them into 1d array:
foreach (int j in dPole)
{
if (j > 0)
{
Console.WriteLine(j);
for (int i = 0; i < sizeOf1dArray; i++)
jPole[i] = j;
}
}
Output of Console.WriteLine(j)- to check if the condition is right:
6
2
5
6
9
8
Output of 1d Array:
8
8
8
8
8
8
Only the last number is saved into array. Why? Thanks.
An alternative route would be to use Cast<int> to flatten the array and use Where to filter.
int[,] dPole = new int[,] { { 3, -5, 0 }, { -3, 3, 2 }, { -2, 1, 1 } };
int[] jPole = dPole.Cast<int>().Where(i => i > 0).ToArray();
// jPole is now { 3, 3, 2, 1, 1 };
for (int i = 0; i < sizeOf1dArray; i++)
jPole[i] = j;
because at this loop action last j value is 8 and this loop fills all jPole array with j value every time, that means it fills all with 6 first, than puts 2 at entire array, then 5...... and for last it fills it with 8.
try something like that
int i = 0;
foreach (int j in dPole)
{
if (j > 0)
{
Console.WriteLine(j);
jPole[i] = j;
i++;
}
}

rotate a 4x4 array by 180 degrees c#

hi i need to know how to rotate an array by 180 degrees in place. currently i can get it to rotate 90 degrees but just cannot get it to rotate any further. If anyone can help me that would be great as I've been stuck on this question for a couple of days now. Thanks, here is my code:
namespace Question_2_1_
{
class Program
{
static void Main(string[] args)
{
int[,] array = new int[4, 4] {
{ 1,2,3,4 },
{ 5,6,7,8 },
{ 9,0,1,2 },
{ 3,4,5,6 } };
int[,] rotated = RotateMatrix(array, 4);
var rowCount = array.GetLength(0);
var colCount = array.GetLength(1);
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
Console.Write(String.Format("{0}", rotated[i, j]));
}
Console.Write(Environment.NewLine);
}
Console.ReadLine();
}
static int[,] RotateMatrix(int[,] matrix, int n)
{
int[,] ret = new int[n, n];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
ret[i, j] = matrix[n - j - 1, i];
}
}
return ret;
}
}
}
You say you want to rotate in-place, but your rotate method returns a new array. Rotating in-place means you modify the matrix itself, without creating a new one.
But, if you're rotating 90 degrees, you can of course only rotate in-place if the matrix is square.
However, you can always rotate in-place if you're rotating 180 degrees. Let's take a non-square matrix:
{ a, b, c, d, e, f },
{ g, h ,i, j, k, l },
{ m, n, o, p, q, r }
If we rotate it 180 degrees, we end up with:
{ r, q, p, o, n, m },
{ l, k, j, i, h, g },
{ f, e, d, c, b, a }
You can see that an item at [r, c] ends up at [#rows - r - 1, #columns - c - 1]. (0-based of course),
so b at [0, 1] ends up at [3 - 0 - 1, 6 - 1 - 1]
The method you can use is: first swap a and r, then b and q, etc.
This is similar to reversing a 1-dimensional array, just in 2 dimensions.
Just as when reversing a 1-dimensional array, we only go halfway:
the last 2 items we swap are i and j.
I made the method generic, so you can rotate any matrix with it.
static void Rotate180<T>(T[,] matrix) {
int rowCount = matrix.GetLength(0), columnCount = matrix.GetLength(1);
int max = rowCount * columnCount / 2, m = 0;
for (int r = 0; ; ++r) {
for (int c = 0; c < columnCount; ++c) {
Swap(matrix, r, c, rowCount - r - 1, columnCount - c - 1);
if (++m >= max) return;
}
}
}
static void Swap<T>(T[,] matrix, int r1, int c1, int r2, int c2) {
T temp = matrix[r1, c1];
matrix[r1, c1] = matrix[r2, c2];
matrix[r2, c2] = temp;
}
The answer you're looking for is:
ret[i, j] = [n - (i + 1), n - j - 1];
However, this is not in-place as you're creating an entirely different array "ret"
Do it with reversing the columns first, and then the rows.
class Program
{
static void Main(string[] args)
{
var A = new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
RotateMatrix180(ref A);
// A = {{16,15,14,.. }, .. , { ..3,2,1} }
}
public static void RotateMatrix180<T>(ref T[,] matrix)
{
int n = matrix.GetLength(0), m = matrix.GetLength(1);
if(n!=m) { /* error */ }
for(int i = 0; i<n; i++)
{
for(int j = 0; j<n/2; j++)
{
T temp = matrix[i, j];
matrix[i, j]=matrix[i,n-j-1];
matrix[i, n-j-1]=temp;
}
}
for(int i = 0; i<n/2; i++)
{
for(int j = 0; j<n; j++)
{
T temp = matrix[i, j];
matrix[i, j]=matrix[n-i-1, j];
matrix[n-i-1, j]=temp;
}
}
}
}
PS. I added the ref keyword to make it obvious the function modifies the existing array. The code will work the same without it, because arrays are always reference types.

Categories

Resources