How to insert timespan in my bubble sort? - c#

I created a program to perform bubble sort on random numbers and I am trying to include the time it takes to go through each sorting operations in milliseconds. I tried a few ways but my program does not even acknowledge the code for it. Does anybody see what I am doing wrong?
class BubbleSort
{
static void Main(string[] args)
{
int[] a = { 50000, 250000, 25000, 750000, 500000, 100, 100000,
1000000, 1000 };
int t;
Console.WriteLine("Array is: ");
for (int i = 0; i < a.Length; i++)
{
Console.WriteLine(a[i]);
}
DateTime start = DateTime.Now;
DateTime end;
for (int j = 0; j <= a.Length - 2; j++)
{
for (int i = 0; i <= a.Length - 2; i++)
{
if (a[i] > a[i + 1])
{
t = a[i + 1];
a[i + 1] = a[i];
a[i]=t;
}
}
}
end = DateTime.Now;
TimeSpan ts = end.Subtract(start);
Console.WriteLine("The Sorted Array: ");
foreach (int Array in a)
Console.Write(Array + " ");
Console.Read();
Console.WriteLine("Duration = {0} ms", ts.TotalMilliseconds);
}

Related

Displaying an arrays index number

I need help with C#
I'm currently trying to find the minimum value in a 2D array. I have managed to do this however, after I have found the minimum value I want the corresponding values index number (Where it is stored in my 2D array) to be output. For example, I have a 2D and a 1D array. Once the minimum value has been discovered the index value for the 2D array needs to be changed in the 1D array.
The 2d array is c[i,j]
and the 1D array is a[i]
so how would i be able to display the j number in my c array in my a array. For example, if my minimum value was at c[1,5] I want the value in a[5] to be changed from 0 to 1. Any help would be great thanks!
P.S. if ive made this sound really confusing I apologise I'm new to this !
int n = 5, m = 10, MinValue = 100, MaxValue = 1, Total = 0, Sum = 0; //n = number of values m = max value in array MinValue = Lowest number in array
Random Rand = new Random();
int[] A = new int[n + 1];
for (int i = 1; i < n+1; i++) //Reached and unreached array - creation
{
A[i] = 0;
}
A[1] = 1;
int[,] c = new int[n + 1, n + 1]; //Create array
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
c[i, j] = Rand.Next(1, m); //Randomise the array
if (i == j)
{
c[i, j] = 99; // give void spaces the value of 99
}
if (c[i, j] > MaxValue && c[i, j] < 99)
{
MaxValue = c[i, j]; // max value takes the highest value (that isnt 99)
}
}
}
for (int p = 1; p <= n; p++)
{
for (int i = 1; i <= n+1; i++)
{
for (int j = 1; i <= n+1; i++)
{
if (c[i, j] <= MinValue)
{
if (A[i] == 1)
{
if (A[i] == 0)
{
Total = Sum + MinValue;
Sum = Total;
A[i] = 1;
}
}
}
}
}
}
Console.WriteLine("Total Value = " + Total);
Console.WriteLine("");
Console.WriteLine("The tracking array - what has been reached and what hasn't"); // Output reaching array
Console.WriteLine("");
for (int i = 1; i <= n; i++)
{
Console.WriteLine("A[" + i + "] = " + A[i].ToString("00") + " ");
//Output the array to screen
}
Console.WriteLine("");
Console.WriteLine("The link length array"); // Output link length array
Console.WriteLine("");
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
Console.Write("c[" + i + "," + j + "] = " + c[i, j].ToString("00") + " ");
}
Console.WriteLine();
//Output the array to screen
}
Console.WriteLine("");
Console.ReadLine();

My code won't do the sum; only the elements of the matrix appear and then nothing happens

