How to resize multidimensional (2D) array in C#? - c#

I tried the following but it just returns a screwed up array.
T[,] ResizeArray<T>(T[,] original, int rows, int cols)
{
var newArray = new T[rows,cols];
Array.Copy(original, newArray, original.Length);
return newArray;
}

Most methods in the array class only work with one-dimensional arrays, so you have to perform the copy manually:
T[,] ResizeArray<T>(T[,] original, int rows, int cols)
{
var newArray = new T[rows,cols];
int minRows = Math.Min(rows, original.GetLength(0));
int minCols = Math.Min(cols, original.GetLength(1));
for(int i = 0; i < minRows; i++)
for(int j = 0; j < minCols; j++)
newArray[i, j] = original[i, j];
return newArray;
}
To understand why it doesn't work with Array.Copy, you need to consider the layout of a multidimensional array in memory. The array items are not really stored as a bidimensional array, they're stored contiguously, row after row. So this array:
{ { 1, 2, 3 },
{ 4, 5, 6 } }
Is actually arranged in memory like that: { 1, 2, 3, 4, 5, 6 }
Now, assume you want to add one more row and one more column, so that the array looks like this:
{ { 1, 2, 3, 0 },
{ 4, 5, 6, 0 },
{ 0, 0, 0, 0 } }
The layout in memory would now be as follows: { 1, 2, 3, 0, 4, 5, 6, 0, 0, 0, 0, 0 }
But Array.Copy treats all arrays as one-dimensional. MSDN says:
When copying between multidimensional arrays, the array behaves like a long one-dimensional array, where the rows (or columns) are conceptually laid end to end
So when you try to copy the original array to the new one, it just copies one memory location to the other, which gives, in one-dimensional representation:
{ 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0 }.
If you convert that to a two-dimensional representation, you get the following:
{ { 1, 2, 3, 4 },
{ 5, 6, 0, 0 },
{ 0, 0, 0, 0 } }
This is why you're getting a screwed up array... Note that it would work property if you changed the number of rows, but not the number of columns.

This combines Thomas and Manuel's answers and provides the performance benefit of Array.Copy and the ability to both increase and decrease the size of the array.
protected T[,] ResizeArray<T>(T[,] original, int x, int y)
{
T[,] newArray = new T[x, y];
int minX = Math.Min(original.GetLength(0), newArray.GetLength(0));
int minY = Math.Min(original.GetLength(1), newArray.GetLength(1));
for (int i = 0; i < minY; ++i)
Array.Copy(original, i * original.GetLength(0), newArray, i * newArray.GetLength(0), minX);
return newArray;
}
Please note that the x and y axis of your array is up to your own implementation and you may need to switch the 0s and 1s around to achieve the desired effect.

Thank you Thomas, your explanation was very helpful but your implemented solution is too slow. I modified it to put Array.Copy to good use.
void ResizeArray<T>(ref T[,] original, int newCoNum, int newRoNum)
{
var newArray = new T[newCoNum,newRoNum];
int columnCount = original.GetLength(1);
int columnCount2 = newRoNum;
int columns = original.GetUpperBound(0);
for (int co = 0; co <= columns; co++)
Array.Copy(original, co * columnCount, newArray, co * columnCount2, columnCount);
original = newArray;
}
Here I'm assuming that there are more rows than columns so I structured the array as [columns, rows]. That way I use Array.Copy on an entire column in one shot (much faster than one cell a time).
It only works to increment the size of the array but it can probably be tweaked to reduce the size too.

And for generic resizing of multi dimensional arrays:
public static class ArrayExtentions {
public static Array ResizeArray(this Array arr, int[] newSizes) {
if (newSizes.Length != arr.Rank) {
throw new ArgumentException("arr must have the same number of dimensions as there are elements in newSizes", "newSizes");
}
var temp = Array.CreateInstance(arr.GetType().GetElementType(), newSizes);
var sizesToCopy = new int[newSizes.Length];
for (var i = 0; i < sizesToCopy.Length; i++) {
sizesToCopy[i] = Math.Min(newSizes[i], arr.GetLength(i));
}
var currentPositions = new int[sizesToCopy.Length];
CopyArray(arr, temp, sizesToCopy, currentPositions, 0);
return temp;
}
private static void CopyArray(Array arr, Array temp, int[] sizesToCopy, int[] currentPositions, int dimmension) {
if (arr.Rank - 1 == dimmension) {
//Copy this Array
for (var i = 0; i < sizesToCopy[dimmension]; i++) {
currentPositions[dimmension] = i;
temp.SetValue(arr.GetValue(currentPositions), currentPositions);
}
} else {
//Recursion one dimmension higher
for (var i = 0; i < sizesToCopy[dimmension]; i++) {
currentPositions[dimmension] = i;
CopyArray(arr, temp, sizesToCopy, currentPositions, dimmension + 1);
}
}
}
}

I was looking for something like this, but something that would effectively let me "pad" a 2D array from both ends, and also have the ability to reduce it.
I've run a very simple test:
The array was string[1000,1000], average time for my machine was 44ms per resize.
The resize increased or decreased padding on all sides by 1 each time, so all data in the array was copied. This performance hit was more than acceptable for my requirements.
public static void ResizeArray<T>(
ref T[,] array, int padLeft, int padRight, int padTop, int padBottom)
{
int ow = array.GetLength(0);
int oh = array.GetLength(1);
int nw = ow + padLeft + padRight;
int nh = oh + padTop + padBottom;
int x0 = padLeft;
int y0 = padTop;
int x1 = x0 + ow - 1;
int y1 = y0 + oh - 1;
int u0 = -x0;
int v0 = -y0;
if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0;
if (x1 >= nw) x1 = nw - 1;
if (y1 >= nh) y1 = nh - 1;
T[,] nArr = new T[nw, nh];
for (int y = y0; y <= y1; y++)
{
for (int x = x0; x <= x1; x++)
{
nArr[x, y] = array[u0 + x, v0 + y];
}
}
array = nArr;
}
padLeft, padRight, padTop, padBottom can be negative or positive. If you pass in all 0s, the array generated will be identical to the source array.
This could be particularly useful for anyone who wants to "scroll" their elements around their array.
Hope it's of use to someone!

