How many swaping & comparsions in each sorting algorithm? - c#

class Sort
{
int[] arr;
int counter=0;
//Constructor
public Sort()
{
arr = new int[10000];
}
string address;
public void SwitchCase(int Case)
{
switch (Case)
{
case 1:
address = #"C:\Users\Aqib Saeed\Desktop\case1.txt";
break;
case 2:
address = #"C:\Users\Aqib Saeed\Desktop\case2.txt";
break;
case 3:
address = #"C:\Users\Aqib Saeed\Desktop\case3.txt";
break;
default:
break;
}
}
//Read file for input
public void FillArray()
{
using (StreamReader rdr = new StreamReader(address))
{
for (int i = 0; i < arr.Length; i++)
{
arr[i] = Convert.ToInt32(rdr.ReadLine());
}
}
}
// Insertion Sort
public void InsertionSort()
{
int insert;
for (int i = 1; i < arr.Length; i++)
{
insert = arr[i];
int moveItem = i;
while (moveItem > 0 && arr[moveItem - 1] > insert)
{
arr[moveItem] = arr[moveItem - 1];
moveItem--;
counter++;
}
arr[moveItem] = insert;
}
}
public void Counter()
{
Console.WriteLine(counter);
}
//Bubble Sorting
public void BubbleSort()
{
int temp;
for (int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < arr.Length - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
counter++;
}
}
}
}
//Selection Sorting
public void SelectionSort()
{
int min, temp;
for (int i = 0; i < arr.Length; i++)
{
min = i;
for (int j = i + 1; j < arr.Length; j++)
if (arr[j] < arr[min])
min = j;
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
counter++;
}
}
// Write Output to file
public void Writer()
{
using (StreamWriter wrtr = new StreamWriter(#"C:\Users\AqibSaeed\Desktop\SortedOutput.txt"))
{
for (int i = 0; i < arr.Length; i++)
{
wrtr.WriteLine(arr[i]);
}
}
}
}
static void Main(string[] args)
{
Sort srt = new Sort();
Console.WriteLine("Enter Case 1 OR 2 OR 3");
srt.SwitchCase(Convert.ToInt32(Console.ReadLine()));
srt.FillArray();
srt.BubbleSort();
srt.Writer();
Console.WriteLine("Sorted Output File Is Ready");
srt.Counter();
Console.ReadLine();
}
I implement my Sort class for sorting integers and place int counter to determine number of swaps and comparsions. But I am not sure it is working correctly! Is there any other way to determine number of swaping and comparsions?

You could create a class which implements IComparable to count the comparator access and a specialized collection which counts the swaps. Like that you dont have to count the access inside of the sort algorithms and you delegate the tasks more strict to code parts.
In the index operator you count the swap operations and in the IComparable implementation you count the comparisons
Example for a class SortItem which implements the IComparable:
public class SortItem<T> : IComparable<T> where T : IComparable
{
private static int _ComparisonCount = 0;
public static int ComparisonCount
{
private set
{
_ComparisonCount = value;
}
get
{
return _ComparisonCount;
}
}
public T Value
{
get;
set;
}
public static void ResetComparisonCount()
{
_ComparisonCount = 0;
}
#region IComparable<T> Members
public int CompareTo(T other)
{
ComparisonCount++;
return this.Value.CompareTo(other);
}
#endregion
}
and the sorting collection:
public class SortCollection<T> : IList<SortItem<T>>
{
public SortCollection(IList<T> sortList)
{
InnerList = sortList;
}
private IList<T> InnerList = null;
public T this[int key]
{
get
{
return InnerList[key];
}
set
{
SwapCount++;
InnerList[key] = value;
}
}
private int _SwapCount = 0;
public int SwapCount
{
private set
{
_SwapCount = value;
}
get
{
return _SwapCount;
}
}
public void ResetSwapCount()
{
_SwapCount = 0;
}
}
Here the execution:
List<Int32> baseList = new List<int>(new Int32 {6, 2, 7, 3, 1, 6, 7 });
SortCollection<Int32> sortList = new SortCollection<int>(baseList);
//do the sorting....
Console.WriteLine("Swaps: " + sortList.SwapCount.ToString());
Console.WriteLine("Comparisons: " + SortItem<Int32>.ComparisonCount.ToString());
SortItem<Int32>.ResetComparisonCount();
sortList.ResetSwapCount();

You are only counting swaps and not counting comparisons. If you want to count comparisons then you need to add an extra counter that you increment every time you pass an if comparison.

Related

Add another item in array without built-in functions

The following script is working fine. But need to add one more item in array without built-in function. Is it possible to do without Resize() ?
string[] data = {"item-1", "item-2"};
Array.Resize(ref data, 3);
data[2] = "item-3";
foreach(string i in data) {
Console.WriteLine(i);
}
No. Arrays are fixed size, so the only way to add more stuff to them is to resize them.
If you have a scenario where you need to add a dynamic number of elements, use List<T> instead.
Assuming you're trying to increase the size of an array without any built-in libraries or data structures, you just need to create a new larger array, copy the old elements, then add your new element.
string[] data = {"item-1", "item-2"};
string[] newData = new string[data.Length + 1];
int i;
for (i = 0; i < data.Length; i++) {
newData[i] = data[i];
}
newData[i] = "item-3";
Console.WriteLine(newData[2]);
The short answer is no. But if you want you can always implement a logic that does the resizing. You could do something like this implementation of a List:
public class List<T> : IAbstractList<T>
{
private const int DEFAULT_CAPACITY = 4;
private T[] _items;
public List()
: this(DEFAULT_CAPACITY) {
}
public List(int capacity)
{
if (capacity < 0)
{
throw new ArgumentOutOfRangeException(nameof(capacity));
}
this._items = new T[capacity];
}
public T this[int index]
{
get
{
this.ValidateIndex(index);
return this._items[index];
}
set
{
this.ValidateIndex(index);
this._items[index] = value;
}
}
public int Count { get; private set; }
public void Add(T item)
{
this.GrowIfNecessary();
this._items[this.Count++] = item;
}
public bool Contains(T item)
{
for (int i = 0; i < this.Count; i++)
{
if (this._items[i].Equals(item))
{
return true;
}
}
return false;
}
public int IndexOf(T item)
{
for (int i = 0; i < this.Count; i++)
{
if (this._items[i].Equals(item))
{
return i;
}
}
return -1;
}
public void Insert(int index, T item)
{
this.ValidateIndex(index);
this.GrowIfNecessary();
for (int i = this.Count - 1; i > index; i--)
{
this._items[i] = this._items[i - 1];
}
this._items[index] = item;
this.Count++;
}
public bool Remove(T item)
{
var index = this.IndexOf(item);
if (index == - 1)
{
return false;
}
this.RemoveAt(index);
return true;
}
public void RemoveAt(int index)
{
this.ValidateIndex(index);
for(int i = index; i < this.Count - 1; i++)
{
this._items[i] = this._items[i + 1];
}
this._items[this.Count - 1] = default;
this.Count--;
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < this.Count; i++)
{
yield return this._items[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
=> this.GetEnumerator();
private void ValidateIndex(int index)
{
if (index < 0 || index >= this.Count)
{
throw new IndexOutOfRangeException(nameof(index));
}
}
private void GrowIfNecessary()
{
if (this.Count == this._items.Length)
{
var array = new T[this.Count * 2];
Array.Copy(this._items, array, this._items.Length);
this._items = array;
}
}
}
The above sample code can give you ideas about implementing other methods that need array resizing as well.

Addresses of values in an array aren't static C#

So, I am currently making a little code with some pointers. I am trying to get every values of an array, and their respective address. However, the initial array is empty, and the user has to enter numbers as an input, which ends up being added to the array itself. Then, I want to get the address of each value that the user added, one by one. Everything works fine, except one thing; I want every value to have a static address. However, I noticed that at every inputs, every values had a different address than the one they had before. I tried to put the array as a global static variable, but it still doesn't work. Any help?
Thanks for everyone who takes their time to answer! <3
Full code:
using System;
public class ClearIt
{
public int k = 8;
}
public static class Arr
{
public static int StaticAddress;
public static int[] x = { };
}
public class Class
{
public static unsafe void Main()
{
ClearIt clearIt = new ClearIt();
int k2 = clearIt.k;
for (int j = 0; j < 1;)
{
string Read = Console.ReadLine();
int ReadToInt;
bool isTrue;
isTrue = int.TryParse(Read, out ReadToInt);
if (!isTrue)
{
return;
}
int StaticAdd = Arr.StaticAddress = ReadToInt;
if (k2 > 0)
{
var xList = Arr.x.ToList();
xList.Add(StaticAdd);
Arr.x = xList.ToArray();
Array.Sort(Arr.x);
k2--;
}
else if(k2 == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
var xList2 = Arr.x.ToList();
xList2.Clear();
Arr.x = xList2.ToArray();
Console.WriteLine("Array cleared.");
Console.ForegroundColor = ConsoleColor.White;
k2 = 8;
}
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\nValues\tAddresses");
for (int i = 0; i < Arr.x.Length; i++)
{
fixed (int* y = &Arr.x[i])
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\n" + *y + $"\t{(long)y:X}\n");
Console.ForegroundColor = ConsoleColor.White;
}
}
}
}
}
The short answer is that everytime you assign to Arr.x you are creating a new array and a new part of memory is used.
The statement below for example causes Arr.x address to change
Arr.x = xList2.ToArray();
If you do not want to change the address of Arr.x, then only assign it once to the maximum length, and keep track of the item count actually stored.
My best guess is that you are trying to do something like this
where the addresses in memory do not change when items are added or the
array is cleared. After the 8th number is added, the list clears
and more numbers can be added
As you can see the address value does not change.
I am using fixed buffer arrays to store the values, instead of the regular array. Here is the code that generates the output above
class Program
{
static void Main(string[] args)
{
var arr = new FixedArray();
do
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"{"offset"}\t{"address"}\t{"value"}");
for (int i = 0; i < arr.Count; i++)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write($"{i}");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write($"\t{arr.GetItemAddress(i)}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"\t{arr[i]:X}");
Console.ForegroundColor = ConsoleColor.Gray;
}
if (arr.Count == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Array Cleared.");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine();
}
Console.WriteLine("Enter Value:");
string input = Console.ReadLine();
if (int.TryParse(input, out int value))
{
if (arr.Add(value))
{
}
else
{
arr.Clear();
}
}
else
{
return;
}
} while (true);
}
}
and FixedArray is the object that actually stores the data
public unsafe struct FixedArray
{
public const int Size = 8;
fixed int data[Size];
public FixedArray(params int[] array) : this()
{
Count = Math.Min(Size, array.Length);
fixed (int* ptr = data)
{
for (int i = 0; i < Count; i++)
{
ptr[i] = array[i];
}
}
}
public IntPtr GetItemAddress(int offset = 0)
{
fixed (int* ptr = &data[offset])
{
return (IntPtr)ptr;
}
}
public int this[int offset]
{
get
{
if (offset >= 0 && offset < Count)
{
return data[offset];
}
return 0;
}
}
public int Count { get; private set; }
public void Clear() { Count = 0; }
public bool Add(int x)
{
if (Count < Size)
{
data[Count] = x;
Count++;
return true;
}
return false;
}
public int[] ToArray()
{
int[] array = new int[Count];
fixed (int* ptr = data)
{
for (int i = 0; i < Count; i++)
{
array[i] = ptr[i];
}
}
return array;
}
}
You don't have to use a fixed buffer array. You can just use a standard array, but with the readonly keyword so it only gets assigned once. Use the class below as a replacement to FixedArray above.
public class StdArray
{
public const int Size = 8;
public int Count { get; private set; }
readonly int[] data;
public StdArray(params int[] array)
{
data = new int[Size];
Count = Math.Min(Size, array.Length);
Array.Copy(array, data, Count);
}
public unsafe IntPtr GetItemAddress(int offset = 0)
{
fixed (int* ptr = &data[offset])
{
return (IntPtr)ptr;
}
}
public int this[int offset]
{
get
{
if (offset >= 0 && offset < Count)
{
return data[offset];
}
return 0;
}
}
public void Clear() { Count = 0; }
public bool Add(int x)
{
if (Count < Size)
{
data[Count] = x;
Count++;
return true;
}
return false;
}
public int[] ToArray()
{
int[] array = new int[Count];
Array.Copy(data, array, Count);
return array;
}
}

