Bubble sort is not working - c#

Currently the user is able to input numbers into the ListBox, and I want the ListBox to be sorted by the bubble sort below when a sort checkbutton is clicked. However, it only outputs the index number e.g. 0,1,2,3... I am not allowed to use any array or containers just the items property and parsing and converting.
private void sorted()
{
int a = Convert.ToInt32(lstHoldValue.Items.Count);
int temp;
for (int i = 0; i < a; i++)
{
for (int j = i + 1; j < a; j++)
{
if (Convert.ToInt32(lstHoldValue.Items[i]) >
Convert.ToInt32(lstHoldValue.Items[j]))
{
temp = Convert.ToInt32(lstHoldValue.Items[i]);
(lstHoldValue.Items[i]) = Convert.ToInt32(lstHoldValue.Items[j]);
(lstHoldValue.Items[j]) = temp;
}
}
}
lstHoldValue.Items.Clear();
for (int i = 0; i < a; i++)
{
Convert.ToInt32(lstHoldValue.Items.Add("\t" + i));
}
}

This is more like a Bubble sort algorithm:
private void BubbleSort()
{
int a = lstHoldValue.Items.Count;
for (int i = 0; i < a - 1; i++)
{
var k = 0;
for(var j = 1; j < a - i; j++)
{
if (Convert.ToInt32(lstHoldValue.Items[j]) < Convert.ToInt32(lstHoldValue.Items[k]))
{
var temp = lstHoldValue.Items[j];
lstHoldValue.Items[j] = lstHoldValue.Items[k];
lstHoldValue.Items[k] = temp;
k = j;
}
else
{
k++;
}
}
}
}
It will sort the numbers in the Items collection of your lstHoldValue listBox control

If the item in the ListBox is not an integer, then it is sorted as zero (0).
This sets bubbleUp to true indicating that a swap has been made in the list box. This variable is used to indicate that a swap has/has not been made in the last comparison. Entering the while(bubbleUp) sets bubbleUp to false to indicate that no swaps have been made. Then a loop through each item in the list box to compare adjacent items and swap if needed. If a swap is made, bubbleUp gets set to true indicating that the sort is not finished. bubbleUp only needs to be set once in the for loop to indicate another iteration is necessary. CheckItem is the conversion from string to integer. Hope this helps.
private void sorted()
{
bool bubbleUp = true;
string temp = "";
while (bubbleUp)
{
// bubble up adjacent values
bubbleUp = false;
for (int i = 0; i < _ListBox.Items.Count - 1; i++)
{
if (CheckItem(_ListBox.Items[i].ToString()) > CheckItem(_ListBox.Items[i + 1].ToString()))
{
temp = _ListBox.Items[i].ToString();
_ListBox.Items[i] = _ListBox.Items[i + 1];
_ListBox.Items[i + 1] = temp;
bubbleUp = true;
}
}
}
}
private int CheckItem(string inItem)
{
int value;
if (int.TryParse(inItem, out value))
return value;
return 0;
}
private void button1_Click(object sender, EventArgs e)
{
sorted();
}

Related

Bubble sort when using struct members

