C# 2DArray IndexOutOfBound, Why? - c#

In the following C# code I want to create a 2D Array with the size of [5,2].
If I understand it correctly, that should look like this:
0 1 2
0[0,0] [0,1] [0,2]
1[1,0] [1,1] [1,2]
2[2,0] [2,1] [2,2]
3[3,0] [3,1] [3,2]
4[4,0] [4,1] [4,2]
But why does my program throw out an
IndexOutOfRangeException
...?
using System;
namespace program {
class program{
Random random = new Random();
int[,] board = new int[5,2];
public program(){
Print2DArray(randomBoard(0.5,board));
}
public int[,] randomBoard(double chance, int[,] board){
int[,] temp = board;
for(int y = 0; y < board.GetLength(1); y++){
for(int x = 0; x < board.GetLength(0); x++){
if(random.NextDouble() <= chance){
board[y,x] = 1;
} else {
board[y,x] = 0;
}
}
}
return temp;
}
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();
}
}
static void Main(string[] args){
program program1 = new program();
}
}
}

In your code, y goes from 0 to number of elements in dimension 1
while x goes 0 to number of elements in dimension 0
However, inside your for loop you seem to have the dimensions swapped,
board[y,x] = 1; // change this to board [x,y] = 1;
similarly for the else condition it should be board[x,y] = 0

Related

how can i sort a matrix's each row from smallest to largest and then find the matrix's peak value?

i need to write a program that takes 1 to 100 integers randomly, then i need to take this program's transpose, then I need to sort this matrix (each row in itself) from smallest to largest.
and finally, i need to find this matrix's peak value. here is what i have written for the program. for now, it creates a random matrix (20x5) and then it takes its transpose. can you help me with finding its peak value and then sort its each row?
PS.: using classes is mandatory!
using System;
namespace my_matrix;
class Program
{
public int[,] Create(int[,] myarray, int Row, int Clm)
{
Random value = new Random();
myarray = new int[Row, Clm];
int i = 0;
int j = 0;
while (i < Row)
{
while (j < Clm)
{
myarray[i, j] = value.Next(1, 100);
j++;
}
i++;
j = 0;
}
return myarray;
}
public int[,] Print(int[,] myarray, int Row, int Clm)
{
Console.WriteLine("=====ARRAY=====");
for (int a = 0; a < Row; a++)
{
for (int b = 0; b < Clm; b++)
{
Console.Write(myarray[a, b] + " ");
}
Console.WriteLine();
}
return null;
}
public int[,] Transpose(int[,] myarray, int Row, int Clm)
{
for (int b = 0; b < Clm; b++)
{
for (int a = 0; a < Row; a++)
{
Console.Write(myarray[a, b] + " ");
}
Console.WriteLine();
}
return myarray;
}
public int[,] Print_Transpose(int[,] myarray, int Row, int Clm)
{
Console.WriteLine("=====TRANSPOSE=====");
for (int b = 0; b < Clm; b++)
{
for (int a = 0; a < Row; a++)
{
Console.Write(myarray[a, b] + " ");
}
Console.WriteLine();
}
return null;
}
static void Main(string[] args)
{
Program x = new Program();
int[,] myarray = new int[20, 5];
int[,] a = x.Create(myarray, 20, 5);
x.Print(a, 20, 5);
x.Print_Transpose(a, 20, 5);
}
}
i don't know how to make a class which sorta each row from smallest to largest and also i dont know how to create a class which finds the matrix's peak value.
You can run over the array, keeping the maxNum:
public int getMax(int[,] fromArray)
{
int maxNum = 0;
for (int b = 0; b < fromArray.GetUpperBound(1); b++)
{
for (int a = 0; a < fromArray.GetUpperBound(0); a++)
{
if (maxNum < fromArray[a,b])
{
maxNum = fromArray[a, b];
}
}
}
return maxNum;
}
Call the function like:
Console.Write("Max number = {0:D}", x.getMax (a));
If you want a sort method, you can place all values in a List, sort them and convert back to array.
public int[] SortArray(int[,] fromArray)
{
List<int> newList = new List<int>(fromArray.Length);
for (int b = 0; b < fromArray.GetUpperBound(1); b++)
{
for (int a = 0; a < fromArray.GetUpperBound(0); a++)
{
newList.Add (fromArray[a, b]);
}
}
newList.Sort();
return newList.ToArray<int>();
}

