I am trying to put the values of a matrix into an array in a specific order. The matrix is 2*length, where the length is the length of the message chosen by the user divided by two. The array is the entire length.
I have attempted using a for-loop where the first two values of the matrix ([0, 0] and [1, 0]) are put in the array.
Int[,] result = new int[2, length/2];
String[] resultArray = new string[length];
tracker = 0;
while (tracker < length)
{
for (int i = 0; i < length/2; i++)
{
resultArray[2*i] = Convert.ToString(result[0, i]);
resultArray[(2*i)+1] = Convert.ToString(result[1, i]);
}
tracker++;
}
When I run this code, I get the System.IndexOutOfRangeException: 'Index was outside the bounds of the array.' error message. The second expression in the for-loop is highlited.
I can't seem to realize what I've done wrong. (2*i)+1 when i=(length/2-1) should equal length-1, right?
Not a explicit answer, but way more fault proof than your aproach: to iterate trough a square matrix you can use
var y = i / d
var x = i % d
where d is the dimension of the array
int d = 2;
int length = d * d; // square matrix;
for (int i = 0; i < length; i++)
{
// iterate trough the array via column -> row by row (or horizontal)
int y = i / d;
int x = i % d; // => i mod 2 (remnant of division by 2)
resultArray[i] = Convert.ToString(result[x, y]);
}
for (int i = 0; i < length; i++)
{
// iterate trough the array via row -> column by column (or vertical)
int x = i / d;
int y = i % d;
resultArray[i] = Convert.ToString(result[x, y]);
}
You can actually iterate over a matrix using LINQ. You just need to use Cast<T>() to get the right IEnumerable interface then use a simple Select. It'll iterate over the first dimension first and within that iterate over the second dimension.
If I set up test data like this:
int[,] result = new int[2, 5];
result[0,0] = 00;
result[0,1] = 01;
result[0,2] = 02;
result[0,3] = 03;
result[0,4] = 04;
result[1,0] = 10;
result[1,1] = 11;
result[1,2] = 12;
result[1,3] = 13;
result[1,4] = 14;
Then this statement:
var resultArray1 = result.Cast<int>().Select( n => n.ToString("00")).ToArray();
Will yield these results:
00
01
02
03
04
10
11
12
13
14
If you wish to iterate over the second dimension first, you can write a short extension method:
public static IEnumerable<T> ToSingleDimension<T>(this T[,] source)
{
for (int i=0; i<=source.GetUpperBound(1); i++)
{
for (int j=0; j<=source.GetUpperBound(0); j++)
{
yield return source[j,i];
}
}
}
And call it like this:
var resultArray2 = result.ToSingleDimension().Select( n => n.ToString("00")).ToArray();
Which will yield these results:
00
10
01
11
02
12
03
13
04
14
See the example on DotNetFiddle.
You can use MathNet.Numerics library with some LINQ to achieve what you want:
PM > Install-Package MathNet.Numerics
var result = new double[2,4]
{
{ 1,2,3,4 },
{ 5,6,7,8 },
};
var resultArray = Matrix
.Build
.DenseOfArray(result)
.ToRowArrays()
.SelectMany(q => q.ToArray().Select(w => w.ToString()))
.ToArray();
You can use ToColumnArrays() if your initial array has shape [4,2] rather than [2,4]
Related
int numberOfThreads=4;
int division = (size * size) / numberOfThreads;
int startI = 0, startJ = 0;
int endI = division/size,endJ=division%size;
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Start I: {0} Start J:{1} && End I: {2} End J: {3}",startI,startJ,endI,endJ);
startI = endI;
startJ = endJ;
//endI += (division/size); <-- how to find next ending index?
//endJ += (division % size); <-- how to find next ending index?
}
I want to divide my 2D array into numberOfThreads parts. I know how to get the starting and ending index of first part, but I need help to find endI and endJ for rest of the array. For example if I had a 4x4 array which I want to divide in to 4 partsI would want
0,0 to 0,3 -> 1,0 to 1,3 -> 2,0 to 2,3 -> 3,0 to 3,4
If I want to divide it ino 8 parts:
0,0 to 0,0 -> 0,1 to 0,1 -> 0,2 to 0,2 -> 0,3 to 0,3 etc
So assuming I've understood correctly, I think you want to end up with something like this:
[
[[0,0],[0,1][0,2][0,3]],
[[1,0],[1,1][1,2][1,3]],
[[2,0],[2,1][2,2][2,3]],
[[3,0],[3,1][3,2][3,3]]
]
Or perhaps like this:
[
[0,0],
[0,1],
[0,2],
[0,3],
[1,0],
[1,1],
[1,2],
[1,3],
[2,0],
[2,1],
[2,2],
[2,3],
[3,0],
[3,1],
[3,2],
[3,3]
}
I'm still a little unclear what your original array looks like, but I'm guessing you're doing it from array dimensions rather than an actual filled array.
If this is all still the case I would do something like this for the 1st version:
public int[][][] GetArrayCoordinates(int xAxisSize, int yAxisSize)
{
var coordinatesArray = new int[xAxisSize][][];
for (int x = 0; x < xAxisSize; x++)
{
coordinatesArray[x] = new int[yAxisSize][];
for (int y = 0; y < yAxisSize; y++)
{
coordinatesArray[x][y] = new int[] { x , y};
}
}
return coordinatesArray;
}
This should give a multidimensional array (an array of arrays of arrays) with the x co-ordinate coming first in each set.
2nd version:
public int[][] GetArrayCoordinates(int xAxisSize, int yAxisSize)
{
var index = 0;
var coordinatesArray = new int[xAxisSize * yAxisSize][];
for (int x = 0; x < xAxisSize; x++)
{
for (int y = 0; y < yAxisSize; y++)
{
coordinatesArray[index] = new int[] { x, y };
index++;
}
}
return coordinatesArray;
}
This should give you a jagged array (array of arrays) with the x co-ordinate coming first in each set.
I'm working on a math game in the Unity game engine using C#, specifically a reusable component to teach the grid method for multiplication. For example, when given the numbers 34 and 13, it should generate a 3X3 grid (a header column and row for the multiplier and multiplicand place values and 2X2 for the number of places in the multiplier and multiplicand). Something that looks like this:
My issue is that I don't know the best way to extract the place values of the numbers (eg 34 -> 30 and 4). I was thinking of just converting it to a string, adding 0s to the higher place values based on its index, and converting it back to an int, but this seems like a bad solution. Is there a better way of doing this?
Note: I'll pretty much only be dealing with positive whole numbers, but the number of place values might vary.
Thanks to all who answered! Thought it might be helpful to post my Unity-specific solution that I constructed with all the replies:
List<int> GetPlaceValues(int num) {
List<int> placeValues = new List<int>();
while (num > 0) {
placeValues.Add(num % 10);
num /= 10;
}
for(int i = 0;i<placeValues.Count;i++) {
placeValues[i] *= (int)Mathf.Pow(10, i);
}
placeValues.Reverse();
return placeValues;
}
Take advantage of the way our number system works. Here's a basic example:
string test = "12034";
for (int i = 0; i < test.Length; ++i) {
int digit = test[test.Length - i - 1] - '0';
digit *= (int)Math.Pow(10, i);
Console.WriteLine("digit = " + digit);
}
Basically, it reads from the rightmost digit (assuming the input is an integer), and uses the convenient place value of the way our system works to calculate the meaning of the digit.
test.Length - i - 1 treats the rightmost as 0, and indexes positive to the left of there.
- '0' converts from the encoding value for '0' to an actual digit.
Play with the code
Perhaps you want something like this (ideone):
int n = 76302;
int mul = 1;
int cnt = 0;
int res[10];
while(n) {
res[cnt++] = (n % 10) * mul;
mul*=10;
cout << res[cnt-1] << " ";
n = n / 10;
}
output
2 0 300 6000 70000
My answer is incredibly crude, and could likely be improved by someone with better maths skills:
void Main()
{
GetMulGrid(34, 13).Dump();
}
int[,] GetMulGrid(int x, int y)
{
int[] GetPlaceValues(int num)
{
var numDigits = (int)Math.Floor(Math.Log10(num) + 1);
var digits = num.ToString().ToCharArray().Select(ch => Convert.ToInt32(ch.ToString())).ToArray();
var multiplied =
digits
.Select((d, i) =>
{
if (i != (numDigits - 1) && d == 0) d = 1;
return d * (int)Math.Pow(10, (numDigits - i) - 1);
})
.ToArray();
return multiplied;
}
var xComponents = GetPlaceValues(x);
var yComponents = GetPlaceValues(y);
var arr = new int[xComponents.Length + 1, yComponents.Length + 1];
for(var row = 0; row < yComponents.Length; row++)
{
for(var col = 0; col < xComponents.Length; col++)
{
arr[row + 1,col + 1] = xComponents[col] * yComponents[row];
if (row == 0)
{
arr[0, col + 1] = xComponents[col];
}
if (col == 0)
{
arr[row + 1, 0] = yComponents[row];
}
}
}
return arr;
}
For your example of 34 x 13 it produces:
And for 304 x 132 it produces:
It spits this out as an array, so how you consume and display the results will be up to you.
For two-digit numbers you can use modulo
int n = 34;
int x = n % 10; // 4
int y = n - x; // 30
I have a matrix like this
13 7 22
101 50 3
I Want to Print The smallest Number from the same.
Below is my Code:
using System;
class Class1
{ int min(int[,] arr)
{
int small = arr[0, 0];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (small > arr[i, j])
{
small = arr[i, j];
}
}
}
return small;
}
public static void Main()
{
int[,] x;
x = new int[,] { { 13, 7, 22 }, { 101, 50, 3 } };
Class1 obj = new Class1();
Console.WriteLine("Smallest Element : {0}", obj.min(x));
Console.ReadLine();
}
}
Throws Error as
{"Index was outside the bounds of the array."}
Expected output is 3
Why am getting this error? Please give me solution.
Note that you can use foreach to iterate over all the elements of a multidimensional array without having to worry about indices.
So it is simpler to write your min() method like so (note that I'm also using Math.Min() to find the lower of two values rather than writing my own if to do it):
static int min(int[,] arr)
{
int small = int.MaxValue;
foreach (int n in arr)
small = Math.Min(n, small);
return small;
}
Also note how I initialised small to be the largest possible int, in order to avoid having to access the first value of the array to initialise it.
If you wanted to use Linq to do the same thing you can just do this:
int min = array.Cast<int>().Min();
The reason that Cast<int> is needed is because a multidimensional array only implements the non-generic IEnumerable rather than the generic IEnumerable<T>. See this question for more details.
However using Linq an advanced topic if you are currently learning C#, in which case don't worry about that for now!
Try the following code, it will resolve X x X matrix
List<List<int>> matrix = new List<System.Collections.Generic.List<int>>()
{
new List<int>() {5,10,6}, new List<int>() {6,11,7}, new List<int>() {7,12,8}, new List<int>() {8,13,9}
};
To find MIN Value:
matrix.SelectMany(m => m.Select(n => n)).OrderBy(m => m).FirstOrDefault().Dump();
To find MAX Value
matrix.SelectMany(m => m.Select(n => n)).OrderByDescending(m => m).FirstOrDefault().Dump();
If you are using multi dimensional array
int[,] matrix = { { 1, 2, 3 }, { 3, 4, 5 } };
IEnumerable<int> query = matrix.OfType<int>();
query.SelectMany(m => m.Select(n => n)).OrderBy(m => m).FirstOrDefault().Dump();
Your array is 2X3 so you have specify condition for first loop is i<2
Like this
int min(int[,] arr)
{
int small = arr[0, 0];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
if (small > arr[i, j])
{
small = arr[i, j];
}
}
}
return small;
}
I have been testing this implementation of radix-Sort:
public void RadixSort(int[] a)
{
// our helper array
int[] t=new int[a.Length];
// number of bits our group will be long
int r=4; // try to set this also to 2, 8 or 16 to see if it is quicker or not
// number of bits of a C# int
int b=32;
// counting and prefix arrays
// (note dimensions 2^r which is the number of all possible values of a r-bit number)
int[] count=new int[1<<r];
int[] pref=new int[1<<r];
// number of groups
int groups=(int)Math.Ceiling((double)b/(double)r);
// the mask to identify groups
int mask = (1<<r)-1;
// the algorithm:
for (int c=0, shift=0; c<groups; c++, shift+=r)
{
// reset count array
for (int j=0; j<count.Length; j++)
count[j]=0;
// counting elements of the c-th group
for (int i=0; i<a.Length; i++)
count[(a[i]>>shift)&mask]++;
// calculating prefixes
pref[0]=0;
for (int i=1; i<count.Length; i++)
pref[i]=pref[i-1]+count[i-1];
// from a[] to t[] elements ordered by c-th group
for (int i=0; i<a.Length; i++)
t[pref[(a[i]>>shift)&mask]++]=a[i];
// a[]=t[] and start again until the last group
t.CopyTo(a,0);
}
// a is sorted
}
And I don't quite understand why you would set r to a different value than b.
I got the best results by always setting it to the b value. What would be an example where I get an advantage from using a smaller value than b?
Edit: This only works if you don't use the full range of the input type:
Example: using an int[] as input will only sort with r = b if you use r = b < 32. So in the case b = 32 you need to set r to 16
I don't understand using 2 bits to separate 4000 elements into groups of 3, since 4000 / 3 is not a power of 2.
If the range of values is 0 to 4000, and the size of the array is >= 4000, counting sort would be faster:
#define SORTMAX 4000
void CountSort(int a[], size_t n)
{
size_t cnt[SORTMAX + 1];
for (size_t i = 0; i <= SORTMAX; i++)
cnt[i] = 0;
for (size_t i = 0; i < n; i++)
cnt[a[i]]++; // no out of range check
for (size_t j = 0, i = 0; i <= SORTMAX; i++)
while (cnt[i]--)
a[j++] = (int)i;
}
I have a list{int a,int b,int c} that holds data like
a b c
12 23 45
24 45 34
44 56 77
12 34 11
98 35 33
...
I want to have that data in 3 arrays
so if I have 3 separated arrays I would do
int[] a = new int[lst.Count];
int[] b = new int[lst.Count];
int[] c = new int[lst.Count];
for (int i = 0; i < lst.Count; i++)
{
a[i] = lst[i].a;
b[i] = lst[i].b;
c[i] = lst[i].c;
}
Now how to copy list{int, int, int} to 3d array?
int size = lst.Count;
int[, ,] array_t = new int[size , size , size ];
Your int[,,] is a 3-dimensional array, but it seems you're only dealing with 2-dimensional data, so an int[,] will be fine:
int[,] array_t = new int[lst.Count,3];
for (int i = 0; i < lst.Count; i++)
{
array_t[i,0] = a[i];
array_t[i,1] = b[i];
array_t[i,2] = c[i];
}
Or skip the intermediate arrays:
int[,] array_t = new int[lst.Count,3];
for (int i = 0; i < lst.Count; i++)
{
array_t[i,0] = lst[i].a;
array_t[i,1] = lst[i].b;
array_t[i,2] = lst[i].c;
}
If I understood you correctly (which I'm not sure), you seem to want to have a 3d array representing points at certain coordinates contained in your list. If it is what you want to do:
for(int i = 0; i < lst.Count; i++)
array_t[lst[i].a, lst[i].b, lst[i].c] = 1;
the rest of your array would be filled with zeros.