namespace Suma_diagonala_secundara
{
class Program
{
static void Main(string[] args)
{
int n, i, j, s = 0;
Console.Write("n= ");
n = Convert.ToInt32(Console.ReadLine());
int[,] tab = new int[n, n];
for(i=0;i<n;i++)
for (j = 0; j < n; j++)
{
Console.Write("tab[{0}][{1}]= ", i + 1, j + 1);
tab[i, j] = Convert.ToInt32(Console.ReadLine());
}
Console.Write("\nElementele matricii sunt: ");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
Console.Write("{0} ", tab[i, j]);
Console.WriteLine("");
}
Console.WriteLine("Suma elementelor de pe diagonala secundara este: ");
for (i = 0; i < n; i++)
{
s = s + tab[i, n - i + 1];
}
Console.ReadKey();
}
}
}
In your loop
for (i = 0; i < n; i++)
{
s = s + tab[i, n - i + 1];
}
you are accessing the array out of bounds, since n - 0 + 1 = n + 1 is larger than n - 1 (the largest index in tab).
What you actually want is (note the parentheses)
for (i = 0; i < n; i++)
{
s = s + tab[i, n - (i + 1)];
}
The following line:
s = s + tab[i, n - i + 1];
Is throwing an IndexOutOfRangeException because you are requesting an index higher than the array capacity.
The correct loop code is (with decrement instead increment)
for (i = 0; i < n; i++)
{
s = s + tab[i, n - i - 1];
}

