Bucket Sort algorithm issues c# [duplicate] - c#

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I am learning about sorting algorithms, and am currently at a loss with my first "Distribution Pass". As my notations describe, the first loop is where I sort each value into my bucket array based on the one's value. It works for every value except for the 9th index of my values array. The loop terminates before it gets to the 9th index. I've tried changing the conditions of the for loop, but that doesn't seem to work. Some help or hints as to what is happening would be much appreciated!
** Edit this is not the complete algorithm, it is only the first two steps. I am following the instructions from my c# book. The notes placed before each loop are the word for word instructions from the book. I don't want to continue with the sorting algorithm until I get the first loop working properly.
public static void Sort(int[] values)
{
int n = values.Length;
int[,] buckets = new int[n, n - 1];
int index = 0;
// Place each value of the one-dimensional array
// into a row of the bucket array, based on the
// value's "one's" (rightmost) digit.
// "Distribution Pass"
for (int i = 0; i < values.Length -1; ++i)
{
// Get the one's value of values[i]
int ones = (values[i] % 10);
// Place the value in the appropriate bucket
buckets[ones, i] = values[i];
}
// Loop through the bucket array row by row,
// and copy the values back to the original
// array.
// "Gathering Pass"
for (int r = 0; r < n; r++)
{
for (int c = 0; c < n - 1; c++)
{
try
{
if (buckets[r, c] != 0)
{
values[index] = buckets[r, c];
index++;
}
}
catch
{
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Random rand = new Random();
int[] randomArray = new int[10];
label1.Text = "Unsorted Array: ";
label2.Text = " Sorted Array: ";
for (int i = 0; i < randomArray.Length; i++)
{
randomArray[i] = rand.Next(10, 100);
label1.Text += randomArray[i] + " ";
}
Sort(randomArray);
label2.Text += string.Join(" ", randomArray);
}

Related

Losing value if backwards List printing matrix

I need to display a Sheet so that the lines are aligned bottom and left. If there are no 10 characters in the word, the number of "+" characters is added so that the total of the line is 10 characters (see my output).
Why, when I print a List, I lose one row?
What's wrong with my piece of code? This matrix should be 10X10.
My output
List<string> filtredList = new List<string>() { "Jacuzzi", "Action", "Chinchilla", "Squeezebox", "Academic", "Abstract" };
int row = 10;
filtredList = Sorting(filtredList); //method is sorting by descending.
foreach (var item in filtredList) Console.WriteLine("Item: " + item + " length: " + item.Length);
Console.WriteLine("-------------------------------------");
//AFTER SORTING IN LIST:
//1)Squeezebox 2)Chinchilla 3)Academic 4)Abstract 5)Jacuzzi 6)Action
for (int i = 10; i > 0; i--)
{
try
{
if (filtredList[i].Length != 10)
{
Console.Write(filtredList[i]);
row = 10 - filtredList[i].Length;
Console.WriteLine(string.Concat(Enumerable.Repeat("+", row)));
}
else Console.WriteLine(filtredList[i]);
}
catch (SystemException)
{
row = 10;
Console.WriteLine(string.Concat(Enumerable.Repeat("+", row)));
}
}
Because your for loop is never gets to 0:
for (int i = 10; i > 0; i--)
i goes from 10 to 1 and that's why the first item of your list never prints.
Note:
Index of first item of an array or a list is 0
The better code would be:
for (int i = 9; i >= 0; i--)
Although you can use better alternatives for some of your code, but this will solve your problem.
EDIT:
You can use this approach (just change the for part to this) to not raise any exceptions (because its not normally a use case for try-catch)and also get faster results:
for (int i = 9; i >= 0; i--)
{
if (i < filtredList.Count)
{
if (filtredList[i].Length != 10)
{
Console.Write(filtredList[i]);
row = 10 - filtredList[i].Length;
Console.WriteLine(new string('+', row));
}
else Console.WriteLine(filtredList[i]);
}
else
{
row = 10;
Console.WriteLine(new string('+', row));
}
}

How to shrink int array basing on the number of elements?

So let's say I have a base int[] tab array with 100 elements. I want to perform Erastotenes' Sieve using tmp array storing not compatibile elements. Since I don't know exactly how many elements will land in this array, I declare it as new int[100]. But is there any way to shrink that array after performing population task? Like for example, I end up with 46 numbers instead of 100, so I'd like to shrink that array's size accordingly, based on the number of said elements. I'd like to avoid manual resize, I'd rather do it programatically.
Sample code:
int[] tab = new int[100];
int[] tmp = new int[100];
for(int i = 0; i < tab.Length; i++) {
tab[i] = i;
}
EDIT. One idea that came to my mind is to perform while loop strictly counting amount of elements in tmp array which could help me determine its final size.
EDIT 2. Working solution:
int[] tab = new int[100];
List<int> tmp = new List<int>();
List<int> se = new List<int>();
for(int i = 0; i < tab.Length; i++)
{
tab[i] = i + 2;
}
se.Add(tab[0]);
se.Add(tab[1]);
for (int i = 2; i < tab.Length; i++)
{
if (tab[i] % 2 == 0 || tab[i] % 3 == 0)
{
if (tmp.IndexOf(tab[i]) == -1)
{
tmp.Add(tab[i]);
}
}
}
int k = 3;
int value;
while(k < tab.Length)
{
if(tmp.IndexOf(tab[k]) == -1) {
value = tab[k];
for (int i = k; i < tab.Length; i++)
{
if(tmp.IndexOf(tab[i]) == -1)
{
if(tab[i] % value == 0 && tab[i] != value)
{
tmp.Add(tab[i]);
}
else
{
if(se.IndexOf(tab[i]) == -1)
{
se.Add(tab[i]);
}
}
}
}
}
k++;
}
Console.WriteLine("Zawartość tablicy początkowej:");
for(int i = 0; i < tab.Length; i++)
{
Console.Write(tab[i] + " ");
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Elementy wykluczone:");
foreach(int t in tmp)
{
Console.Write(t + " ");
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Sito Erastotenesa:");
foreach (int s in se)
{
Console.Write(s + " ");
}
Console.WriteLine();
Console.WriteLine();
No, you can't shrink an array (or grow, for that matter). You can create a new array with the correct size and copy the data to the new one, but an array, once created, can not change size.
The easiest way to achieve this is using List<T> which is nothing more than a thin wrapper over an array that hides away all the plumbing of how and when the underlying array needs to grow and copying data from the "depleted" to the newer array.
Once you've populated the list, if you need an array then simply call ToArray().
public static void Resize<T> (ref T[]? array, int newSize);
This method allocates a new array with the specified size, copies elements from the old array to the new one, and then replace the old array with the new one. the array must be a one-dimensional array.
Changes the number of elements of a one-dimensional array to the specified new size.
You can read the full article here

fill array with random but unique numbers in C# [duplicate]

This question already has answers here:
Generate N random and unique numbers within a range
(7 answers)
Best way to randomize an array with .NET
(19 answers)
Closed 6 years ago.
Okay I know there are few posts like this but I need to use only loops (for,do,while) and if, else to fill array with random but unique numbers so how shall i edit this code
int[] x = new int[10];
Random r = new Random();
int i;
for (i = 0; i < x.Length; i++) {
x[i] = r.Next(10);
Console.WriteLine("x[{0}] = {1}", i, x[i]);
}
You could check if the newly generated number already exists in the array, if not then add it to the array, if yes then generate a new one.
For examle:
class Program
{
static void Main(string[] args)
{
int[] x = new int[10];
Random r = new Random();
int i;
for (i = 0; i < x.Length; i++)
{
var next = 0;
while (true)
{
next = r.Next(10);
if (!Contains(x, next)) break;
}
x[i] = next;
Console.WriteLine("x[{0}] = {1}", i, x[i]);
}
Console.ReadLine();
}
static bool Contains(int[] array, int value)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] == value) return true;
}
return false;
}
}
Without checking that generated number is already presented in array you can't to solve this task.
So you must generate new number and before inserting it into array check for uniq.

Finding the sum of the values in a 2D Array in C#

Trying to build a method that will find the sum of all the values within the 2D array. I'm very new to programming and can't find a good starting point on trying to figure out how its done. Here is what I have so far (forgive me, I'm usually an english/history guy, logic isn't my forte...)
class Program
{
static void Main(string[] args)
{
int[,] myArray = new int[5,6];
FillArray(myArray);
LargestValue(myArray);
}
//Fills the array with random values 1-15
public static void FillArray(int[,] array)
{
Random rnd = new Random();
int[,] tempArray = new int[,] { };
for (int i = 0; i < tempArray.GetLength(0); i++)
{
for (int j = 0; j < tempArray.GetLength(1); j++)
{
tempArray[i, j] = rnd.Next(1, 16);
}
}
}
//finds the largest value in the array (using an IEnumerator someone
//showed me, but I'm a little fuzzy on how it works...)
public static void LargestValue(int[,] array)
{
FillArray(array);
IEnumerable<int> allValues = array.Cast<int>();
int max = allValues.Max();
Console.WriteLine("Max value: " + max);
}
//finds the sum of all values
public int SumArray(int[,] array)
{
FillArray(array);
}
}
I guess I could try to find the sum of each row or column and add them up with a for loop? Add them up and return an int? If anyone could shed any insight, it would be greatly appreciated, thanks!
Firstly, you don't need to call FillArray in the beginning of each method, you have already populated the array in the main method, you are passing a populated array to these other methods.
A loop similar to what you use to populate the array is the easiest to understand:
//finds the sum of all values
public int SumArray(int[,] array)
{
int total = 0;
// Iterate through the first dimension of the array
for (int i = 0; i < array.GetLength(0); i++)
{
// Iterate through the second dimension
for (int j = 0; j < array.GetLength(1); j++)
{
// Add the value at this location to the total
// (+= is shorthand for saying total = total + <something>)
total += array[i, j];
}
}
return total;
}
To sum an array if you know the length is easy
As a bonus code included to get the highest valeu too.
You could easily expand this to get other kinds of statistical code.
I asume below Xlength and Ylength are integers too, and known by you.
You could also replace them by a number in the code.
int total = 0;
int max=0;
int t=0; // temp valeu
For (int x=0;x<Xlength;x++)
{
for (int y=0;y<Ylength;y++)
{
t = yourArray[x,y];
total =total +t;
if(t>max){max=t;} // an if on a single line
}
}
here is a link with an MSDN sample on how to retrieve unknown array lengths.
and there is a nice site to have around when you start in c#
google ".net perls"

A logic issue regarding a very simple solution that performs the factorizing function

This solution factorizes a number (numInput), it works perfectly well except for a logic error I can't seem to find no matter how much I track the solution. The logic error causes the returned result to be 0 no matter the value initialized for numInput.
using System;
namespace factorizer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(factorialise());
Console.ReadKey();
}
private static int factorialise()
{
int numInput = int.Parse(Console.ReadLine());
int[] number = new int[numInput];
for (int i = 1; i < numInput; i++) //stores the (n-1)...(n-i) value for the number input'd in the array number[i]
{
number[i - 1] = numInput - i; //the element indicating the index number is 'i - 1' index values start from zero
}
for (int index = 0; index < number.Length; index++) //multiplies the element corresponding the index number with the number input'd
{
numInput = numInput * number[index];
}
return numInput;
}
}
}
Your last item in array stays uninitialized (i.e. equal to zero). Change items count:
int[] number = new int[numInput-1];
Also why not simply use for loop?
int result = 1;
for(int i = 1; i <= numInput; i++)
result *= i;
And another sample just for fun
Enumerable.Range(1, numInput).Aggregate(1, (a,i) => a * i)

Categories