C# Linked Lists (adding an element to a defined position)

Our teacher asked us to implement the class LinkedList. I was able to implement everything he asked for. But he gave us a bonus question that I was not able to solving.
He asked us to implement this fonction:
public void add(float x, int pos)
{
// Add x at the position pos, pos = 0 refer to the first element.
}
He also demanded that his code verifies the following UnitTest:
public class UnitTest1
{
private MyList l;
public UnitTest1()
{
l = new MyList();
for (int i = 0; i < 10; ++i)
{
l.add(i * i);
}
for (int i = 0; i < 10; ++i)
{
l.add(i * i);
}
}
[TestMethod]
public void TestAdd()
{
Assert.AreEqual(l.count(), 20);
}
[TestMethod]
public void TestGet()
{
for (int i = 0; i < 10; ++i)
{
Assert.AreEqual(l.get(i), (9 - i) * (9 - i));
}
for (int i = 10; i < 20; ++i)
{
Assert.AreEqual(l.get(i), (19 - i) * (19 - i));
}
}
[TestMethod]
public void TestFind()
{
int k;
for (int i = 0; i < 100; ++i)
{
for (k = 0; k < 10; ++k)
{
if (k * k == i)
{
Assert.AreEqual(l.find(i), true);
break;
}
}
if (k == 10)
{
Assert.AreEqual(l.find(i), false);
}
}
}
[TestMethod]
public void TestStats()
{
Assert.AreEqual(l.max(), 81);
float s = 0;
for (int i = 0; i < 10; ++i)
{
s += i * i + i * i;
}
Assert.AreEqual(l.sum(), s);
Assert.AreEqual(l.average(), s / 20);
}
[TestMethod]
public void TestCountValue()
{
MyList l1 = new MyList();
for (int i = 0; i < 10; ++i)
{
l1.add(i);
l1.add(i * i);
}
Assert.AreEqual(l1.count(-1), 0);
Assert.AreEqual(l1.count(0), 2);
Assert.AreEqual(l1.count(1), 2);
Assert.AreEqual(l1.count(2), 1);
Assert.AreEqual(l1.count(3), 1);
Assert.AreEqual(l1.count(4), 2);
Assert.AreEqual(l1.count(5), 1);
Assert.AreEqual(l1.count(6), 1);
Assert.AreEqual(l1.count(7), 1);
Assert.AreEqual(l1.count(8), 1);
Assert.AreEqual(l1.count(9), 2);
Assert.AreEqual(l1.count(10), 0);
Assert.AreEqual(l1.count(16), 1);
}
[TestMethod]
public void TestRemoveFirst()
{
MyList l1 = new MyList();
for (int i = 0; i < 10; ++i)
{
l1.add(i);
l1.add(i * i);
}
Assert.AreEqual(l1.count(81), 1);
l1.removeFirst();
Assert.AreEqual(l1.count(), 19);
Assert.AreEqual(l1.count(81), 0);
Assert.AreEqual(l1.count(-1), 0);
Assert.AreEqual(l1.count(0), 2);
Assert.AreEqual(l1.count(1), 2);
Assert.AreEqual(l1.count(2), 1);
Assert.AreEqual(l1.count(3), 1);
Assert.AreEqual(l1.count(4), 2);
Assert.AreEqual(l1.count(5), 1);
Assert.AreEqual(l1.count(6), 1);
Assert.AreEqual(l1.count(7), 1);
Assert.AreEqual(l1.count(8), 1);
Assert.AreEqual(l1.count(9), 2);
Assert.AreEqual(l1.count(10), 0);
Assert.AreEqual(l1.count(16), 1);
}
[TestMethod]
public void TestInsert()
{
MyList l1 = new MyList();
for (int i = 9; i >= 0; --i)
{
l1.add(i);
}
for (int i = 0; i <= 10; ++i)
{
l1.add(i, 2 * i);
}
for (int i = 0; i < 10; ++i)
{
Assert.AreEqual(l1.get(2 * i), i, "i=" + i);
Assert.AreEqual(l1.get(2 * i + 1), i);
}
Assert.AreEqual(l1.get(20), 10);
}
}
That's what I was capable of:
public class MyList
{
class Element
{
public float value;
public Element next;
}
Element first;
public MyList()
{
first = null;
}
public void add(float x)
{
Element e = new Element();
e.value = x;
e.next = first;
first = e;
}
public float get(int i)
{
if (first == null)
{
throw new Exception("Empty list... no elements inside");
}
Element tmp = first;
for (int j = 0; j < i; ++j)
{
tmp = tmp.next;
if (tmp == null)
{
throw new Exception("...");
}
}
return tmp.value;
}
public void print()
{
Element e = first;
while (e != null)
{
Console.WriteLine(e.value);
e = e.next;
}
}
public bool find(float x)
{
Element e = first;
while (e != null)
{
if (e.value == x)
{
return true;
}
e = e.next;
}
return false;
}
public float max()
{
float G = 0;
for (Element e = first; e != null; e = e.next)
{
if (e.value > G)
{
G = e.value;
}
}
return G;
}
public int count()
{
Element e = first;
int c = 0;
while (e != null)
{
c++;
e = e.next;
}
return c;
}
public int count(float x)
{
int c = 0;
for (Element e = first; e != null; e = e.next)
{
if (e.value == x)
{
c++;
}
}
return c;
}
public float sum()
{
float S = 0;
for (Element e = first; e != null; e = e.next)
{
S += e.value;
}
return S;
}
public float average()
{
return sum() / count();
}
public void removeFirst()
{
Element e = first;
first = e.next;
}
public void add(float x, int pos)
{
//I have absolutely no idea how to implement this fonction.
}
}
It will be similar to the code in the get() method.
Break your problem down into smaller problems
Does pos = 0?
if so, create a new root and point it to the old root
if not, loop (pos) times and create a new element. Then set the next property of the new element to the next property of the current element. Set the current element next property to your new element
.
public void add(float x, int pos)
{
if(pos == 0)
{
// create a new root and point the new root to the existing root
}
else
{
Element tmp = first;
for(int i = 0; i < pos; i++)
{
tmp = tmp.next;
}
// create new element
// set new element next property to tmp.next
// set tmp.next to new element
}
}

