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.
Related
I've tried creating linked list/node classes and I'm not sure where to go next. My attempts haven't went well because after creating the classes I'm just not sure what the next step is.
I'm trying to create a program that has a dinosaur node which saves information about the dinosaur such as id, species etc and I want to allow the user to create and remove dinosaurs from the list. So I need to allow the user to input data, I assume there's a way to make dino id get set automatically but I'm not to sure.
I've included the LinkedList.cs and the Node.cs so you can see where I'm going but I have no idea what to do within my program class to utilise the linked list and achieve what I'm trying to do.
Added Program.cs class incase that helps identify/show where I am within the program/what I need to do.
Linked List Class:
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System.Text;
namespace JurrasicFinal
{
public class LinkedList
{
private Node head;
private int count;
public LinkedList()
{
this.head = null;
this.count = 0;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public object this[int index]
{
get { return this.Get(index); }
}
public object Add(int index, object o)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (index > count)
index = count;
Node current = this.head;
if (this.Empty || index == 0)
{
this.head = new Node(o, this.head);
}
else
{
for (int i = 0; i < index - 1; i++)
{
current = current.Next;
current.Next = new Node(o, current.Next);
}
}
count++;
return o;
}
public object Add(object o)
{
return this.Add(count, o);
}
public object Remove(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = count - 1;
Node current = this.head;
object result = null;
if (index == 0)
{
result = current.Data;
this.head = current.Next;
}
else
{
for (int i = 0; index < index - 1; i++) ;
current = current.Next;
result = current.Next.Data;
current.Next = current.Next.Next;
}
count--;
return result;
}
public void Clear()
{
this.head = null;
this.count = 0;
}
public int IndexOf(object o)
{
Node current = this.head;
for (int i = 0; i < this.count; i++)
{
if (current.Data.Equals(o))
return i;
current = current.Next;
}
return -1;
}
public bool Contains(object o)
{
return this.IndexOf(o) >= 0;
}
public object Get(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = this.count - 1;
Node current = this.head;
for (int i = 0; i < index; i++)
current = current.Next;
return current.Data;
}
}
}
Node Class:
using System;
using System.Collections.Generic;
using System.Text;
namespace JurrasicFinal
{
public class Node
{
private object data;
private Node next;
private string DinoSpecies;
private string DinoName;
public Node(object data, Node next)
{
this.data = data;
this.next = next;
}
public object Data
{
get { return this.data; }
set { this.data = value; }
}
public Node Next
{
get { return this.next; }
set { this.next = value; }
}
}
}
Program Class:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq.Expressions;
namespace JurrasicFinal
{
class Program
{
class Dinosaur
{
public string Name;
public string Classification;
public char Sex;
}
static void Main(string[] args)
{
LinkedList<Dinosaur> DinoList = new LinkedList<Dinosaur>();
Dinosaur Dino1 = new Dinosaur();
Dino1.Name = "Tyrannosaurus Rex";
Dino1.Classification = "Carnivorous";
Dino1.Sex = 'M';
Dinosaur Dino2 = new Dinosaur();
Dino2.Name = "Velociraptor";
Dino2.Classification = "Carnivorous";
Dino2.Sex = 'F';
Dinosaur Dino3 = new Dinosaur();
Dino3.Name = "Procompsognathus";
Dino3.Classification = "Carnivorous";
Dino3.Sex = 'M';
void printList()
{
Console.WriteLine("Current Queue: ");
Console.WriteLine("\n");
foreach (Dinosaur d in DinoList)
{
Console.WriteLine("Name: " + d.Name);
Console.WriteLine("Classification: " + d.Classification);
Console.WriteLine("Sex " + d.Sex);
Console.WriteLine("\n");
}
Console.WriteLine(Dino1.Name + Dino1.Sex);
}
DinoList.AddLast(Dino1);
DinoList.AddLast(Dino2);
DinoList.AddLast(Dino3);
printList();
Console.WriteLine(DinoList.Count);
FileStream fileStream = File.OpenWrite("E:/Work/Dinosaur.txt");
BinaryWriter writer = new BinaryWriter(fileStream);
foreach (Dinosaur d in DinoList)
{
writer.Write(d.Name);
writer.Write(d.Classification);
writer.Write(d.Sex);
}
writer.Close();
Console.WriteLine("Reading Back From File");
FileStream file = File.OpenRead("E:/Work/Dinosaur.txt");
BinaryReader reader = new BinaryReader(file);
for (int i = 1; i < 3; i++)
{
Dinosaur d = new Dinosaur();
d.Name = reader.ReadString();
d.Classification = reader.ReadString();
d.Sex = reader.ReadChar();
DinoList.AddLast(d);
}
reader.Close();
Console.ReadKey();
}
}
}
I think you might be looking for something like this, which hangs on user input and tries to do simple validation. I made it a bit overly complex to demonstrate some options.
class Sample
{
private static int index = 0;
static void Main(string[] args)
{
LinkedList<Dinosaur> DinoList = new LinkedList<Dinosaur>();
while (true)
{
var dino = new Dinosaur();
dino.Name = GetInput("Enter dino name (q to quit): ");
if (dino.Name == "q" || dino.Name == "Q")
{
break;
}
dino.Classification = GetInput("Enter dino classification: ");
char[] sexes = new char[] {'F', 'f', 'M', 'm'};
while (true)
{
Console.WriteLine("Enter dino sex (M/F): ");
dino.Sex = (char) Console.Read();
if (sexes.Contains(dino.Sex))
{
break;
}
}
int inputIndex = default;
while (true)
{
var indexString = GetInput($"Enter 0-index list position (max {DinoList.Count})");
inputIndex = Convert.ToInt32(indexString);
if (inputIndex <= DinoList.Count)
{
break;
}
}
DinoList.Add(inputIndex, dino);
index++;
Console.WriteLine("Dinosaurs:");
Console.WriteLine(new string('-', 30));
for (var i = 0; i < DinoList.Count; i++)
{
var dinosaur = (Dinosaur) DinoList.Get(i);
Console.WriteLine("Name: " + dinosaur.Name);
Console.WriteLine("Classification: " + dinosaur.Classification);
Console.WriteLine("Sex: " + dinosaur.Sex);
}
}
}
private static string GetInput(string prompt)
{
Console.WriteLine(prompt);
var input = Console.ReadLine();
while (string.IsNullOrWhiteSpace(input))
{
input = Console.ReadLine();
}
return input;
}
}
Note that you have to make your LinkedList and Node into LinkedList<T> and Node<T> but they converted directly, so it's just a bit of typing.
Hope it helps!
Edit: Add classes provided in question, modified to be generic.
public class Node<T>
{
private object data;
private Node<T> next;
private string DinoSpecies;
private string DinoName;
public Node(object data, Node<T> next)
{
this.data = data;
this.next = next;
}
public object Data
{
get { return this.data; }
set { this.data = value; }
}
public Node<T> Next
{
get { return this.next; }
set { this.next = value; }
}
}
public class LinkedList<T>
{
private Node<T> head;
private int count;
public LinkedList()
{
this.head = null;
this.count = 0;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public object this[int index]
{
get { return this.Get(index); }
}
public object Add(int index, object o)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (index > count)
index = count;
Node<T> current = this.head;
if (this.Empty || index == 0)
{
this.head = new Node<T>(o, this.head);
}
else
{
for (int i = 0; i < index - 1; i++)
{
current = current.Next;
current.Next = new Node<T>(o, current.Next);
}
}
count++;
return o;
}
public object Add(object o)
{
return this.Add(count, o);
}
public object Remove(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = count - 1;
Node<T> current = this.head;
object result = null;
if (index == 0)
{
result = current.Data;
this.head = current.Next;
}
else
{
for (int i = 0; index < index - 1; i++) ;
current = current.Next;
result = current.Next.Data;
current.Next = current.Next.Next;
}
count--;
return result;
}
public void Clear()
{
this.head = null;
this.count = 0;
}
public int IndexOf(object o)
{
Node<T> current = this.head;
for (int i = 0; i < this.count; i++)
{
if (current.Data.Equals(o))
return i;
current = current.Next;
}
return -1;
}
public bool Contains(object o)
{
return this.IndexOf(o) >= 0;
}
public object Get(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = this.count - 1;
Node<T> current = this.head;
for (int i = 0; i < index; i++)
current = current.Next;
return current.Data;
}
}
I have an array of string, a total of(100k). I need to check if the same string has occurred previously, if it occurs all I have to do is return that string. I have written the code using nested for loops, but unfortunately I am getting bad performance. It takes 1.9 mins to process the function correctly for (string[100K]) whereas I am expecting it to finish it within a couple of seconds.
My concern is not the logic. My concern is the LOOP. How to increase the efficiency of the loop.
public string StartMatchingProcess(string[]inputArray)
{
string[] stringArray = inputArray;
string result = string.Empty;
for (long i = 0; i < stringArray.Length; i++)
{
for (long j = 0; j <= i; j++)
{
if(i == j) break;
if (IsPrefix(stringArray[i], stringArray[j]))
{
return stringArray[i];
}
}
}
Console.WriteLine("GOOD SET");
return result;
}
public bool IsPrefix(string string1,string string2)
{
if (AreString1ValuesValid(string1, string2))
{
if (string1 == string2.Substring(0, string1.Length))
{
Console.WriteLine("BAD SET");
Console.WriteLine(string1);
return true;
}
}
else if (AreString2ValuesValid(string1, string2))
{
if (string2 == string1.Substring(0, string2.Length))
{
Console.WriteLine("BAD SET");
Console.WriteLine(string1);
return true;
}
}
return false;
}
public bool AreString1ValuesValid(string string1, string string2)
=> string1.Length <= string2.Length;
public bool AreString2ValuesValid(string string1, string string2)
=> string2.Length <= string1.Length;
Sort the initial array, and you can check neighbors only:
public string StartMatchingProcess(string[] inputArray) {
if (null == inputArray)
throw new ArgumentNullException(nameof(inputArray));
string[] sorted = inputArray.OrderBy(item => item).ToArray();
for (int i = 1; i < sorted.Length; ++i) {
string prior = sorted[i - 1];
string current = sorted[i];
if (current.StartsWith(prior))
return prior;
}
return "";
}
So, you'll have O(n * log(n)) time complexity vs. O(n**2) (initial solution)
It's really bad idea to use nested loops for this task because you have O(n*n) complexity for the answer and need to make 10.000.000.000 calls of Substring() for 100k array.
There is a specific structures for strings. For example, you can use Trie:
public string StartMatchingProcess(string[] inputArray)
{
var trie = new Trie();
foreach(var w in inputArray)
trie.AddWord(w);
foreach(var w in inputArray)
if(trie.HasPrefix(w) || trie.HasWord(w)
return w;
return string.Empty;
}
If you are just trying to determine if your array has duplicate string values, consider LINQ to get the count of the occurences.
string[] arrayTest = new string[] { "hello", "hello", "world"};
string myValue = "hello";
var stringCount = arrayTest.Where(n => n == myValue).Count();
if (stringCount > 1) return myValue;
In the above, we check to see if "hello" is in the array more than once, and if it is, we return it.
Here is a complete solution using linq.
public class Node
{
public char letter { get; }
public int Index { get; set; }
public List<Node> ChildList { get; set; } = new List<Node>();
public Node(char item, int index)
{
Index = index;
letter = item;
}
}
public class NoPrefixSet
{
public Dictionary<char, Node> ParentNode { get; set; } = new Dictionary<char, Node>();
public string GenerateNodes(string[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
if (IsWordPrefix(inputArray[i]))
{
Console.WriteLine("BAD SET");
Console.WriteLine(inputArray[i]);
return inputArray[i];
}
}
Console.WriteLine("Good Set");
return "Good Set";
}
private void InsertNodeInParent(char item)
=> ParentNode.Add(item, new Node(item, 0));
private bool IsWordPrefix(string word)
{
//Check parent
Node parentNode = null;
bool hasNotInserted = false;
int similarCounter = 0;
if (!ParentNode.Any(a => a.Key == word[0]))
{
InsertNodeInParent(word[0]);
}
parentNode = ParentNode.Where(a => a.Key == word[0]).FirstOrDefault().Value;
for (int letterIndex = 0; letterIndex < word.Length; letterIndex++)
{
if (!parentNode.ChildList.Any(a => a.letter == word[letterIndex]))
{
parentNode.ChildList.Add(new Node(word[letterIndex], letterIndex));
}
else
{
if (!parentNode.ChildList.Where(a => a.letter == word[letterIndex]).First().ChildList.Any() || word.Length == letterIndex+1)
{
if (similarCounter == letterIndex)
return hasNotInserted = true;
}
similarCounter++;
}
parentNode = parentNode.ChildList.Where(a => a.letter == word[letterIndex] && a.Index == letterIndex).First();
}
return hasNotInserted;
}
public void ReadInput()
{
long data = Convert.ToInt64(Console.ReadLine());
string[] stringArray = new string[data];
for (long i = 0; i < data; i++)
{
stringArray[i] = Console.ReadLine();
}
GenerateNodes(stringArray);
}
}
This is the static array I have been given in making a RPN calculator. From this code the RPN calculator adds and subtracts. Now I need to extend my code to multiply and divide but I cant I don't know how.
public class IntStack
{
private const int maxsize = 10;
private int top = 0;
private int[] array = new int[maxsize];
public void Push(int value)
{
array[top++] = value;
}
public int Pop()
{
return array[--top];
}
public int Peek()
{
return array[top - 1];
}
public bool IsEmpty()
{
return top == 0;
}
public bool IsFull()
{
return top == maxsize;
}
public string Print()
{
StringBuilder output = new StringBuilder();
for (int i = top - 1; i >= 0; i--)
output.Append(array[i] + Environment.NewLine);
return output.ToString();
}
}
Here are some methods you can add to your IntStack class that will perform the multiply and division operations. I've added minimal error checking.
public void Multiply()
{
if (array.Length < 2)
return;
var factor1 = Pop();
var factor2 = Pop();
Push(factor1 * factor2);
}
public void Divide()
{
if (array.Length < 2)
return;
var numerator = Pop();
var divisor = Pop();
if (divisor == 0) { // Return stack back to original state.
Push(divisor);
Push(numerator);
return;
}
Push(numerator / divisor);
}
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 !
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.