How to set random numbers in a matrix between two numbers using loops

I want to randomly generate two matrix arrays so I can later add them up and store them into a third matrix, how would I go about doing this? Nearly totally lost, here's what I have so far.
using System;
namespace question2_addingrandommatrice
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
int[,] newarray = new int[3, 3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
int ran2 = random.Next(-10, 10);
int ran1 = random.Next(-10, 10);
newarray[i, j] = ran1, ran2;
}
}
Console.ReadKey();
}
}
}
You are nearly there, you just needed one random.Next
Here is a method that does it for you
private static int[,] GenerateRandomMatrix(int x, int y)
{
var array = new int[x, y];
for (int i = 0; i < array.GetLength(0); i++)
for (int j = 0; j < array.GetLength(1); j++)
array[i, j] = random.Next(-10, 10);
return array;
}
Add pepper and salt to taste
Usage
// 3*3 random matrix
var matrix = GenerateRandomMatrix(3,3);
Additional Resources
Multidimensional Arrays (C# Programming Guide)
You can simply do this.
Random random = new Random();
int[,] newarray = new int[3, 3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
newarray[i, j] = random.Next(-10, 10); ;
}

Custome Size 2D Array with Fitting For Loops

I am creating a 2D array that can have any custom size 1x1, 2x2, 3x3 .... nxn and depending on what the size of the array is, it gets filled with 0 to (n^2)-1, so if it is 2x2 it outputs:
3 2
1 0
It should be something like this int[,] arr = new int [n, n];, to create the 2d array, but how would the for loops be constructed?
what I have tried
using System;
namespace moveElement {
public class move {
static void Main(string[] args) {
int n = 3;
int[, ] arr = new int[n, n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(arr[i, j] + " ");
}
Console.WriteLine();
}
}
}
}
The result of the code:
0 0 0
0 0 0
0 0 0
int k = 0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
arr[i,j] = k++;
}
}
full code to the question:
using System;
namespace moveElement
{
public class move
{
static void Main(string[] args)
{
int n = 3;
int[,] arr = new int [n, n];
//Ivan Smyrnov solution
int k = (n * n) - 1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
arr[i,j] = k--;
}
}
//Ivan Smyrnov solution
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Console.Write(arr[i, j] + " ");
}
Console.WriteLine();
}
}
}
}
Output when n is 3:
8 7 6
5 4 3
2 1 0

Problem with program that separates 2D array into even/odd 2D arrays (extra zeroes in even/odd arrays)

I am practicing with 2D arrays and am making a program that separates a 2D array with random integer values into two separate arrays based on if the values are even or odd.
However, the program seems to be adding additional zeroes to each row in the even and odd arrays. What am I doing wrong?
I think the problem is in the sort() function where I determine the size of the even and odd arrays but I am not sure.
class Program
{
static void Main(string[] args)
{
int[,] arr = new int[10, 10];
// Fills 2D array with random values and prints them out
Random r = new Random();
for (int y = 0; y < arr.GetLength(0); y++)
{
for (int x = 0; x < arr.GetLength(1); x++)
{
arr[y, x] = r.Next(1, 99);
Console.Write(arr[y,x] + " ");
}
Console.WriteLine();
}
Console.WriteLine();
// Function that separates original array into 2 separate ones (even and odd)
sort(arr);
Console.ReadLine();
}
public static void sort(int[,] array)
{
int j1 = 0;
int i1 = 0;
int j2 = 0;
int i2 = 0;
// Increases the size of the even/odd arrays whenever the value of the original array is even/odd respectively
// I think this is where the problem is
for (int y = 0; y < array.GetLength(0); y++)
{
for (int x = 0; x < array.GetLength(1); x++)
{
if (array[y,x] % 2 == 0)
{
i1 += 1;
}
else
{
i2 += 1;
}
}
j1 += 1;
j2 += 1;
}
int[,] evenArr = new int[j1, i1];
int[,] oddArr = new int[j2, i2];
// Sets the values for the even/odd arrays
for (int y = 0; y < array.GetLength(0); y++)
{
for (int x = 0; x < array.GetLength(1); x++)
{
if (array[y, x] % 2 == 0)
{
evenArr[y, x] = array[y, x];
}
else
{
oddArr[y, x] = array[y, x];
}
}
}
// Prints the values for the even array
for (int y = 0; y < evenArr.GetLength(0); y++)
{
for (int x = 0; x < evenArr.GetLength(1); x++)
{
Console.Write(evenArr[y, x] + " ");
}
Console.WriteLine();
}
Console.WriteLine();
// Prints the values for the odd array
for (int y = 0; y < oddArr.GetLength(0); y++)
{
for (int x = 0; x < oddArr.GetLength(1); x++)
{
Console.Write(oddArr[y, x] + " ");
}
Console.WriteLine();
}
}
}
When you initialize your arrays (evenArr = new int[j1, i1], oddArr = new int[j2, i2];) the default values are zero. Since there's an extra zero it means you should check the length and probably reduce it by one.