Finding minimum value from list

How would i build an algorithm here in the most efficient way possible to find minimum value from list? I know the list hasnt done in the best way but, any ideas how to do ?
I have tried few ways but dont seem to get it work efficiently..
Thanks.
class MainClass
{
public class List
{
public int maxSize = 50;
public int MaxSize
{
get
{
return maxSize;
}
set
{
maxSize = value;
}
}
public int firstEmpty = 0;
public int FirstEmpty
{
get
{
return firstEmpty;
}
set
{
firstEmpty = value;
}
}
public int[] data;
public List()
{
data = new int[maxSize];
}
public int returnValueAtIndex(int i)
{
return data[i];
}
public void setValueAtIndex(int v, int i)
{
data[i] = v;
}
}
public static int FIRST(List L)
{
if (END(L) > 0)
return 0;
else
return -1;
}
public static int END(List L)
{
return L.FirstEmpty;
}
public static int NEXT(int p, List L)
{
if (p >= 0 && p < L.MaxSize && p < END(L))
return p+1;
else
return - 1;
}
public static int PREVIOUS(int p, List L)
{
if (p >= 0 && p < L.MaxSize && p <= END(L))
return p-1;
else
return -1;
}
public static int LOCATE (int x, List L)
{
int i = 0;
while (i<END(L) && RETRIEVE(i, L) != x)
{
i++;
}
if (i != END(L))
return i;
else
return -1;
}
public static int RETRIEVE(int p, List L)
{
if (p >= 0 && p < END(L))
return L.returnValueAtIndex(p);
else
return -1;
}
public static void INSERT(int x, int p, List L)
{
if (p >= 0 && p < L.MaxSize && p <= END(L))
{
if (p == END(L))
{
L.setValueAtIndex(x, p);
}
else
{
for (int i = END(L); i > p; i--)
{
L.setValueAtIndex(L.returnValueAtIndex(i - 1), i);
L.setValueAtIndex(x, p);
}
}
L.FirstEmpty = END(L) + 1;
}
else
Console.WriteLine("Alkiota ei voitu lisätä");
}
public void DELETE(int p, List L)
{
if (p >= 0 && p < END(L))
{
for (int i = p; i < p - 1; i++)
{
L.setValueAtIndex(L.returnValueAtIndex(i + 1), i);
}
L.FirstEmpty = END(L) - 1;
}
}
public void MAKENULL(List L)
{
L.FirstEmpty = 0;
}
public static void PRINT(List L)
{
Console.WriteLine("Listan sisältö:");
for (int i = 0; i < END(L); i++)
{
Console.Write(L.returnValueAtIndex(i) + " ");
}
Console.WriteLine();
}
public static void Main(string[] args)
{
List testilista = new List();
INSERT(2, END(testilista), testilista);
INSERT(7, END(testilista), testilista);
INSERT(9, END(testilista), testilista);
INSERT(12, END(testilista), testilista);
INSERT(9, END(testilista), testilista);
INSERT(38, END(testilista), testilista);
Console.WriteLine("testilista");
PRINT(testilista);
Console.ReadLine();
}
}
}
The easiest way to do that in C# is with LinQ:
var minValue = data.Min();
if you want the highest value:
var maxValue = data.Max();
Note: Answer is not specific to C#
Given an unordered list of numbers, the fastest way to find the smallest number in the list is to look at every element in the list.
var unorderedList = [5,4,3,2,6,7,-23,8,-64,2,0,6];
function findSmallest(anArray){
var lowest = anArray[0];
for(var i = 1; i < anArray.length; i++){
var num = anArray[i];
if(num < lowest){
lowest = num;
}
}
return lowest;
}
var smallest = findSmallest(unorderedList);
console.log(smallest); //prints -64
You can run the code here
hit the run button
I don't think this is the best option. For me there is two ways.
Sort your list by this code.
int valueMin = L.returnValueAtIndex(0);
for (int i = 0; i < END(L); i++)
{
//if the value of i is smaller than the value
if (valueMin < L.returnValueAtIndex(i))
{
//i become the min Value
valueMin = L.returnValueAtIndex(i);
}
}
Console.WriteLine(valueMin);
Console.Read();
Or in C# you can use Array.Sort
Array.Sort(L);
Console.WriteLine(L.returnValueAtIndex(0));
Console.Read();
I hope this will help you !