struct SSales
{
private int Y;
private double S;
public int Year
{
get { return Y; }
set { Y = value; }
}
public double Sale
{
get { return S; }
set { S = value; }
}
public SSales (int _year, double _sales)
{
Y = _year;
S = _sales;
}
private void Sortbutton_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
if (yearradio.Checked)
{
int temp = 0;
for (int i = 0; i < bubble.Length - 1; i++)
{
for (int j = 0; j < bubble.Length - 1; j++)
{
if (bubble[i + 1].Year < bubble[i].Year)
{
temp = bubble[i].Year;
bubble[i].Year = bubble[i + 1].Year;
bubble[i + 1].Year = temp;
}
}
}
}
if (salesradio.Checked)
{
double temp2 = 0;
for (int i = 0; i < bubble.Length - 1; i++)
{
for (int j = 0; j < bubble.Length - 1; j++)
{
if (bubble[i + 1].Sale > bubble[i].Sale)
{
temp2 = bubble[i].Sale;
bubble[i].Sale = bubble[i + 1].Sale;
bubble[i + 1].Sale = temp2;
}
}
}
}
for (int i = 0; i < bubble.Length; i++)
{
listBox1.Items.Add(bubble[i].ToString());
}
}
While my bubble sorting algorithms work perfectly fine, they only sort incrementally with each click of the Sort Button. I need the listbox to be completely sorted with 1 click.
Also, as my code is now, the Years and Sales reorganize completely independent of each other. When the Sales index changes, the corresponding Year index remains at the same location and vice versa.
I'm guessing a for loop with int j would work, but I'm not sure how to implement it. Any help would be appreciated!
I see two issues. One you are setting/exchanging the Properties of the struct, not the structs themselves. That is why your sales and years are out of sync. You need to exchange the entire struct. Something like:
var temp = bubble[i];
bubble[i] = bubble[i + 1];
bubble[i + 1] = temp;
This leads to the second issue. You have a double loop using index variables i and j. Your swap only uses i. If you are trying to do a bubble sort do you really need nested loops? Consider the pseudo-code implementation that can be found here bubble sort, you should quickly be able to see the issue. Model your sort after that example.
I will guess that you are doing bubble sort for learning / practice reasons. If not you should just use the inbuilt Array.Sort() or Enumerable.OrderBy() or something similar.
There are multiple things you have done wrong. I have the improved code below which I will explain
struct SSales {
public int Year { get; set; } // use auto-properties for brevity
public double Sale { get; set; } // use auto-properties for brevity
public SSales(int year, double sales) {
Year = year;
Sale = sales;
}
}
// Use a generic routine to Swap, instead of replicating the code multiple times
// Note that we are passing by reference so the actual array eventually gets sorted
// Also, don't swap the properties, but the whole record. Else it will corrupt your data
static void Swap<T>(ref T obj1, ref T obj2) {
var temp = obj1;
obj1 = obj2;
obj2 = temp;
}
// Write the sort routine separately. Sorts usually just need a way to compare records, which can be provided by Caller (IoC pattern)
static void Sort<T>(T[] items, Func<T, T, int> comparer) {
for (int i = 0; i < items.Length - 1; i++) {
// Every execution of the inner loop will bubble-up the largest element in the range
// Your array is getting sorted from the end, so you don't need to re-compare the already sorted part
for (int j = 0; j < items.Length - 1 - i; j++) {
if (comparer(items[j], items[j + 1]) > 0) // call the generic user provided comparer to know the sequence
Swap(ref items[j], ref items[j + 1]); // use teh generic swapper to swap elements in the array
}
}
}
private void Sortbutton_Click(object sender, EventArgs e) {
listBox1.Items.Clear();
if (yearradio.Checked) {
// Invoke the Sort routine, with the required comparer
Sort(bubble, (a, b) => a.Year - b.Year);
}
if (salesradio.Checked) {
// Invoke the Sort routine, with the required comparer
Sort(bubble, (a, b) => (int)(a.Sale - b.Sale));
}
for (int i = 0; i < bubble.Length; i++) {
listBox1.Items.Add(bubble[i].ToString());
}
}
Hope that clarifies the issues you are facing and also helps you learn how to write better C# code.

Unsort a listbox in c# winform

I am very new programmer, the user is able to input vales into a ListBox, there is also a option button where the user can sort the numbers in ascending order. However I am also asked to create a option button to unsort back into its original form, however I am not sure how I would do this. I am trying to do this without the use of any containers/arrays. here is my code to sort:
private void sorted()
{
int a = lstHoldValue.Items.Count;
for (int i = 0; i < a - 1; i++)
{
var k = 0;
for (var j = 1; j < a - i; j++)
{
if (Convert.ToInt32(lstHoldValue.Items[j]) < Convert.ToInt32(lstHoldValue.Items[k]))
{
var temp = lstHoldValue.Items[j];
lstHoldValue.Items[j] = lstHoldValue.Items[k];
lstHoldValue.Items[k] = temp;
k = j;
}
else
{
k++;
}
}
}
}

Index Of Longest Run C#

