Sorting a list manually - c#

So basically the user is able to fill a number, that number gets added to a list and once the user pressed a button the list should be sorted without using the .Sort(); function
public int[] nummers;
public ObservableCollection<int> alleNummers = new ObservableCollection<int>();
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
alleNummers.Add(int.Parse(nummerBox.Text));
listBox.ItemsSource = alleNummers;
}
private void sortBtn_Click(object sender, RoutedEventArgs e)
{
foreach (int i in alleNummers)
{
//Sort the int's from small to big
}
nummers = alleNummers.ToArray();
listBox.ItemsSource = nummers;
}
I think, I need to make use of a foreach loop but wouldn't know what to type.
This is a small homework assignment btw.

Here are some algorithms that you can follow to sort your list programmatically Sorting Algorithms with Code and great explanation
Bubble Sort
public static void IntArrayBubbleSort (int[] data)
{
int i, j;
int N = data.Length;
for (j=N-1; j>0; j--) {
for (i=0; i<j; i++) {
if (data [i] > data [i + 1])
exchange (data, i, i + 1);
}
}
}
Selection Sort
public static int IntArrayMin (int[] data, int start)
{
int minPos = start;
for (int pos=start+1; pos < data.Length; pos++)
if (data [pos] < data [minPos])
minPos = pos;
return minPos;
}
public static void IntArraySelectionSort (int[] data)
{
int i;
int N = data.Length;
for (i=0; i < N-1; i++) {
int k = IntArrayMin (data, i);
if (i != k)
exchange (data, i, k);
}
}
Insertion Sort
public static void IntArrayInsertionSort (int[] data)
{
int i, j;
int N = data.Length;
for (j=1; j<N; j++) {
for (i=j; i>0 && data[i] < data[i-1]; i--) {
exchange (data, i, i - 1);
}
}
}
Shell Sort
static int[] GenerateIntervals (int n)
{
if (n < 2) { // no sorting will be needed
return new int[0];
}
int t = Math.Max (1, (int)Math.Log (n, 3) - 1);
int[] intervals = new int[t];
intervals [0] = 1;
for (int i=1; i < t; i++)
intervals [i] = 3 * intervals [i - 1] + 1;
return intervals;
}
public static void IntArrayShellSortBetter (int[] data)
{
int[] intervals = GenerateIntervals (data.Length);
IntArrayShellSort (data, intervals);
}
Quicksort a.k.a. Partition Sort
public static void IntArrayQuickSort (int[] data, int l, int r)
{
int i, j;
int x;
i = l;
j = r;
x = data [(l + r) / 2]; /* find pivot item */
while (true) {
while (data[i] < x)
i++;
while (x < data[j])
j--;
if (i <= j) {
exchange (data, i, j);
i++;
j--;
}
if (i > j)
break;
}
if (l < j)
IntArrayQuickSort (data, l, j);
if (i < r)
IntArrayQuickSort (data, i, r);
}
public static void IntArrayQuickSort (int[] data)
{
IntArrayQuickSort (data, 0, data.Length - 1);
}
Random Data Generation
public static void IntArrayGenerate (int[] data, int randomSeed)
{
Random r = new Random (randomSeed);
for (int i=0; i < data.Length; i++)
data [i] = r.Next ();
}

I would like to offer up this guide as a solution to your question
Sorting algorithms represent foundational knowledge that every
computer scientist and IT professional should at least know at a basic
level. And it turns out to be a great way of learning about why arrays
are important well beyond mathematics.
In this section, we’re going to take a look at a number of well-known
sorting algorithms with the hope of sensitizing you to the notion of
performance–a topic that is covered in greater detail in courses such
as algorithms and data structures
Introduction to Computer Science in C# 10.4. Sorting Algorithms
it contains many examples, including Bubble Sort:
public static void IntArrayBubbleSort (int[] data)
{
int i, j;
int N = data.Length;
for (j=N-1; j>0; j--) {
for (i=0; i<j; i++) {
if (data [i] > data [i + 1])
exchange (data, i, i + 1);
}
}
}