Shuffling a 2D array without using Collections

I don't know how to shuffle 2D array without duplicate elements. Can anyone help me to shuffle a 2D array?
Here is what I have so far:
public class Shuffle2DArray
{
public Shuffle2DArray ()
{
}
public static void Main(string[] args)
{
int[,] a = new int[3, 3] { { 1, 2, 3, }, { 6, 7, 8 }, { 11, 12, 13 } };
Shuffle2DArray shuffle = new Shuffle2DArray ();
shuffle.getshuffle2D (a);
}
void getshuffle2D(int[,] arr)
{
Random ran = new Random ();
for (int i = 0; i < arr.GetLength (0); i++) {
for (int j = 0; j < arr.GetLength (1); j++) {
int m = ran.Next(arr.GetLength (0)-1);
int n = ran.Next(arr.GetLength (1)-1);
int temp = arr[0,j];
arr[i,0] = arr[m,n+1];
arr[m,n] = temp;
Console.Write(arr[i,j]+ "\t");
}
Console.WriteLine();
}
}
}
Well, I would say shuffle the 2d array the same way as you shuffle the 1d array.
For instance, Fisher–Yates shuffle for 1d array is something like this
public static class Utils
{
public static void Swap<T>(ref T a, ref T b) { var temp = a; a = b; b = temp; }
public static void RandomShuffle<T>(this T[] target, Random random = null)
{
if (target.Length < 2) return;
if (random == null) random = new Random();
for (int i = target.Length - 1; i > 0; i--)
{
int j = random.Next(i + 1);
if (i != j) Swap(ref target[i], ref target[j]);
}
}
}
All you need is to realize that having a 2d array
T[,] array
and accessing the element of the array
array[row, column]
that
row = index / columnCount
column = index % columnCount
where
index = [0, array.Lenght - 1] corresponds to the index in 1d array
columnCount = array.GetLength(1)
adding the 2d version function to the class above is trivial
public static class Utils
{
// ...
public static void RandomShuffle<T>(this T[,] target, Random random = null)
{
if (target.Length < 2) return;
if (random == null) random = new Random();
int columnCount = target.GetLength(1);
for (int i = target.Length - 1; i > 0; i--)
{
int j = random.Next(i + 1);
if (i != j) Swap(ref target[i / columnCount, i % columnCount], ref target[j / columnCount, j % columnCount]);
}
}
}
Sample usage:
int[,] a = new int[3, 3] { { 1, 2, 3, }, { 6, 7, 8 }, { 11, 12, 13 } };
a.RandomShuffle();
You need to first order your array by random sequence of numbers. What you are doing now is just changing two random items of 2d array at each iterate thus it may result in duplicate items.
Look at this Sort algorithm for 1d array.
for (int i = 0; i < arr.Length - 1; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] > arr[j]) // ran.Next(-1,1) == 0 // or any random condition
{
int temp = arr[i];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
As you can see we need 2 loops to sort 1d array. So in order to sort 2d array we need 4 loops.
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(0); j++)
{
for (int k = 0; k < arr.GetLength(1); k++)
{
for (int l = 0; l < arr.GetLength(1); l++)
{
if (arr[i, k] > arr[j, l]) // ran.Next(-1,1) == 0
{
int temp = arr[i, k];
arr[i, k] = arr[j, l];
arr[j, l] = temp;
}
}
}
}
}
Then write another algorithm to print items.
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i, j] + "\t");
}
Console.WriteLine();
}
This was Sort algorithm. Now if you just change this condition with random one you sort your array by random.
Change if (arr[i, k] > arr[j, l])
To if (ran.Next(-1,1) == 0). this is just randomly true or false.

Categories