I am trying to solve this question:
Write a function that finds the zero-based index of the longest run in a string. A run is a consecutive sequence of the same character. If there is more than one run with the same length, return the index of the first one.
For example, IndexOfLongestRun("abbcccddddcccbba") should return 6 as the longest run is dddd and it first appears on index 6.
Following what i have done:
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter =1;
int maxCount = 0;
int idenxOf = 0;
for (int i =0; i<array1.Length-1 ; i++)
{
if (comparer.Compare(array1[i],array1[i+1]) == 0)
{
counter++;
}
else {
if(maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
return idenxOf ;
}
}
public class Comparer : IComparer<char>
{
public int Compare(char firstChar, char nextChar)
{
return firstChar.CompareTo(nextChar);
}
}
The problem is that when i get to the last index for example "abbccaaaaaaaaaa"
which is a in this case, and when i=14 (taking this string as example) and when i<array1.Length-1 statment is false, the for loop jumps directrly to return indexOf; and return the wrong index, I am trying to find out how to push the forloop to continue the implementation so idenxOf could be changed to the right index. Any help please?
You could check whether a new best score is achieved for each iteration when current == previous. Minimally slower, but it allows you to write shorter code by omitting an extra check after the loop:
int IndexOfLongestRun(string input)
{
int bestIndex = 0, bestScore = 0, currIndex = 0;
for (var i = 0; i < input.Length; ++i)
{
if (input[i] == input[currIndex])
{
if (bestScore < i - currIndex)
{
bestIndex = currIndex;
bestScore = i - currIndex;
}
}
else
{
currIndex = i;
}
}
return bestIndex;
}
Promote the loop variable i to method scope and repeat the conditional block if (maxCount < counter) { ... } right after the loop exit. Thus, it executes one more time after the loop completes
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter = 1;
int maxCount = 0;
int idenxOf = 0;
int i;
for (i = 0; i < array1.Length - 1; i++)
{
if (comparer.Compare(array1[i], array1[i + 1]) == 0)
{
counter++;
}
else
{
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
return idenxOf;
}
As usual late, but joining the party. A natural classic algorithm:
static int IndexOfLongestRun(string input)
{
int longestRunStart = -1, longestRunLength = 0;
for (int i = 0; i < input.Length; )
{
var runValue = input[i];
int runStart = i;
while (++i < input.Length && input[i] == runValue) { }
int runLength = i - runStart;
if (longestRunLength < runLength)
{
longestRunStart = runStart;
longestRunLength = runLength;
}
}
return longestRunStart;
}
At the end you have both longest run index and length.
public static int IndexOfLongestRun(string str)
{
var longestRunCount = 1;
var longestRunIndex = 0;
var isNew = false;
var dic = new Dictionary<int, int>();
for (var i = 0; i < str.Length - 1; i++)
{
if (str[i] == str[i + 1])
{
if (isNew) longestRunIndex = i;
longestRunCount++;
isNew = false;
}
else
{
isNew = true;
dic.Add(longestRunIndex, longestRunCount);
longestRunIndex = 0;
longestRunCount = 1;
}
}
return dic.OrderByDescending(x => x.Value).First().Key;
}
This will return -1 if the string is empty and you have the flexibility of returning the index and the count depending on your specification.
string myStr = "aaaabbbbccccccccccccdeeeeeeeee";
var longestIndexStart = -1;
var longestCount = 0;
var currentCount = 1;
var currentIndexStart = 0;
for (var idx = 1; idx < myStr.Length; idx++)
{
if (myStr[idx] == myStr[currentIndexStart])
currentCount++;
else
{
if (currentCount > longestCount)
{
longestIndexStart = currentIndexStart;
longestCount = currentCount;
}
currentIndexStart = idx;
currentCount = 1;
}
}
return longestIndexStart;
The accepted answer from Kvam works great for small strings, but as the length approaches 100,000 characters (and perhaps this isn't needed), its efficiency wains.
public static int IndexOfLongestRun(string str)
{
Dictionary<string, int> letterCount = new Dictionary<string, int>();
for (int i = 0; i < str.Length; i++)
{
string c = str.Substring(i, 1);
if (letterCount.ContainsKey(c))
letterCount[c]++;
else
letterCount.Add(c, 1);
}
return letterCount.Values.Max();
}
This solution is twice as fast as Kvam's with large strings. There are, perhaps, other optimizations.

Listbox not removing values in c# GUI

The user basically enters a number of hex values into a textbox separated by commas eg. AA,1B,FF. These are then displayed in a listbox box. if the number of hex values in the textbox exceeds the size to transfer defined by the user, the listbox only displays the this number of values or if the size to transfer is bigger that adds zero values to the listbox.
this works fine until you enter a value with a zero in front of it such as AA,BB,CC,DD,EE,0F, if sizeToTransfer = 2, the listbox should display 0xAA and 0xBB. but instead it only removes the 0F value?
I'm pretty new to programming so it may be something obvious I'm missing any help would be appreciated.
private void WriteSPI1_Click(object sender, EventArgs e)
{
string hexstring = textbox1.Text;
HexValues.Items.Clear();
string[] hexarray = hexstring.Split((",\r\n".ToCharArray()), StringSplitOptions.RemoveEmptyEntries);
byte[] hexbytes = new byte[hexarray.Length];
uint num = Convert.ToUInt32(hexarray.Length);
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
if (hexarray.Length > sizeToTransfer)
{
diff = num - sizeToTransfer;
for (i = 0; i < diff+1; i++)
{
HexValues.Items.Remove("0x" + x);
}
}
else
{
diff = sizeToTransfer - num;
for (i = 0; i < diff; i++)
{
HexValues.Items.Add("0x00");
}
}
}
CHANGE
for (int j = 0; j < sizeToTransfer; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
WITH
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
and remove the if stantment that follow

Selection sort just working once in C# gui

I am using selection sort in GUI and the thing is that when I select selection sort and do sorting on generate numbers it sorts generated numbers for one time but if next time I will use other number it will do just the first step of sorting by just replacing two numbers and won't work then... So why it's not working again and why showing such different behavior?
The code is:-
void SelectionSort() {
int i = 0;
int j, min, temp;
min = i;
for (j = i + 1; j < 10; j++) {
if (generate[min] > generate[j]) {
min = j;
}
}
if (min != i) {
temp = generate[i];
generate[i] = generate[min];
generate[min] = temp;
//show1(generate);
}
show1(generate);
i++;
}
My guess, you need to add i=0; at the beginning.
I guess from your function that i is a global variable.
You need to reset i to 0 every time you enter the function (Inside the function)
using System;
namespace SelectionSortExample
{
class Program
{
static void Main(string[] args)
{
int[] num = { 105, 120, 10, 200, 20 };
for (int i = 0; i < num.Length; i++)
{
int minIndex = i;
for (int j = i + 1; j < num.Length; j++)
{
if (num[minIndex] > num[j])
{
minIndex = j;
}
}
int tmp = num[i];
num[i] = num[minIndex];
num[minIndex] = tmp;
}
}
}
}

Categories