C# enter value into multidimensional array

I am build a program with c#, and have included dataGridView on it. I do math operation on that dataGridView data, then insert the result into multidimensional array. But i got error message that say "Object reference not set to an instance of an object".
here my code:
frm_clustering.cs
public void hitungMatriksJarak()
{
clusteringModel cm = new clusteringModel();
int i = 0;
int j = 0;
for (i = 0; i < this.dgv_clustering.Rows.Count; i++)
{
for (j = 0; j < this.dgv_clustering.Rows.Count; j++)
{
cm.matriks[j,i] = Math.Sqrt(Math.Pow(Convert.ToDouble(this.dgv_clustering[1, i].Value), 2) +
Math.Pow(Convert.ToDouble(this.dgv_clustering[2, i].Value), 2) +
Math.Pow(Convert.ToDouble(this.dgv_clustering[3, i].Value), 2) +
Math.Pow(Convert.ToDouble(this.dgv_clustering[4, i].Value), 2));
}
}
}
clusteringModel.cs:
class clusteringModel
{
private int _jmlKel;
public int jmlKel
{
get { return _jmlKel; }
set { _jmlKel = value; }
}
private double[,] _matriks = new double[500,500];
public double[,] matriks
{
get { return _matriks; }
set { _matriks = value; }
}
}

Categories

Resources