here is a implementation of the BubbleSort algorithm. This is one of the slowest but also one of the "easy to understand" sorting algorithms.
for (int i = (alleNummers.Count - 1); i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
if (alleNummers[j - 1] > alleNummers[j])
{
var temp = alleNummers[j - 1];
alleNummers[j - 1] = alleNummers[j];
alleNummers[j] = temp;
}
}
}
if you want to use another one, i mentioned some in one of my recent answers:
I want an efficient sorting algorithm to sort an array

Try this! this approach will short the list by ascending order.
List<int> lst = new List<int>() { 2, 3, 1, 0, 5 };
int j=0;
while (j < lst.Count)
{
for (int i = lst.Count - 1; i >= 0; i--)
{
if ((i - 1) >= 0 && lst[i] < lst[i - 1])
{
int temp = lst[i];
lst[i] = lst[i - 1];
lst[i - 1] = temp;
}
}
j++;
}

Related

Getting Time limit Exceed for last 3 Test Cases in a Program:C# [duplicate]

Given an array of n integers and a number, d, perform left rotations on the array. Then print the updated array as a single line of space-separated integers.
Sample Input:
5 4
1 2 3 4 5
The first line contains two space-separated integers denoting the respective values of n (the number of integers) and d (the number of left rotations you must perform).
The second line contains n space-separated integers describing the respective elements of the array's initial state.
Sample Output:
5 1 2 3 4
static void Main(String[] args)
{
string[] arr_temp = Console.ReadLine().Split(' ');
int n = Int32.Parse(arr_temp[0]);
int d = Int32.Parse(arr_temp[1]);
string[] arr = Console.ReadLine().Split(' ');
string[] ans = new string[n];
for (int i = 0; i < n; ++i)
{
ans[(i + n - d) % n] = arr[i];
}
for (int j = 0; j < n; ++j)
{
Console.Write(ans[j] + " ");
}
}
How to use less memory to solve this problem?
This will use less memory in most cases as the second array is only as big as the shift.
public static void Main(string[] args)
{
int[] n = { 1, 2, 3, 4, 5 };
LeftShiftArray(n, 4);
Console.WriteLine(String.Join(",", n));
}
public static void LeftShiftArray<T>(T[] arr, int shift)
{
shift = shift % arr.Length;
T[] buffer = new T[shift];
Array.Copy(arr, buffer, shift);
Array.Copy(arr, shift, arr, 0, arr.Length - shift);
Array.Copy(buffer, 0, arr, arr.Length - shift, shift);
}
This problem can get a bit tricky but also has a simple solution if one is familiar with Queues and Stacks.
All I have to do is define a Queue (which will contain the given array) and a Stack.
Next, I just have to Push the Dequeued index to the stack and Enqueue the Popped index in the Queue and finally return the Queue.
Sounds confusing? Check the code below:
static int[] rotLeft(int[] a, int d) {
Queue<int> queue = new Queue<int>(a);
Stack<int> stack = new Stack<int>();
while(d > 0)
{
stack.Push(queue.Dequeue());
queue.Enqueue(stack.Pop());
d--;
}
return queue.ToArray();
}
Do you really need to physically move anything? If not, you could just shift the index instead.
Actually you asked 2 questions:
How to efficiently rotate an array?
and
How to use less memory to solve this problem?
Usually efficiency and low memory usage are mutually exclusive. So I'm going to answer your second question, still providing the most efficient implementation under that memory constraint.
The following method can be used for both left (passing negative count) or right (passing positive count) rotation. It uses O(1) space (single element) and O(n * min(d, n - d)) array element copy operations (O(min(d, n - d)) array block copy operations). In the worst case scenario it performs O(n / 2) block copy operations.
The algorithm is utilizing the fact that
rotate_left(n, d) == rotate_right(n, n - d)
Here it is:
public static class Algorithms
{
public static void Rotate<T>(this T[] array, int count)
{
if (array == null || array.Length < 2) return;
count %= array.Length;
if (count == 0) return;
int left = count < 0 ? -count : array.Length + count;
int right = count > 0 ? count : array.Length - count;
if (left <= right)
{
for (int i = 0; i < left; i++)
{
var temp = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = temp;
}
}
else
{
for (int i = 0; i < right; i++)
{
var temp = array[array.Length - 1];
Array.Copy(array, 0, array, 1, array.Length - 1);
array[0] = temp;
}
}
}
}
Sample usage like in your example:
var array = Enumerable.Range(1, 5).ToArray(); // { 1, 2, 3, 4, 5 }
array.Rotate(-4); // { 5, 1, 2, 3, 4 }
Isn't using IEnumerables better? Since It won't perform all of those maths, won't allocate that many arrays, etc
public static int[] Rotate(int[] elements, int numberOfRotations)
{
IEnumerable<int> newEnd = elements.Take(numberOfRotations);
IEnumerable<int> newBegin = elements.Skip(numberOfRotations);
return newBegin.Union(newEnd).ToArray();
}
IF you don't actually need to return an array, you can even remove the .ToArray() and return an IEnumerable
Usage:
void Main()
{
int[] n = { 1, 2, 3, 4, 5 };
int d = 4;
int[] rotated = Rotate(n,d);
Console.WriteLine(String.Join(" ", rotated));
}
I have also tried this and below is my approach...
Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
I have tried to used stack and queue in C# to achieve the output as follows:
public int[] rotateArray(int[] A, int rotate)
{
Queue<int> q = new Queue<int>(A);
Stack<int> s;
while (rotate > 0)
{
s = new Stack<int>(q);
int x = s.Pop();
s = new Stack<int>(s);
s.Push(x);
q = new Queue<int>(s);
rotate--;
}
return q.ToArray();
}
I've solve the challange from Hackerrank by following code. Hope it helps.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApp1
{
class ArrayLeftRotationSolver
{
TextWriter mTextWriter;
public ArrayLeftRotationSolver()
{
mTextWriter = new StreamWriter(#System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);
}
public void Solve()
{
string[] nd = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(nd[0]);
int d = Convert.ToInt32(nd[1]);
int[] a = Array.ConvertAll(Console.ReadLine().Split(' '), aTemp => Convert.ToInt32(aTemp))
;
int[] result = rotLeft(a, d);
mTextWriter.WriteLine(string.Join(" ", result));
mTextWriter.Flush();
mTextWriter.Close();
}
private int[] rotLeft(int[] arr, int shift)
{
int n = arr.Length;
shift %= n;
int[] vec = new int[n];
for (int i = 0; i < n; i++)
{
vec[(n + i - shift) % n] = arr[i];
}
return vec;
}
static void Main(string[] args)
{
ArrayLeftRotationSolver solver = new ArrayLeftRotationSolver();
solver.Solve();
}
}
}
Hope this helps.
public static int[] leftrotation(int[] arr, int d)
{
int[] newarr = new int[arr.Length];
var n = arr.Length;
bool isswapped = false;
for (int i = 0; i < n; i++)
{
int index = Math.Abs((i) -d);
if(index == 0)
{
isswapped = true;
}
if (!isswapped)
{
int finalindex = (n) - index;
newarr[finalindex] = arr[i];
}
else
{
newarr[index] = arr[i];
}
}
return newarr;
}
Take the Item at position 0 and add it at the end. remove the item at position 0. repeat n times.
List<int> iList = new List<int>();
private void shift(int n)
{
for (int i = 0; i < n; i++)
{
iList.Add(iList[0]);
iList.RemoveAt(0);
}
}
An old question, but I thought I'd add another possible solution using just one intermediate array (really, 2 if you include the LINQ Take expression). This code rotates to right rather than left, but may be useful nonetheless.
public static Int32[] ArrayRightRotation(Int32[] A, Int32 k)
{
if (A == null)
{
return A;
}
if (!A.Any())
{
return A;
}
if (k % A.Length == 0)
{
return A;
}
if (A.Length == 1)
{
return A;
}
if (A.Distinct().Count() == 1)
{
return A;
}
for (var i = 0; i < k; i++)
{
var intermediateArray = new List<Int32> {A.Last()};
intermediateArray.AddRange(A.Take(A.Length - 1).ToList());
A = intermediateArray.ToArray();
}
return A;
}
O(1) space, O(n) time solution
I think in theory this is as optimal as it gets, since it makes a.Length in-place swaps and 1 temp variable swap per inner loop.
However I suspect O(d) space solutions would be faster in real life due to less code branching (fewer CPU command pipeline resets) and cache locality (mostly sequential access vs in d element steps).
static int[] RotateInplaceLeft(int[] a, int d)
{
var swapCount = 0;
//get canonical/actual d
d = d % a.Length;
if(d < 0) d += a.Length;
if(d == 0) return a;
for (var i = 0; swapCount < a.Length; i++) //we're done after a.Length swaps
{
var dstIdx = i; //we need this becasue of ~this: https://youtu.be/lJ3CD9M3nEQ?t=251
var first = a[i]; //save first element in this group
for (var j = 0; j < a.Length; j++)
{
var srcIdx = (dstIdx + d) % a.Length;
if(srcIdx == i)// circled around
{
a[dstIdx] = first;
swapCount++;
break; //hence we're done with this group
}
a[dstIdx] = a[srcIdx];
dstIdx = srcIdx;
swapCount++;
}
}
return a;
}
If you take a look at constrains you will see that d <= n (number of rotations <= number of elements in array). Because of that this can be solved in 1 line.
static int[] rotLeft(int[] a, int d)
{
return a.Skip(d).Concat(a.Take(d)).ToArray();
}
// using the same same array, and only one temp variable
// shifting everything several times by one
// works, simple, but slow
public static int[] ArrayRotateLeftCyclical(int[] a, int shift)
{
var length = a.Length;
for (int j = 0; j < shift; j++)
{
int t = a[0];
for (int i = 0; i < length; i++)
{
if (i == length - 1)
a[i] = t;
else
a[i] = a[i + 1];
}
}
return a;
}
Let's say if I have a array of integer 'Arr'. To rotate the array 'n' you can do as follows:
static int[] leftRotation(int[] Arr, int n)
{
int tempVariable = 0;
Queue<int> TempQueue = new Queue<int>(a);
for(int i=1;i<=d;i++)
{
tempVariable = TempQueue.Dequeue();
TempQueue.Enqueue(t);
}
return TempQueue.ToArray();`
}
Let me know if any comments. Thanks!
This is my attempt. It is easy, but for some reason it timed out on big chunks of data:
int arrayLength = arr.Length;
int tmpCell = 0;
for (int rotation = 1; rotation <= d; rotation++)
{
for (int i = 0; i < arrayLength; i++)
{
if (arr[i] < arrayElementMinValue || arr[i] > arrayElementMaxValue)
{
throw new ArgumentException($"Array element needs to be between {arrayElementMinValue} and {arrayElementMaxValue}");
}
if (i == 0)
{
tmpCell = arr[0];
arr[0] = arr[1];
}
else if (i == arrayLength - 1)
{
arr[arrayLength - 1] = tmpCell;
}
else
{
arr[i] = arr[i + 1];
}
}
}
what about this?
public static void RotateArrayAndPrint(int[] n, int rotate)
{
for (int i = 1; i <= n.Length; i++)
{
var arrIndex = (i + rotate) > n.Length ? n.Length - (i + rotate) : (i + rotate);
arrIndex = arrIndex < 0 ? arrIndex * -1 : arrIndex;
var output = n[arrIndex-1];
Console.Write(output + " ");
}
}
It's very straight forward answer.
Main thing is how you choose the start index.
public static List<int> rotateLeft(int d, List<int> arr) {
int n = arr.Count;
List<int> t = new List<int>();
int h = d;
for (int j = 0; j < n; j++)
{
if ((j + d) % n == 0)
{
h = 0;
}
t.Add(arr[h]);
h++;
}
return t;
}
using this code, I have successfully submitted to hacker rank problem,
// fast and beautiful method
// reusing the same array
// using small temp array to store replaced values when unavoidable
// a - array, s - shift
public static int[] ArrayRotateLeftWithSmallTempArray(int[] a, int s)
{
var l = a.Length;
var t = new int[s]; // temp array with size s = shift
for (int i = 0; i < l; i++)
{
// save cells which will be replaced by shift
if (i < s)
t[i] = a[i];
if (i + s < l)
a[i] = a[i + s];
else
a[i] = t[i + s - l];
}
return a;
}
https://github.com/sam-klok/ArraysRotation
public static void Rotate(int[] arr, int steps)
{
for (int i = 0; i < steps; i++)
{
int previousValue = arr[arr.Length - 1];
for (int j = 0; j < arr.Length; j++)
{
int currentValue = arr[j];
arr[j] = previousValue;
previousValue = currentValue;
}
}
}
Here is an in-place Rotate implementation of a trick posted by גלעד ברקן in another question. The trick is:
Example, k = 3:
1234567
First reverse in place each of the two sections delineated by n-k:
4321 765
Now reverse the whole array:
5671234
My implementation, based on the Array.Reverse method:
/// <summary>
/// Rotate left for negative k. Rotate right for positive k.
/// </summary>
public static void Rotate<T>(T[] array, int k)
{
ArgumentNullException.ThrowIfNull(array);
k = k % array.Length;
if (k < 0) k += array.Length;
if (k == 0) return;
Debug.Assert(k > 0);
Debug.Assert(k < array.Length);
Array.Reverse(array, 0, array.Length - k);
Array.Reverse(array, array.Length - k, k);
Array.Reverse(array);
}
Live demo.
Output:
Array: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Rotate(5)
Array: 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7
Rotate(-2)
Array: 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9

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.

Counting comparisons in Heapsort using C#

I have a heapsort algorithm.
private int heapSize;
private void BuildHeap(int[] arr)
{
heapSize = arr.Length - 1;
for (int i = heapSize / 2; i >= 0; i--)
{
Heapify(arr, i);
}
}
private void Swap(int[] arr, int x, int y)//function to swap elements
{
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
private void Heapify(int[] arr, int index)
{
int left = 2 * index + 1;
int right = 2 * index + 2;
int largest = index;
if (left <= heapSize && arr[left] > arr[index])
{
largest = left;
}
if (right <= heapSize && arr[right] > arr[largest])
{
largest = right;
}
if (largest != index)
{
Swap(arr, index, largest);
Heapify(arr, largest);
}
}
public int PerformHeapSortTest(int[] arr)
{
int counter = 0;
BuildHeap(arr);
for (int i = arr.Length - 1; i >= 0; i--)
{
Swap(arr, 0, i);
heapSize--;
Heapify(arr, 0);
}
DisplayArray(arr);
}
Private void DisplayArray(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{Console.Write("{0}\n", arr[i])}
}
I want to count the comparisons and don't understand how to implement this using this heap sort algorithm which is in a separate class which I call from the main. I have looked around online and can't find anything. Could some one show me how to implement comparisons to this algorithm?
You need to implement your comparisons using Compare method instead of using operators. Please see full answer here (answer post): how to count heapsort key comparisons

Matrix Row - QuickSort recursion problem

I've adapted QuickSort Method to sort Array's Row.
Here's the code:
That one works fine
static void QuickSort(int lowBound, int highBound, int[] a)
{
int temp = 0;
int x = random.Next(lowBound, highBound);
int pivot = a[x];
int i = lowBound;
int j = highBound;
do
{
while (a[i] < pivot) i++;
while (pivot < a[j]) j--;
if (i <= j)
{
temp = a[i]; //changes an element smaller than the pivot...
a[i] = a[j];//... with the greater one
a[j] = temp;
i++; j--;
}
}
while (i <= j);
if (lowBound < j) { QuickSort(lowBound, j, a); }//recursion
if (i < highBound){ QuickSort(i,highBound, a); }
}
Here's the problematic method
static void QuickSortMatrix(int[,] a)
{
int n = a.GetLength(0);
int m = a.GetLength(1);
for (int i = 0; i < n; i++)
{
QuickSortRow(0, m - 1, i, a);
}
for (int j = 0; j < m; j++)
{
QuickSortRow(0, n - 1, j, a);
}
}
static void QuickSortRow(int lowBound, int highBound, int row, int[,] a)
{
int temp = 0;
int x = random.Next(lowBound, highBound);
int pivot = a[row,x];
int p = lowBound;
int q = highBound;
do
{
while (a[row,p] < pivot) p++;
while (pivot < a[row,q]) q--;
if (p <= q)
{
temp = a[row,p];
a[row,p] = a[row,q];
a[row,q] = temp;
p++; q--;
}
}
while (p <= q);
if (lowBound < q) { QuickSortRow(lowBound, q, row, a); }
if (p < highBound) { QuickSortRow(p, highBound,row, a); }
}
At first when the "for" loop is executed everything's ok bur for some reason when executed recursively the row that should be constant when calling the method goes outside the matrix boundaries.
Here's my array and rows reaches value of 4
int[,] matrix =
{
{7,8,9,10,11,5},
{3,6,4,16,22,4},
{7,9,17,8,3,21},
{24,7,11,19,3,4}
};
I hope my explanation was clear enough.
Could anybody advise me? What I'm missing here?
Thank you for your kind help!
BR
Stephan
n is the number of rows in the matrix (4)
m is the number of columns in the matrix (6)
In your second loop you are going 0..m and passing that value to the row parameter. It blows up because there are more columns in the matrix than rows. i.e. It tries to read matrix[4, 0].
Note: as far as I can tell you don't need the second loop because your rows are already sorted after the first loop. Remove that and it won't throw an exception.

Extension method for fill rectangular array in C#

I want write extension method for fill multidimensional rectangular array. I know how to do it for the array with a fixed number of measurements:
public static void Fill<T>(this T[] source, T value)
{
for (int i = 0; i < source.Length; i++)
source[i] = value;
}
public static void Fill<T>(this T[,] source, T value)
{
for (int i = 0; i < source.GetLength(0); i++)
for (int j = 0; j < source.GetLength(1); j++)
source[i, j] = value;
}
public static void Fill<T>(this T[,,] source, T value)
{
for (int i = 0; i < source.GetLength(0); i++)
for (int j = 0; j < source.GetLength(1); j++)
for (int k = 0; k < source.GetLength(2); k++)
source[i, j, k] = value;
}
Can I write one fill-method for all multidimensional rectangular array?
You can change the fixed dimension parameter to an Array parameter so you can put the extension on any Array. Then I used recursion to iterate through each position of the array.
public static void Fill<T>(this Array source, T value)
{
Fill(0, source, new long[source.Rank], value);
}
static void Fill<T>(int dimension, Array array, long[] indexes, T value)
{
var lowerBound = array.GetLowerBound(dimension);
var upperBound = array.GetUpperBound(dimension);
for (int i = lowerBound; i <= upperBound; i++)
{
indexes[dimension] = i;
if (dimension < array.Rank - 1)
{
Fill(dimension + 1, array, indexes, value);
}
else
{
array.SetValue(value, indexes);
}
}
}
Here's a solution that does not use recursion (and is less complex):
public static void FillFlex<T>(this Array source, T value)
{
bool complete = false;
int[] indices = new int[source.Rank];
int index = source.GetLowerBound(0);
int totalElements = 1;
for (int i = 0; i < source.Rank; i++)
{
indices[i] = source.GetLowerBound(i);
totalElements *= source.GetLength(i);
}
indices[indices.Length - 1]--;
complete = totalElements == 0;
while (!complete)
{
index++;
int rank = source.Rank;
indices[rank - 1]++;
for (int i = rank - 1; i >= 0; i--)
{
if (indices[i] > source.GetUpperBound(i))
{
if (i == 0)
{
complete = true;
return;
}
for (int j = i; j < rank; j++)
{
indices[j] = source.GetLowerBound(j);
}
indices[i - 1]++;
}
}
source.SetValue(value, indices);
}
}
This is modeled from the System.Array.ArrayEnumerator. This implementation should have a similar level of correctness as ArrayEnumerator and (based on a few spot checks) appears to function fine.

Categories