This builds on Manuel's answer to also allow to apply an offset to the copied data (e.g. to copy the source array to the center of the target array, instead of to [0, 0]):
public static T[,] ResizeArray<T>(T[,] original, int newWidth, int newHeight, int offsetX = 0, int offsetY = 0)
{
T[,] newArray = new T[newWidth, newHeight];
int width = original.GetLength(0);
int height = original.GetLength(1);
for (int x = 0; x < width; x++) {
Array.Copy(original, x * height, newArray, (x + offsetX) * newHeight + offsetY, height);
}
return newArray;
}

I really like Stephen Tierney's answer building upon the work of others.
As Stephen notes the x/y is up to interpretation.
I have refactored it slightly to use m*n sizes & ij coordinate indexing that is probably the most common notation for matrices (wikipedia for reference https://en.wikipedia.org/wiki/Matrix_(mathematics)).
In this notation,
'm' is the number of rows
'n' is the number of columns
'i' is the first coordinate, aka row index (increases as you go down)
public static T[,] Resize2D<T>(this T[,] original, int m, int n)
{
T[,] newArray = new T[m, n];
int mMin = Math.Min(original.GetLength(0), newArray.GetLength(0));
int nMin = Math.Min(original.GetLength(1), newArray.GetLength(1));
for (int i = 0; i < mMin; i++)
Array.Copy(original, i * original.GetLength(1), newArray, i * newArray.GetLength(1), nMin);
return newArray;
}

Related

How to quickly move items in the row of the matrix [duplicate]

How can I quickly shift all the items in an array one to the left, padding the end with null?
For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
Edit: I said quickly but I guess I meant efficiently. I need to do this without creating a List or some other data structure. This is something I need to do several hundred thousand times in as short amount of time as possible.
Here's my test harness...
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
var destination = new int?[source.Length];
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000;i++)
{
Array.Copy(source, 1, destination, 0, source.Length - 1);
}
s.Stop();
Console.WriteLine(s.Elapsed);
Here are the performance results for 1 million iterations of each solution (8 Core Intel Xeon E5450 # 3.00GHz)
100 elements 10000 elements
For Loop 0.390s 31.839s
Array.Copy() 0.177s 12.496s
Aaron 1 3.789s 84.082s
Array.ConstrainedCopy() 0.197s 17.658s
Make the choice for yourself :)
The quickest way to do this is to use Array.Copy, which in the final implementation uses a bulk memory transfer operation (similar to memcpy):
var oldArray = new int?[] { 1, 2, 3, 4, 5, 6 };
var newArray = new int?[oldArray.Length];
Array.Copy(oldArray, 1, newArray, 0, oldArray.Length - 1);
// newArray is now { 2, 3, 4, 5, 6, null }
Edited: according to the documentation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
So if you don't want to allocate a new array, you can pass in the original array for both source and destination--although I imagine the tradeoff will be a somewhat slower performance since the values go through a temporary holding position.
I suppose, as in any investigation of this kind, you should do some quick benchmarking.
Here is my solution, similar to Task's in that it is a simple Array wrapper and that it takes O(1) time to shift the array to the left.
public class ShiftyArray<T>
{
private readonly T[] array;
private int front;
public ShiftyArray(T[] array)
{
this.array = array;
front = 0;
}
public void ShiftLeft()
{
array[front++] = default(T);
if(front > array.Length - 1)
{
front = 0;
}
}
public void ShiftLeft(int count)
{
for(int i = 0; i < count; i++)
{
ShiftLeft();
}
}
public T this[int index]
{
get
{
if(index > array.Length - 1)
{
throw new IndexOutOfRangeException();
}
return array[(front + index) % array.Length];
}
}
public int Length { get { return array.Length; } }
}
Running it through Jason Punyon's test code...
int?[] intData = Enumerable.Range(1, 100).Cast<int?>().ToArray();
ShiftyArray<int?> array = new ShiftyArray<int?>(intData);
Stopwatch watch = new Stopwatch();
watch.Start();
for(int i = 0; i < 1000000; i++)
{
array.ShiftLeft();
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Takes ~29ms, regardless of the array size.
Use the Array.Copy() method as in
int?[] myArray = new int?[]{0,1,2,3,4};
Array.Copy(myArray, 1, myArray, 0, myArray.Length - 1);
myArray[myArray.Length - 1] = null
The Array.Copy is probably the way, Microsoft wanted us to copy array elements...
Couldn't you use a System.Collections.Generic.Queue instead of an array ?
I feel like you need to perform actions on your value the discard it, thus using a queue seems to be more appropriate :
// dummy initialization
System.Collections.Generic.Queue<int> queue = new Queue<int>();
for (int i = 0; i < 7; ++i ) { queue.Enqueue(i); }// add each element at the end of the container
// working thread
if (queue.Count > 0)
doSomething(queue.Dequeue());// removes the last element of the container and calls doSomething on it
For any pour soul finding this thread and about to implement one of the highly rated answers. All of them are trash, I'm not sure why that is. Maybe Dested asked for a new array implementation at first or something that has now been removed from the question. Well if you simply want to shift the array and don't need a new one, see an answer like tdaines's answer. And read up on things like the Circular Buffer / Ring Buffer : http://en.wikipedia.org/wiki/Circular_buffer. No moving of the actual data is necessary. The performance of shifting an array should not be tied to the size of the array.
If it absolutely has to be in an array, then I would recommend the most obvious code possible.
for (int index = startIndex; index + 1 < values.Length; index++)
values[index] = values[index + 1];
values[values.Length - 1] = null;
This gives the optimizer the most opportunities to find the best way on whatever target platform the program is installed on.
EDIT:
I just borrowed Jason Punyon's test code, and I'm afraid he's right. Array.Copy wins!
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
int indexToRemove = 4;
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000; i++)
{
Array.Copy(source, indexToRemove + 1, source, indexToRemove, source.Length - indexToRemove - 1);
//for (int index = indexToRemove; index + 1 < source.Length; index++)
// source[index] = source[index + 1];
}
s.Stop();
Console.WriteLine(s.Elapsed);
Array.Copy takes between 103 and 150 ms on my machine.
for loop takes between 269 and 338 ms on my machine.
Can't you
allocate the array with an extra 1000 elements
have an integer variable int base = 0
instead of accessing a[i] access a[base+i]
to do your shift, just say base++
Then after you've done this 1000 times, copy it down and start over.
That way, you only do the copy once per 1000 shifts.
Old joke:
Q: How many IBM 360s does it take to shift a register by 1 bit?
A: 33. 32 to hold the bits in place, and 1 to move the register. (or some such...)
You can use the same array as source and destination for fast in-place copy:
static void Main(string[] args)
{
int[] array = {0, 1, 2, 3, 4, 5, 6, 7};
Array.ConstrainedCopy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = 0;
}
You might do it like this:
var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 }; // Your array
var itemList = new List<int?>(items); // Put the items in a List<>
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
items = itemList.ToArray(); // Turn the list back into an array
Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:
var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
The best and most efficient method I believe is using Buffer.BlockCopy function.
You will set both source and destination to your array, the offset of the source is 1. Depending on your array type (I assume it is int), 1 int = 4 bytes, so you must pass in 4 as the second parameter of this function. Note that the offset is byte offset.
So it looks like this:
int bytes2copy = yourArray.length - 4;
Buffer.BlockCopy(yourArray, 4, yourArray, 0, bytes2copy);
yourArray[yourArray.length-1] = null;
Try this! using Linq. No need of second Array.
var i_array = new int?[] {0, 1, 2, 3, 4, 5, 6 };
i_array = i_array.Select((v, k) => new { v = v, k = k }).
Where(i => i.k > 0).Select(i => i.v).ToArray();
Array.Resize(ref i_array, i_array.Length + 1);
Output:
[0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
If you own the memory you could consider using Unsafe Code and good old fashioned pointers.
Make yourself a memory stream and lock it down or use Marshal.AllocHGlobal
Construct all your arrays in it with a little bit of padding at the beginning and end.
increment or decrement all of the array pointers at once. You'll still need to loop back and set your nulls.
If you need to selectively increment or decrement the arrays you would have to add padding between them.
Arrays are incredibly low level data structures, if you treat them in a low level way you can get huge performance out of them.
A baytrail doing this could outperform Jason's with all its copying 8 Core Intel Xeon E5450 # 3.00GHz
Not tested this code, but it should shifts all the values to right by one. Note that the last three lines of code is all you require to efficiently shift the array.
public class Shift : MonoBehaviour {
//Initialize Array
public int[] queue;
void Start () {
//Create Array Rows
queue = new int[5];
//Set Values to 1,2,3,4,5
for (int i=0; i<5;i++)
{
queue[i] = i + 1;
}
//Get the integer at the first index
int prev = queue[0];
//Copy the array to the new array.
System.Array.Copy(queue, 1, queue, 0, queue.Length - 1);
//Set the last shifted value to the previously first value.
queue[queue.Length - 1] = prev;
Implementation with Extension methods passing shifting direction as Enum.
"for" statements and indexers only (don't use Array.Copy method).
using System;
namespace ShiftArrayElements
{
public static class EnumShifter
{
public static int[] Shift(int[] source, Direction[] directions)
{
for (var i = 0; i < directions.Length; i++)
{
var direction = directions[i];
if (direction == Direction.Left)
{
source.LeftShift();
}
else if (direction == Direction.Right)
{
source.RightShift();
}
else
{
throw new InvalidOperationException("Direction is invalid");
}
}
return source;
}
public static void LeftShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[0];
for (int j = 0; j + 1 < source.Length; j++)
{
source[j] = source[j + 1];
}
source[lastIndex] = temp;
}
public static void RightShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[lastIndex];
for (int j = lastIndex; j > 0; j--)
{
source[j] = source[j - 1];
}
source[0] = temp;
}
}
}
Array copying is an O(n) operation and creates a new array.
While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:
using System;
using System.Text;
public class ArrayReindexer
{
private Array reindexed;
private int location, offset;
public ArrayReindexer( Array source )
{
reindexed = source;
}
public object this[int index]
{
get
{
if (offset > 0 && index >= location)
{
int adjustedIndex = index + offset;
return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
}
return reindexed.GetValue( index );
}
}
public void Reindex( int position, int shiftAmount )
{
location = position;
offset = shiftAmount;
}
public override string ToString()
{
StringBuilder output = new StringBuilder( "[ " );
for (int i = 0; i < reindexed.Length; ++i)
{
output.Append( this[i] );
if (i == reindexed.Length - 1)
{
output.Append( " ]" );
}
else
{
output.Append( ", " );
}
}
return output.ToString();
}
}
By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...
ArrayReindexer original = new ArrayReindexer( SourceArray );
Console.WriteLine( " Base array: {0}", original.ToString() );
ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
reindexed.Reindex( 1, 1 );
Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
Will produce the output:
Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
Shifted array: [ 0, 2, 3, 4, 5, 6, null ]
I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )
It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.
Hope this helps!
Incorrect and slightly amusing answer (thanks, i'll be here all night !)
int?[] test = new int?[] {0,1,2,3,4,5,6 };
int?[] t = new int?[test.Length];
t = test.Skip(1).ToArray();
t[t.Length - 1] = null;
In the spirit of still using Skip (dont ask me, i know worst usage of LINQ extension methods ever), the only way I thought of rewriting it would be
int?[] test = new int?[] { 0, 1, 2, 3, 4, 5, 6 };
int?[] t = new int?[test.Length];
Array.Copy(test.Skip(1).ToArray(), t, t.Length - 1);
But it's in NO WAY faster than the other options.
I know this is an old question but coming from Google there was no simple example so thanks to this is the easiest way to reorder a list, and you don't have to supply the type it will work it out at runtime,
private static List<T> reorderList<T>(List<T> list){
List<T> newList = new List<T>();
list.ForEach(delegate(T item)
{
newList.Add(item);
});
return newList;
}
using System;
using System.Threading;
namespace ShiftMatrix
{
class Program
{
static void Main(string[] args)
{
MatrixOperation objMatrixOperation = new MatrixOperation();
//Create a matrix
int[,] mat = new int[,]
{
{1, 2},
{3,4 },
{5, 6},
{7,8},
{8,9},
};
int type = 2;
int counter = 0;
if (type == 1)
{
counter = mat.GetLength(0);
}
else
{
counter = mat.GetLength(1);
}
while (true)
{
for (int i = 0; i < counter; i++)
{
ShowMatrix(objMatrixOperation.ShiftMatrix(mat, i, type));
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
public static void ShowMatrix(int[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
for (int k = 0; k < rows; k++)
{
for (int l = 0; l < columns; l++)
{
Console.Write(matrix[k, l] + " ");
}
Console.WriteLine();
}
}
}
class MatrixOperation
{
public int[,] ShiftMatrix(int[,] origanalMatrix, int shift, int type)
{
int rows = origanalMatrix.GetLength(0);
int cols = origanalMatrix.GetLength(1);
int[,] _tmpMatrix = new int[rows, cols];
if (type == 2)
{
for (int x1 = 0; x1 < rows; x1++)
{
int y2 = 0;
for (int y1 = shift; y2 < cols - shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
y2--;
for (int y1 = 0; y1 < shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
}
}
else
{
int x2 = 0;
for (int x1 = shift; x2 < rows - shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
x2--;
for (int x1 = 0; x1 < shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
}
return _tmpMatrix;
}
}
}
See C# code below to remove space from string. That shift character in array. Performance is O(n). No other array is used. So no extra memory either.
static void Main(string[] args)
{
string strIn = System.Console.ReadLine();
char[] chraryIn = strIn.ToCharArray();
int iShift = 0;
char chrTemp;
for (int i = 0; i < chraryIn.Length; ++i)
{
if (i > 0)
{
chrTemp = chraryIn[i];
chraryIn[i - iShift] = chrTemp;
chraryIn[i] = chraryIn[i - iShift];
}
if (chraryIn[i] == ' ') iShift++;
if (i >= chraryIn.Length - 1 - iShift) chraryIn[i] = ' ';
}
System.Console.WriteLine(new string(chraryIn));
System.Console.Read();
}
a is array of ints & d is number of times array has to shift left.
static int[] rotLeft(int[] a, int d)
{
var innerLoop = a.Length - 1;
for(var loop=0; loop < d; loop++)
{
var res = a[innerLoop];
for (var i= innerLoop; i>=0; i--)
{
var tempI = i-1;
if (tempI < 0)
{
tempI = innerLoop;
}
var yolo = a[tempI];
a[tempI] = res;
res = yolo;
}
}
return a;
}
Simple way to do it when you need to resize the same array.
var nLength = args.Length - 1;
Array.Copy(args, 1, args, 0, nLength);
Array.Resize(ref args, nLength);

SubArray of a 2d array with non-zero lower bounds

The extension :
public static T[,] SubArray<T>(this T[,] values, int row_min, int row_max, int col_min, int col_max)
{
int num_rows = row_max - row_min + 1;
int num_cols = col_max - col_min + 1;
T[,] result = new T[num_rows, num_cols];
int total_cols = values.GetUpperBound(1) + 1;
int from_index = row_min * total_cols + col_min;
int to_index = 0;
for (int row = 0; row <= num_rows - 1; row++)
{
Array.Copy(values, from_index, result, to_index, num_cols);
from_index += total_cols;
to_index += num_cols;
}
return result;
}
work well for 2D arrays arrays whose GetLowerBound(0) and GetLowerBound(1) are equal to zero. For instance if
int[,] arr1 = new int[5, 4];
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 4; ++j)
{
arr1[i, j] = i + j;
}
}
var arr1sub = arr1.SubArray(2, 3, 1, 3);
Then arr1sub is the 2d array with 2 rows and 3 colums (boths with indexes starting at 0)
3 4 5
5 6 7
Now if I look at the case where the initial array as indexes not starting at zero :
int[,] arr2 = (int[,])Array.CreateInstance(typeof(int), new int[] { 5, 4 }, new int[] { 3, 1 });
for (int i = arr2.GetLowerBound(0); i <= arr2.GetUpperBound(0); ++i)
{
for (int j = arr2.GetLowerBound(1); j <= arr2.GetUpperBound(1); ++j)
{
arr2[i, j] = i - arr2.GetLowerBound(0) + j - arr2.GetLowerBound(1);
}
}
var arr2sub = arr2.SubArray(5, 6, 2, 4);
the last line of previous code snippet will trigger an exception in the SubArray extension function at the line
Array.Copy(values, from_index, result, to_index, num_cols);
for row equal to zero.
I understand of the 2d array arr1 (with zero based indexes) is layed out in memory but not how the 2d array arr2 (with non-zero-based indexes) is layed out in memory, hence my use of Array.Copy must be wrong in this case, but I don't see why.
You are not calculating total_cols and from_index correctly.
public static T[,] SubArray<T>(this T[,] values, int row_min, int row_max, int col_min, int col_max)
{
int num_rows = row_max - row_min + 1;
int num_cols = col_max - col_min + 1;
T[,] result = new T[num_rows, num_cols];
int total_cols = values.GetLength(1);
int from_index = (row_min - values.GetLowerBound(0)) * total_cols + (col_min - values.GetLowerBound(1)) + values.GetLowerBound(0);
int to_index = 0;
for (int row = 0; row <= num_rows - 1; row++)
{
Array.Copy(values, from_index, result, to_index, num_cols);
from_index += total_cols;
to_index += num_cols;
}
return result;
}
total_cols is the obvious one; as for from_index, I cannot find any documentation on that, but it would appear that sourceIndex in Array.Copy starts counting from sourceArray.GetLowerBound(0) and not from zero, which is not necessarily immediately obvious given that this index keeps growing across rows and columns.

How to Convert int[] to int[,] - C#

I have an int array in one dimension:
var intArray=new[] { 1, 2, 3, 4, 5, 6 };
and I want to convert it to two dimensions, such as:
var intArray2D=new[,] { {1, 2}, {3, 4}, {5, 6} };
How do I achieve this with C#?
with a loop perhaps:
for (int i = 0; i < oldArr.Length; i=i+2)
{
newArr[i/2, 0] = oldArr[i];
newArr[i/2, 1] = oldArr[i + 1];
}
Untested, but should get you pointed in the right direction...
If the one dimensional array contains the primitive data in row major order, and the total capacity of the 2 dimensional array equals the length of the one dimensional array, you can use this.
int[] source = new int[6];
int[,] target = new int[3, 2];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(int));
Note that unlike Array.Copy and other array/list methods, Buffer.BlockCopy operates on a number of bytes of data, even if each element of the array is larger than 1 byte. It also only operates on arrays of primitive data types.
Additional references:
Multi-dimensional arrays are stored in row-major order (ECMA-335 Partition I, ยง8.9.1)
Buffer.BlockCopy
Edit: Here is a complete unit test.
[TestMethod]
public void SOTest16203210()
{
int[] source = new int[6] { 1, 2, 3, 4, 5, 6 };
int[,] destination = new int[3, 2];
Buffer.BlockCopy(source, 0, destination, 0, source.Length * sizeof(int));
Assert.AreEqual(destination[0, 0], 1);
Assert.AreEqual(destination[0, 1], 2);
Assert.AreEqual(destination[1, 0], 3);
Assert.AreEqual(destination[1, 1], 4);
Assert.AreEqual(destination[2, 0], 5);
Assert.AreEqual(destination[2, 1], 6);
}
I believe you want to split an integer array into an array of two integers each:
int[] list = new int[] { 1, 2, 3, 4, 5, 6};
int[][] newlist = new int[list.Length / 2][];
for (int i = 0, n = 0; i < list.Length; i += 2, n++)
{
newlist[n] = new[] { list[i], list[i + 1] };
}
To assign it to Points in particular you could try:
List<Point> plist = new List<Point>();
for (int i = 0; i < list.Length; i += 2)
{
plist.Add(new Point(list[i], list[i + 1]));
}
you may use this code. in here you can send any length you like. you can "deivde" the arry[] to arry[,] for any lenth.2 or 3 or what ever you like! as long as size % a.length ==0 !!!!
code
static int[,] convert(int[] a, int size)
{
int[,] value = new int[a.Length / size, size];
int counter = 0;
//
for (int b = 0; b < value.GetLength(0); b++)
for (int c = 0; c < value.GetLength(1); c++)
{
value[b, c] = a[counter];
counter++;
}
return value;
}
If the product of the dimensions are the same, the fastest way would probably be to pin the matrix using a fixed statement, then to use the Marshalling class to copy the continuous block from the array to an IntPtr created from the void* you got from the fixed.
You would have to wrap this in an unsafe statement and enable unsafe in the assembly's build config.
I have converted this from vb to c#
int Size = OldArray.Length;
int[,] NewPoints = null;
if (Size % 2 != 0) {
//Error - Array has odd number of elements!
} else {
for (i = 0; i <= Size - 1; i += 2) {
Array.Resize(ref AllPoints, (i / 2) + 1, 2);
NewPoints[i / 2, 0] = OldArray(i);
NewPoints[i / 2, 1] = OldArray(i + 1);
}
}
You could try this:
int [] a = {1,2,3,4,5,6};
int [,] b = new int[a.Length/2,2];
for(int i = 0;i<a.Length;i++)
{
b[i/2,i%2] = a[i];
}
Note that i/2 is an integer division, hence both 4/2 and 5/2 will give 2 which is a correct index in 2Darray for the tuple 5 and 6 from the original array. The second index is determined using reminder when divided by 2, it will give 0 if the index is even number and 1 if the index of the item from the original array is odd number.
I would consider this for any dimension of array:
public class TestClass {
public static void TestMethod2D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer2D=new ArrayIndexer<int>(3, 2);
for(var i=intLinear.Length; i-->0; indexer2D[i]=intLinear[i])
;
var int2D=(int[,])indexer2D.ToArray();
}
public static void TestMethod4D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer4D=new ArrayIndexer<int>(2, 2, 2, 2);
for(var i=intLinear.Length; i-->0; indexer4D[i]=intLinear[i])
;
var int4D=(int[, , ,])indexer4D.ToArray();
}
}
public partial class ArrayIndexer<T> {
public Array ToArray() {
return m_Array;
}
public ArrayIndexer(params int[] lengths) {
m_Array=Array.CreateInstance(typeof(T), lengths);
}
public T this[params int[] indices] {
set {
m_Array.SetValue(value, indices.Transform(m_Array));
}
get {
return (T)m_Array.GetValue(indices.Transform(m_Array));
}
}
Array m_Array;
}
public static partial class ArrayExtensions {
public static int[] Transform(
this int[] indices, Array array, bool isRowMajor=true) {
if(indices.Length>array.Rank)
return indices;
else {
var list=indices.ToList();
if(isRowMajor)
list.Reverse();
for(int r, q=0, i=0, count=array.Rank; count-->0; ++i) {
var index=isRowMajor?count-i:i;
if(indices.Length>i) {
q=Math.DivRem(indices[i]+q, array.GetLength(index), out r);
list[i]=r;
}
else {
if(index<0) {
list.Add(q);
q=0;
}
else {
q=Math.DivRem(q, array.GetLength(index), out r);
list.Add(r);
}
}
}
if(isRowMajor)
list.Reverse();
return list.ToArray();
}
}
}
ArrayExtensions.Transform is an indices transformer, it performs the linear transformation with the geometry of a given array. isRowMajor controls the layout, such as you would regard an int[,] in x, y or in y, x order.

n-dimensional Array

I want to create an n-dimensional array of doubles. At compile-time, the number of dimensions n is not known.
I ended up defining the array as a dictionary, with the key being an array of ints corresponding to the different axes (so in a 3-dimensional array, I'd supply [5, 2, 3] to get the double at (5, 2, 3) in the array.
However, I also need to populate the dictionary with doubles from (0, 0, ... 0) to (m1, m2, ... mn), where m1 to mn is the length of each axis.
My initial idea was to create nested for-loops, but as I still don't know how many I'd need (1 for each dimension), I can't do this at compile-time.
I hope I've formulated the question in an understandable manner, but feel free to ask me to elaborate parts.
To create a n-dimensional array, you can use the Array.CreateInstance method:
Array array = Array.CreateInstance(typeof(double), 5, 3, 2, 8, 7, 32));
array.SetValue(0.5d, 0, 0, 0, 0, 0, 0);
double val1 = (double)array.GetValue(0, 0, 0, 0, 0, 0);
array.SetValue(1.5d, 1, 2, 1, 6, 0, 30);
double val2 = (double)array.GetValue(1, 2, 1, 6, 0, 30);
To populate the arrays, you can use the Rank property and GetLength method to return the length of the current dimension, using a couple of nested for loops to do a O(n^m) algo (warning - untested):
private bool Increment(Array array, int[] idxs, int dim) {
if (dim >= array.Rank) return false;
if (++idxs[idxs.Length-dim-1] == array.GetLength(dim)) {
idxs[idxs.Length-dim-1] = 0;
return Increment(array, idxs, dim+1);
}
return true;
}
Array array = Array.CreateInstance(typeof(double), ...);
int[] idxs = new int[array.Rank];
while (Increment(array, idxs, 0)) {
array.SetValue(1d, idxs);
}
A quick followup on this matter:
We used the Array.CreateInstance method with success, but as someone predicted, it was fairly inefficient, and additionally created readability problems.
Instead, we have developed a method, where the n-dimensional array is converted into a 1-dimensional (normal) array.
public static int NDToOneD(int[] indices, int[] lengths)
{
int ID = 0;
for (int i = 0; i < indices.Length; i++)
{
int offset = 1;
for (int j = 0; j < i; j++)
{
offset *= lengths[j];
}
ID += indices[i] * offset;
}
return ID;
}
1DtoND(int[] indices, int[] arrayLengths)
{
int[] indices = new int[lengths.Length];
for (int i = lengths.Length - 1; i >= 0; i--)
{
int offset = 1;
for (int j = 0; j < i; j++)
{
offset *= lengths[j];
}
int remainder = ID % offset;
indices[i] = (ID - remainder) / offset;
ID = remainder;
}
return indices;
}
This is essentially a generalisation on the conversion of cartesian coordinates to a single integer and back again.
Our testing is not formalized, so any speedup we have gained is entirely anecdotal, but for my machine, it has given about a 30-50% speedup, depending on the sample size, and the readability of the code has improved by a wide margin.
Hope this helps anyone who stumbles upon this question.
Why don't you just use a multidimensional array: double[,,] array = new double[a,b,c]? All the array elements are automatically initialized to 0.0 for you.
Alternatively, you could use a jagged array double[][][], but each sub-array will need to be initialized in a for loop:
int a, b, c;
double[][][] array = new double[a][][];
for (int i=0; i<a; i++) {
double[i] = new double[b][];
for (int j=0; j<b; j++) {
double[i][j] = new double[c];
}
}
EDIT: didn't realise number of dimensions was run-time. Added another answer above.
With this method, you can create n-dimensional jagged arrays of any type.
public static Array CreateJaggedArray<T>(params int[] lengths)
{
if(lengths.Length < 1)
throw new ArgumentOutOfRangeException(nameof(lengths));
void Populate(Array array, int index)
{
for (int i = 0; i < array.Length; i++)
{
Array element = (Array)Activator.CreateInstance(array.GetType().GetElementType(), lengths[index]);
array.SetValue(element, i);
if (index + 1 < lengths.Length)
Populate(element, index + 1);
}
}
Type retType = typeof(T);
for (var i = 0; i < lengths.Length; i++)
retType = retType.MakeArrayType();
Array ret = (Array)Activator.CreateInstance(retType, lengths[0]);
if (lengths.Length > 1)
Populate(ret, 1);
return ret;
}

C# quickest way to shift array

How can I quickly shift all the items in an array one to the left, padding the end with null?
For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
Edit: I said quickly but I guess I meant efficiently. I need to do this without creating a List or some other data structure. This is something I need to do several hundred thousand times in as short amount of time as possible.
Here's my test harness...
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
var destination = new int?[source.Length];
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000;i++)
{
Array.Copy(source, 1, destination, 0, source.Length - 1);
}
s.Stop();
Console.WriteLine(s.Elapsed);
Here are the performance results for 1 million iterations of each solution (8 Core Intel Xeon E5450 # 3.00GHz)
100 elements 10000 elements
For Loop 0.390s 31.839s
Array.Copy() 0.177s 12.496s
Aaron 1 3.789s 84.082s
Array.ConstrainedCopy() 0.197s 17.658s
Make the choice for yourself :)
The quickest way to do this is to use Array.Copy, which in the final implementation uses a bulk memory transfer operation (similar to memcpy):
var oldArray = new int?[] { 1, 2, 3, 4, 5, 6 };
var newArray = new int?[oldArray.Length];
Array.Copy(oldArray, 1, newArray, 0, oldArray.Length - 1);
// newArray is now { 2, 3, 4, 5, 6, null }
Edited: according to the documentation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
So if you don't want to allocate a new array, you can pass in the original array for both source and destination--although I imagine the tradeoff will be a somewhat slower performance since the values go through a temporary holding position.
I suppose, as in any investigation of this kind, you should do some quick benchmarking.
Here is my solution, similar to Task's in that it is a simple Array wrapper and that it takes O(1) time to shift the array to the left.
public class ShiftyArray<T>
{
private readonly T[] array;
private int front;
public ShiftyArray(T[] array)
{
this.array = array;
front = 0;
}
public void ShiftLeft()
{
array[front++] = default(T);
if(front > array.Length - 1)
{
front = 0;
}
}
public void ShiftLeft(int count)
{
for(int i = 0; i < count; i++)
{
ShiftLeft();
}
}
public T this[int index]
{
get
{
if(index > array.Length - 1)
{
throw new IndexOutOfRangeException();
}
return array[(front + index) % array.Length];
}
}
public int Length { get { return array.Length; } }
}
Running it through Jason Punyon's test code...
int?[] intData = Enumerable.Range(1, 100).Cast<int?>().ToArray();
ShiftyArray<int?> array = new ShiftyArray<int?>(intData);
Stopwatch watch = new Stopwatch();
watch.Start();
for(int i = 0; i < 1000000; i++)
{
array.ShiftLeft();
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Takes ~29ms, regardless of the array size.
Use the Array.Copy() method as in
int?[] myArray = new int?[]{0,1,2,3,4};
Array.Copy(myArray, 1, myArray, 0, myArray.Length - 1);
myArray[myArray.Length - 1] = null
The Array.Copy is probably the way, Microsoft wanted us to copy array elements...
Couldn't you use a System.Collections.Generic.Queue instead of an array ?
I feel like you need to perform actions on your value the discard it, thus using a queue seems to be more appropriate :
// dummy initialization
System.Collections.Generic.Queue<int> queue = new Queue<int>();
for (int i = 0; i < 7; ++i ) { queue.Enqueue(i); }// add each element at the end of the container
// working thread
if (queue.Count > 0)
doSomething(queue.Dequeue());// removes the last element of the container and calls doSomething on it
For any pour soul finding this thread and about to implement one of the highly rated answers. All of them are trash, I'm not sure why that is. Maybe Dested asked for a new array implementation at first or something that has now been removed from the question. Well if you simply want to shift the array and don't need a new one, see an answer like tdaines's answer. And read up on things like the Circular Buffer / Ring Buffer : http://en.wikipedia.org/wiki/Circular_buffer. No moving of the actual data is necessary. The performance of shifting an array should not be tied to the size of the array.
If it absolutely has to be in an array, then I would recommend the most obvious code possible.
for (int index = startIndex; index + 1 < values.Length; index++)
values[index] = values[index + 1];
values[values.Length - 1] = null;
This gives the optimizer the most opportunities to find the best way on whatever target platform the program is installed on.
EDIT:
I just borrowed Jason Punyon's test code, and I'm afraid he's right. Array.Copy wins!
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
int indexToRemove = 4;
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000; i++)
{
Array.Copy(source, indexToRemove + 1, source, indexToRemove, source.Length - indexToRemove - 1);
//for (int index = indexToRemove; index + 1 < source.Length; index++)
// source[index] = source[index + 1];
}
s.Stop();
Console.WriteLine(s.Elapsed);
Array.Copy takes between 103 and 150 ms on my machine.
for loop takes between 269 and 338 ms on my machine.
Can't you
allocate the array with an extra 1000 elements
have an integer variable int base = 0
instead of accessing a[i] access a[base+i]
to do your shift, just say base++
Then after you've done this 1000 times, copy it down and start over.
That way, you only do the copy once per 1000 shifts.
Old joke:
Q: How many IBM 360s does it take to shift a register by 1 bit?
A: 33. 32 to hold the bits in place, and 1 to move the register. (or some such...)
You can use the same array as source and destination for fast in-place copy:
static void Main(string[] args)
{
int[] array = {0, 1, 2, 3, 4, 5, 6, 7};
Array.ConstrainedCopy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = 0;
}
You might do it like this:
var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 }; // Your array
var itemList = new List<int?>(items); // Put the items in a List<>
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
items = itemList.ToArray(); // Turn the list back into an array
Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:
var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
The best and most efficient method I believe is using Buffer.BlockCopy function.
You will set both source and destination to your array, the offset of the source is 1. Depending on your array type (I assume it is int), 1 int = 4 bytes, so you must pass in 4 as the second parameter of this function. Note that the offset is byte offset.
So it looks like this:
int bytes2copy = yourArray.length - 4;
Buffer.BlockCopy(yourArray, 4, yourArray, 0, bytes2copy);
yourArray[yourArray.length-1] = null;
Try this! using Linq. No need of second Array.
var i_array = new int?[] {0, 1, 2, 3, 4, 5, 6 };
i_array = i_array.Select((v, k) => new { v = v, k = k }).
Where(i => i.k > 0).Select(i => i.v).ToArray();
Array.Resize(ref i_array, i_array.Length + 1);
Output:
[0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
If you own the memory you could consider using Unsafe Code and good old fashioned pointers.
Make yourself a memory stream and lock it down or use Marshal.AllocHGlobal
Construct all your arrays in it with a little bit of padding at the beginning and end.
increment or decrement all of the array pointers at once. You'll still need to loop back and set your nulls.
If you need to selectively increment or decrement the arrays you would have to add padding between them.
Arrays are incredibly low level data structures, if you treat them in a low level way you can get huge performance out of them.
A baytrail doing this could outperform Jason's with all its copying 8 Core Intel Xeon E5450 # 3.00GHz
Not tested this code, but it should shifts all the values to right by one. Note that the last three lines of code is all you require to efficiently shift the array.
public class Shift : MonoBehaviour {
//Initialize Array
public int[] queue;
void Start () {
//Create Array Rows
queue = new int[5];
//Set Values to 1,2,3,4,5
for (int i=0; i<5;i++)
{
queue[i] = i + 1;
}
//Get the integer at the first index
int prev = queue[0];
//Copy the array to the new array.
System.Array.Copy(queue, 1, queue, 0, queue.Length - 1);
//Set the last shifted value to the previously first value.
queue[queue.Length - 1] = prev;
Implementation with Extension methods passing shifting direction as Enum.
"for" statements and indexers only (don't use Array.Copy method).
using System;
namespace ShiftArrayElements
{
public static class EnumShifter
{
public static int[] Shift(int[] source, Direction[] directions)
{
for (var i = 0; i < directions.Length; i++)
{
var direction = directions[i];
if (direction == Direction.Left)
{
source.LeftShift();
}
else if (direction == Direction.Right)
{
source.RightShift();
}
else
{
throw new InvalidOperationException("Direction is invalid");
}
}
return source;
}
public static void LeftShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[0];
for (int j = 0; j + 1 < source.Length; j++)
{
source[j] = source[j + 1];
}
source[lastIndex] = temp;
}
public static void RightShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[lastIndex];
for (int j = lastIndex; j > 0; j--)
{
source[j] = source[j - 1];
}
source[0] = temp;
}
}
}
Array copying is an O(n) operation and creates a new array.
While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:
using System;
using System.Text;
public class ArrayReindexer
{
private Array reindexed;
private int location, offset;
public ArrayReindexer( Array source )
{
reindexed = source;
}
public object this[int index]
{
get
{
if (offset > 0 && index >= location)
{
int adjustedIndex = index + offset;
return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
}
return reindexed.GetValue( index );
}
}
public void Reindex( int position, int shiftAmount )
{
location = position;
offset = shiftAmount;
}
public override string ToString()
{
StringBuilder output = new StringBuilder( "[ " );
for (int i = 0; i < reindexed.Length; ++i)
{
output.Append( this[i] );
if (i == reindexed.Length - 1)
{
output.Append( " ]" );
}
else
{
output.Append( ", " );
}
}
return output.ToString();
}
}
By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...
ArrayReindexer original = new ArrayReindexer( SourceArray );
Console.WriteLine( " Base array: {0}", original.ToString() );
ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
reindexed.Reindex( 1, 1 );
Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
Will produce the output:
Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
Shifted array: [ 0, 2, 3, 4, 5, 6, null ]
I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )
It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.
Hope this helps!
Incorrect and slightly amusing answer (thanks, i'll be here all night !)
int?[] test = new int?[] {0,1,2,3,4,5,6 };
int?[] t = new int?[test.Length];
t = test.Skip(1).ToArray();
t[t.Length - 1] = null;
In the spirit of still using Skip (dont ask me, i know worst usage of LINQ extension methods ever), the only way I thought of rewriting it would be
int?[] test = new int?[] { 0, 1, 2, 3, 4, 5, 6 };
int?[] t = new int?[test.Length];
Array.Copy(test.Skip(1).ToArray(), t, t.Length - 1);
But it's in NO WAY faster than the other options.
I know this is an old question but coming from Google there was no simple example so thanks to this is the easiest way to reorder a list, and you don't have to supply the type it will work it out at runtime,
private static List<T> reorderList<T>(List<T> list){
List<T> newList = new List<T>();
list.ForEach(delegate(T item)
{
newList.Add(item);
});
return newList;
}
using System;
using System.Threading;
namespace ShiftMatrix
{
class Program
{
static void Main(string[] args)
{
MatrixOperation objMatrixOperation = new MatrixOperation();
//Create a matrix
int[,] mat = new int[,]
{
{1, 2},
{3,4 },
{5, 6},
{7,8},
{8,9},
};
int type = 2;
int counter = 0;
if (type == 1)
{
counter = mat.GetLength(0);
}
else
{
counter = mat.GetLength(1);
}
while (true)
{
for (int i = 0; i < counter; i++)
{
ShowMatrix(objMatrixOperation.ShiftMatrix(mat, i, type));
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
public static void ShowMatrix(int[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
for (int k = 0; k < rows; k++)
{
for (int l = 0; l < columns; l++)
{
Console.Write(matrix[k, l] + " ");
}
Console.WriteLine();
}
}
}
class MatrixOperation
{
public int[,] ShiftMatrix(int[,] origanalMatrix, int shift, int type)
{
int rows = origanalMatrix.GetLength(0);
int cols = origanalMatrix.GetLength(1);
int[,] _tmpMatrix = new int[rows, cols];
if (type == 2)
{
for (int x1 = 0; x1 < rows; x1++)
{
int y2 = 0;
for (int y1 = shift; y2 < cols - shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
y2--;
for (int y1 = 0; y1 < shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
}
}
else
{
int x2 = 0;
for (int x1 = shift; x2 < rows - shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
x2--;
for (int x1 = 0; x1 < shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
}
return _tmpMatrix;
}
}
}
See C# code below to remove space from string. That shift character in array. Performance is O(n). No other array is used. So no extra memory either.
static void Main(string[] args)
{
string strIn = System.Console.ReadLine();
char[] chraryIn = strIn.ToCharArray();
int iShift = 0;
char chrTemp;
for (int i = 0; i < chraryIn.Length; ++i)
{
if (i > 0)
{
chrTemp = chraryIn[i];
chraryIn[i - iShift] = chrTemp;
chraryIn[i] = chraryIn[i - iShift];
}
if (chraryIn[i] == ' ') iShift++;
if (i >= chraryIn.Length - 1 - iShift) chraryIn[i] = ' ';
}
System.Console.WriteLine(new string(chraryIn));
System.Console.Read();
}
a is array of ints & d is number of times array has to shift left.
static int[] rotLeft(int[] a, int d)
{
var innerLoop = a.Length - 1;
for(var loop=0; loop < d; loop++)
{
var res = a[innerLoop];
for (var i= innerLoop; i>=0; i--)
{
var tempI = i-1;
if (tempI < 0)
{
tempI = innerLoop;
}
var yolo = a[tempI];
a[tempI] = res;
res = yolo;
}
}
return a;
}
Simple way to do it when you need to resize the same array.
var nLength = args.Length - 1;
Array.Copy(args, 1, args, 0, nLength);
Array.Resize(ref args, nLength);

Categories