Finding and Fixing Method Issues [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm currently doing an assignment where I need to find the errors in a program that is preventing it from executing. Its a comparison sort program where there are two sorting methods being compared, Merge Sort and Counting Sort. Its giving me the "No overload for (insert method), takes 1 arguments" message, but I'm unable to find or fix what's giving it the errors, any general idea or fixes to make the comparison work would be appreciated.
using System;
using System.Collections;
namespace Sort
{
class Program
{
static void Main(string[] args)
{
Random rdm = new Random();
ArrayList data = new ArrayList();
ArrayList dataB = new ArrayList();
int size = 50000;
int[] dta = new int[size];
int[] dta50 = new int[50];
int randomNum;
DateTime startTime, endTime;
int i;
// Show both methods worked
for (i = 0; i < 50; i++)
{
randomNum = rdm.Next(100);
data.Add(randomNum);
dta50[i] = randomNum;
}
dataB = CountingSort(data);
PrintArray("Merge Sort:", dataB);
MergeSort(dta50);
Console.WriteLine();
Console.WriteLine("\nCounting Sort:");
Console.WriteLine();
for (int x = 0; x < 50; x++)
Console.Write(dta50[x] + " ");
Console.WriteLine();
Console.WriteLine("\nCounting Sort\tMerge Sort");
for (int n = 1; n < 20; n++) // run 20 times
{
data.Clear();
for (i = 0; i < size; i++)
{
randomNum = rdm.Next(size);
data.Add(randomNum);
dta[i] = randomNum;
}
// Counting Sorting
startTime = DateTime.Now;
CountingSort(data);
endTime = DateTime.Now;
TimeSpan howlong = endTime.Subtract(startTime);
Console.Write(" {0}ms", howlong.Milliseconds);
// Merge Sorting
startTime = DateTime.Now;
MergeSort(dta);
endTime = DateTime.Now;
TimeSpan howlong1 = endTime.Subtract(startTime);
Console.WriteLine("\t\t{0}ms", howlong1.Milliseconds);
}
Console.ReadLine();
}
public static void MergeSort(int[] input, int left, int right)
{
if (left < right)
{
int middle = (left + right) / 2;
MergeSort(input, left, middle);
MergeSort(input, middle + 1, right);
//Merge
int[] leftArray = new int[middle - left + 1];
int[] rightArray = new int[right - middle];
Array.Copy(input, left, leftArray, 0, middle - left + 1);
Array.Copy(input, middle + 1, rightArray, 0, right - middle);
int i = 0;
int j = 0;
for (int k = left; k < right + 1; k++)
{
if (i == leftArray.Length)
{
input[k] = rightArray[j];
j++;
}
else if (j == rightArray.Length)
{
input[k] = leftArray[i];
i++;
}
else if (leftArray[i] <= rightArray[j])
{
input[k] = leftArray[i];
i++;
}
else
{
input[k] = rightArray[j];
j++;
}
}
}
}
private static int[] CountingSort(int[] arr, int min, int max)
{
int[] count = new int[max - min + 1];
int z = 0;
for (int i = 0; i < count.Length; i++) { count[i] = 0; }
for (int i = 0; i < arr.Length; i++) { count[arr[i] - min]++; }
for (int i = min; i <= max; i++)
{
while (count[i - min]-- > 0)
{
arr[z] = i;
z++;
}
}
return arr;
}
static void PrintArray(string title, ArrayList dt)
{
int cc = 0;
Console.WriteLine("\n" + title + "\n");
foreach (int item in dt)
{
if (cc < 10)
Console.Write("{0,4}", item);
else
{ Console.WriteLine(); cc = 0; }
}
}
}
}
Look at your functions:
public static void MergeSort(int[] input, int left, int right)
private static int[] CountingSort(int[] arr, int min, int max)
They each expect three values when you invoke them. Look at how you invoke them:
MergeSort(dta50);
CountingSort(data);
MergeSort(dta);
You're supplying one value, not three.
Elsewhere you invoke them differently:
MergeSort(input, left, middle);
MergeSort(input, middle + 1, right);
In those cases you supply three values.
You need to supply the functions with the values it requires. Otherwise the code has no way of knowing what to do.

fastest way to make an element in a list as the first element

I have list and I want a short and fast way to make one of its element as the first.
I have in mind to use the code below to select the 10th element and make it first. But looking for a better soln
tempList.Insert(0, tempList[10]);
tempList.RemoveAt(11);
if you don't mind the ordering of the rest, you actually could swap the two items at position 0 and 10, believe it's better than doing insertion and deletion:
var other = tempList[0];
tempList[0]=tempList[10];
tempList[10] = other;
and you can even make this an extension of List for ease of use, something like:
public static void Swap<T>(this List<T> list, int oldIndex, int newIndex)
{
// place the swap code here
}
There are some special cases when you could get better performance (for the sake of simplicity, I'm assuming that the value is always inserted before the position where it was taken from):
class Program
{
const int Loops = 10000;
const int TakeLoops = 10;
const int ItemsCount = 100000;
const int Multiplier = 500;
const int InsertAt = 0;
static void Main(string[] args)
{
var tempList = new List<int>();
var tempDict = new Dictionary<int, int>();
for (int i = 0; i < ItemsCount; i++)
{
tempList.Add(i);
tempDict.Add(i, i);
}
var limit = 0;
Stopwatch
sG = new Stopwatch(),
s1 = new Stopwatch(),
s2 = new Stopwatch();
TimeSpan
t1 = new TimeSpan(),
t2 = new TimeSpan();
for (int k = 0; k < TakeLoops; k++)
{
var takeFrom = k * Multiplier + InsertAt;
s1.Restart();
for (int i = 0; i < Loops; i++)
{
tempList.Insert(InsertAt, tempList[takeFrom]);
tempList.RemoveAt(takeFrom + 1);
}
s1.Stop();
t1 += s1.Elapsed;
s2.Restart();
for (int i = 0; i < Loops; i++)
{
var e = tempDict[takeFrom];
for (int j = takeFrom - InsertAt; j > InsertAt; j--)
{
tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
}
tempDict[InsertAt] = e;
}
s2.Stop();
t2 += s2.Elapsed;
if (s2.Elapsed > s1.Elapsed || limit == 0)
limit = takeFrom;
}
sG.Start();
for (int k = 0; k < TakeLoops; k++)
{
var takeFrom = k * Multiplier + InsertAt;
if (takeFrom >= limit)
{
for (int i = 0; i < Loops; i++)
{
tempList.Insert(InsertAt, tempList[takeFrom]);
tempList.RemoveAt(takeFrom + 1);
}
}
else
{
for (int i = 0; i < Loops; i++)
{
var e = tempDict[takeFrom];
for (int j = takeFrom - InsertAt; j > InsertAt; j--)
{
tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
}
tempDict[InsertAt] = e;
}
}
}
sG.Stop();
Console.WriteLine("List: {0}", t1);
Console.WriteLine("Dictionary: {0}", t2);
Console.WriteLine("Optimized: {0}", sG.Elapsed);
/***************************
List: 00:00:11.9061505
Dictionary: 00:00:08.9502043
Optimized: 00:00:08.2504321
****************************/
}
}
In the example above, a Dictionary<int,int> is being used to store the index of each element. You will get better results if the gap between insertAt and takeFrom is smaller. As this interval increases, the performance will degrade. I guess you might want to evaluate this gap and take the optimal branch based on it's value.

Need to optimise counting positive and negative values

I need to optimise code that counts pos/neg values and remove non-qualified values by time.
I have queue of values with time-stamp attached.
I need to discard values which are 1ms old and count negative and positive values. here is pseudo code
list<val> l;
v = q.dequeue();
deleteold(l, v.time);
l.add(v);
negcount = l.count(i => i.value < 0);
poscount = l.count(i => i.value >= 0);
if(negcount == 10) return -1;
if(poscount == 10) return 1;
I need this code in c# working with max speed. No need to stick to the List. In fact arrays separated for neg and pos values are welcome.
edit: probably unsafe arrays will be the best. any hints?
EDIT: thanks for the heads up.. i quickly tested array version vs list (which i already have) and the list is faster: 35 vs 16 ms for 1 mil iterations...
Here is the code for fairness sake:
class Program
{
static int LEN = 10;
static int LEN1 = 9;
static void Main(string[] args)
{
Var[] data = GenerateData();
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 30; i++)
{
sw.Reset();
ArraysMethod(data, sw);
Console.Write("Array: {0:0.0000}ms ", sw.ElapsedTicks / 10000.0);
sw.Reset();
ListMethod(data, sw);
Console.WriteLine("List: {0:0.0000}ms", sw.ElapsedTicks / 10000.0);
}
Console.ReadLine();
}
private static void ArraysMethod(Var[] data, Stopwatch sw)
{
int signal = 0;
int ni = 0, pi = 0;
Var[] n = new Var[LEN];
Var[] p = new Var[LEN];
for (int i = 0; i < LEN; i++)
{
n[i] = new Var();
p[i] = new Var();
}
sw.Start();
for (int i = 0; i < DATALEN; i++)
{
Var v = data[i];
if (v.val < 0)
{
int x = 0;
ni = 0;
// time is not sequential
for (int j = 0; j < LEN; j++)
{
long diff = v.time - n[j].time;
if (diff < 0)
diff = 0;
// too old
if (diff > 10000)
x = j;
else
ni++;
}
n[x] = v;
if (ni >= LEN1)
signal = -1;
}
else
{
int x = 0;
pi = 0;
// time is not sequential
for (int j = 0; j < LEN; j++)
{
long diff = v.time - p[j].time;
if (diff < 0)
diff = 0;
// too old
if (diff > 10000)
x = j;
else
pi++;
}
p[x] = v;
if (pi >= LEN1)
signal = 1;
}
}
sw.Stop();
}
private static void ListMethod(Var[] data, Stopwatch sw)
{
int signal = 0;
List<Var> d = new List<Var>();
sw.Start();
for (int i = 0; i < DATALEN; i++)
{
Var v = data[i];
d.Add(new Var() { time = v.time, val = v.val < 0 ? -1 : 1 });
// delete expired
for (int j = 0; j < d.Count; j++)
{
if (v.time - d[j].time < 10000)
d.RemoveAt(j--);
else
break;
}
int cnt = 0;
int k = d.Count;
for (int j = 0; j < k; j++)
{
cnt += d[j].val;
}
if ((cnt >= 0 ? cnt : -cnt) >= LEN)
signal = 9;
}
sw.Stop();
}
static int DATALEN = 1000000;
private static Var[] GenerateData()
{
Random r = new Random(DateTime.Now.Millisecond);
Var[] data = new Var[DATALEN];
Var prev = new Var() { val = 0, time = DateTime.Now.TimeOfDay.Ticks};
for (int i = 0; i < DATALEN; i++)
{
int x = r.Next(20);
data[i] = new Var() { val = x - 10, time = prev.time + x * 1000 };
}
return data;
}
class Var
{
public int val;
public long time;
}
}
To get negcount and poscount, you are traversing the entire list twice.
Instead, traverse it once (to compute negcount), and then poscount = l.Count - negcount.
Some ideas:
Only count until max(negcount,poscount) becomes 10, then quit (no need to count the rest). Only works if 10 is the maximum count.
Count negative and positive items in 1 go.
Calculate only negcount and infer poscount from count-negcount which is easier to do than counting them both.
Whether any of them are faster than what you have now, and which is fastest, depends among other things on what the data typically looks like. Is it long? Short?
Some more about 3:
You can use trickery to avoid branches here. You don't have to test whether the item is negative, you can add its negativity to a counter. Supposing the item is x and it is an int, x >> 31 is 0 for positive x and -1 for negative x. So counter -= x >> 31 will give negcount.
Edit: unsafe arrays can be faster, but shouldn't be in this case, because the loop would be of the form
for (int i = 0; i < array.Length; i++)
do something with array[i];
Which is optimized by the JIT compiler.

Categories