Sort by selection in C# - c#

I am a complete beginner in programming. Trying to make sorting a choice. Everything seems to be ok. Only there is one caveat. Only numbers up to 24 index are filled in the new array. I can’t understand what the problem is.
int[] Fillin(int[] mass)
{
Random r = new Random();
for(int i = 0; i < mass.Length; i++)
{
mass[i] = r.Next(1, 101);
}
return mass;
}
int SearchSmall(int[] mass)
{
int smallest = mass[0];
int small_index = 0;
for(int i = 1; i < mass.Length; i++)
{
if (mass[i] < smallest)
{
smallest = mass[i];
small_index = i;
}
}
return small_index;
}
int[] Remove(int[] massiv,int remind)
{
List<int> tmp = new List<int>(massiv);
tmp.RemoveAt(remind);
massiv = tmp.ToArray();
return massiv;
}
public int[] SortMass(int[] mass)
{
mass = Fillin(mass);
Print(mass);
Console.WriteLine("________________________________");
int[] newmass = new int[mass.Length];
int small;
for(int i = 0; i < mass.Length; i++)
{
small = SearchSmall(mass);
newmass[i] = mass[small];
mass = Remove(mass, small);
}
return newmass;
}

I think your main issue is that when you remove an element in the Remove function, the main loop in for (int i = 0; i < mass.Length; i++) will not check all elements o the initial array. A simple (and ugly) way to fix that would be not to remove the elements but to assign a very high value
public static int[] Remove(int[] massiv, int remind)
{
massiv[remind] = 999999;
return massiv;
}
Or as Legacy suggested simply modify the mass.length for newmass.lengh in the main loop.
As some others have mentioned this is not the best way to order an array, but it is an interesting exercise.

Related

Creating an array of 10 elements and assigning them by counting randomly

Creating an array of 10 elements and assigning them by counting randomly, assigning a new number if the same numbers are repeated
I tried to use the contains method but it didn't appear in the list after the array, I used the exists method but it didn't work either, what kind of way should I follow? thanks
static void Main(string[] args)
{
Random Rnd = new Random();
int[] Numbers = new int[10];
for (int i = 0; i < Numbers.Length; i++)
{
int rast = Rnd.Next(10);
bool b = Array.Exists(Numbers, element => element == rast);
if (!b)
{
i--;
}
else { Numbers[i] = rast; }
}
foreach (int item in Numbers)
{
Console.WriteLine(item);
}
}
It appears that you want the numbers from 0 to 9 in an array in random order. If that is so:
var rng = new Random();
var numbers = Enumerable.Range(0, 10).OrderBy(n => rng.NextDouble()).ToArray();
You're close, but there are two issues in your algorithm:
if (!b) should be if (b)
Rnd.Next(1,10) gets numbers between 1 and 9 so you will never get a 10 and the algorithm will never finish.
After fixing these two your program will work.
Anyway, here's a version that uses .Contains
Random Rnd = new Random();
int[] Numbers = new int[10];
for (int i = 0; i < Numbers.Length; i++)
{
// + 1 because the range of return values includes minValue but not maxValue.
int r = Rnd.Next(minValue: 1, maxValue: Numbers.Length + 1);
while(Numbers.Contains(r))
{
r = Rnd.Next(minValue: 1, maxValue: Numbers.Length + 1);
}
Numbers[i] = r;
}
Console.WriteLine(string.Join(",", Numbers));
Example output:
9,8,7,1,4,6,3,10,5,2
Here's an example. I hope this is the output you want.
public static void Main()
{
Random Rnd = new Random();
int[] Numbers = new int[10];
for (int i = 0; i < Numbers.Length; i++)
{
int rast = Rnd.Next(10);
bool b = Array.Exists(Numbers, element => element == rast);
if (!b)
{
Numbers[i] = rast;
Console.WriteLine(rast);
}
else {
i--;
}
}
}
As a result, I have found the solution, thanks to everyone who answered and showed me the way
int[] Numbers = new int[10];
int x, y;
Random ran = new Random();
for (x = 0; x < 10; x++)
{
Numbers[x] = ran.Next(1, 10);
for (y = x; y >= 0; y--)
{
if (x == y)
{
continue;
}
if (Numbers[x] == Numbers[y])
{
Numbers[x] = ran.Next(1, 10);
y = x;
}
}
Console.WriteLine(Numbers[x]);
}
when i created new project as Console .net in visual studio 2019 ,
it doesnt bring this libraries automatically ,
Because the following libraries are not attached, the codings I used before did not work, I developed another simple solution, and in this way, I realized that I had a problem due to these libraries not being attached.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
int[] Numbers= new int[10];
Random rnd = new Random();
for (int i = 0; i < Numbers.Length; i++)
{
int Num= rnd.Next(10);
if (Numbers.Contains(Num))
{
i--;
}
else
{
Console.WriteLine(Numbers[i] = Num);
}
}

How can I fill array with unique random numbers with for-loop&if-statement?

I'm trying to fill one dimensional array with random BUT unique numbers (No single number should be same). As I guess I have a logical error in second for loop, but can't get it right.
P.S I'm not looking for a more "complex" solution - all I know at is this time is while,for,if.
P.P.S I know that it's a really beginner's problem and feel sorry for this kind of question.
int[] x = new int[10];
for (int i = 0; i < x.Length; i++)
{
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) break;
}
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i);
}
Here is a solution with your code.
int[] x = new int[10];
for (int i = 0; i < x.Length;)
{
bool stop = false;
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) {
stop = true;
break;
}
}
if (!stop)
i++;
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
A simple trace of the posted code reveals some of the issues. To be specific, on the line…
if (x[i] == x[j]) break;
if the random number is “already” in the array, then simply breaking out of the j loop is going to SKIP the current i value into the x array. This means that whenever a duplicate is found, x[i] is going to be 0 (zero) the default value, then skipped.
The outer i loop is obviously looping through the x int array, this is pretty clear and looks ok. However, the second inner loop can’t really be a for loop… and here’s why… basically you need to find a random int, then loop through the existing ints to see if it already exists. Given this, in theory you could grab the same random number “many” times over before getting a unique one. Therefore, in this scenario… you really have NO idea how many times you will loop around before you find this unique number.
With that said, it may help to “break” your problem down. I am guessing a “method” that returns a “unique” int compared to the existing ints in the x array, may come in handy. Create an endless while loop, inside this loop, we would grab a random number, then loop through the “existing” ints. If the random number is not a duplicate, then we can simply return this value. This is all this method does and it may look something like below.
private static int GetNextInt(Random r, int[] x, int numberOfRandsFound) {
int currentRand;
bool itemAlreadyExist = false;
while (true) {
currentRand = r.Next(RandomNumberSize);
itemAlreadyExist = false;
for (int i = 0; i < numberOfRandsFound; i++) {
if (x[i] == currentRand) {
itemAlreadyExist = true;
break;
}
}
if (!itemAlreadyExist) {
return currentRand;
}
}
}
NOTE: Here would be a good time to describe a possible endless loop in this code…
Currently, the random numbers and the size of the array are the same, however, if the array size is “larger” than the random number spread, then the code above will NEVER exit. Example, if the current x array is set to size 11 and the random numbers is left at 10, then you will never be able to set the x[10] item since ALL possible random numbers are already used. I hope that makes sense.
Once we have the method above… the rest should be fairly straight forward.
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
int numberOfRandsFound = 0;
int[] ArrayOfInts = new int[DataSize];
int currentRand;
for (int i = 0; i < ArrayOfInts.Length; i++) {
currentRand = GetNextInt(random, ArrayOfInts, numberOfRandsFound);
ArrayOfInts[i] = currentRand;
numberOfRandsFound++;
}
for (int i = 0; i < ArrayOfInts.Length; i++) {
Console.WriteLine(ArrayOfInts[i]);
}
Console.ReadKey();
}
Lastly as other have mentioned, this is much easier with a List<int>…
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
List<int> listOfInts = new List<int>();
bool stillWorking = true;
int currentRand;
while (stillWorking) {
currentRand = random.Next(RandomNumberSize);
if (!listOfInts.Contains(currentRand)) {
listOfInts.Add(currentRand);
if (listOfInts.Count == DataSize)
stillWorking = false;
}
}
for (int i = 0; i < listOfInts.Count; i++) {
Console.WriteLine(i + " - " + listOfInts[i]);
}
Console.ReadKey();
}
Hope this helps ;-)
The typical solution is to generate the entire potential set in sequence (in this case an array with values from 0 to 9). Then shuffle the sequence.
private static Random rng = new Random();
public static void Shuffle(int[] items)
{
int n = list.Length;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
int temp = items[k];
items[k] = items[n];
items[n] = temp;
}
}
static void Main(string[] args)
{
int[] x = new int[10];
for(int i = 0; i<x.Length; i++)
{
x[i] = i;
}
Shuffle(x);
for(int i = 0; i < x.Length; i++)
{
Console.WritLine(x[i]);
}
}
//alternate version of Main()
static void Main(string[] args)
{
var x = Enumerable.Range(0,10).ToArray();
Shuffle(x);
Console.WriteLine(String.Join("\n", x));
}
You can simply do this:
private void AddUniqueNumber()
{
Random r = new Random();
List<int> uniqueList = new List<int>();
int num = 0, count = 10;
for (int i = 0; i < count; i++)
{
num = r.Next(count);
if (!uniqueList.Contains(num))
uniqueList.Add(num);
}
}
Or:
int[] x = new int[10];
Random r1 = new Random();
int num = 0;
for (int i = 0; i < x.Length; i++)
{
num = r1.Next(10);
x[num] = num;
}

Function returning the highest value in an array

I am still having slight troubles with functions and arrays. I have created an array that has been filled with random numbers. I am trying to create a function that sets up the array and returns the highest value. I am not to sure on how to approach this but this and what I have written so far has not been able to compile.
namespace Task_1._13
{
class Program
{
static void Main(string[] args)
{
gettingMaximum(int i);
}
public int gettingMaximum(int i);
{
int maximum = 0;
int[] myArray = new int[10];
Random rand = new Random();
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = rand.Next(19);
}
for (int i = 0; i < 10; i++)
{
if (i == 0)
maximum = myArray[i];
else
if (myArray[i] < maximum) maximum = myArray[i];
int result = i;
return result;
}
}
}
}
That's what I have gotten so far. I am not very experienced in programming so help would be appreciated.
for (int i = 0; i < myArray.Length; i++)
{
if(myArray[i] > maximum)
{
maximum = myArray[i];
}
}
return maximum;
OR you can just use the Max function like this
return myArray.Max();
If you want to return the largest value, you can use System.Linq and use the Max function.
int largestValue = myArray.Max();
Enunerable.Max Method
public int gettingMaximum();
{
int maximum = 0;
int[] myArray = new int[10];
Random rand = new Random();
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = rand.Next(19);
}
for (int i = 0; i < myArray.Length; i++)
{
if (i == 0)
maximum = myArray[i];
else
if (myArray[i] > maximum) maximum = myArray[i];
}
return maximum;
}
This should work.
Updated w/ comments
namespace Task_1._13
{
class Program
{
static void Main(string[] args)
{
// gettingMaximum(int i); This won't work because the int can't be declared while it's being passed into the method
int i = 0; // You need to declare the i before you pass it to a method. Although look closely at your method and the reason you are passing in a value. Do you need it or use it?
Console.WriteLine(gettingMaximum(i)); // I'm outputting the results to the screen so that you can verify that at least something happened
}
public static int gettingMaximum(int z)//; You don't need the semicolon here
// Also, I renamed this to z to demonstrate that you never use it. You could just as easily remove it
// Also, this method must be marked static which is outside the scope of this question
{
int maximum = 0;
int[] myArray = new int[10];
Random rand = new Random();
// This looks good. You create the array and loop through the items and set the value
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = rand.Next(19);
}
// This code counts to 10. During each step, it compares the current step with 0.
// If the step (i) is 0, you set the maximum to to that value.
// Otherwise, you see if the array value at that step is LESS than the current maximum, and if it is
// you set the maximum to be that value.
//for (int i = 0; i < 10; i++)
//{
// if (i == 0)
// maximum = myArray[i];
// else
// if (myArray[i] < maximum) maximum = myArray[i];
// int result = i; // Here, you're actually setting the result to the current step number
// return result; // I think you meant to set it to maximum, but you can leave it out completely and just return maximum.
//}
for (int i = 0; i < 10; i++)
{
if (i == 0)
{
maximum = myArray[i];
}
else
{ // Since you have nested if's, i'm using braces to illustrate the paths of the branches
if (myArray[i] > maximum) // What i think you mean is, is the value at this item in the array MORE than my current maximum
{
maximum = myArray[i];
}
}
}
return maximum;
}
}
}

Convert a C# jagged array to an array and back again

I currently have a jagged array Class[][][] which I want to serialise as a normal Class[] array, then convert back into a Class[][][] array after deserialization. Is it at all possible to convert between the two both ways? The dimensions are of constant sizes.
This is how you can flatten to a 1-dimensional structure:
var jagged = new object[][][];
var flattened = jagged.SelectMany(inner => inner.SelectMany(innerInner => innerInner)).ToArray();
As for going back to multidimensional - this will depend entirely on what it is your trying to achieve/what the data represents
If you don't mind serializing a flattened array and an array of ints, you can use the following:
public static int[] JaggedSizes<T>(this T[][][] topArray)
{
List<int> rtn = new List<int>();
rtn.Add(topArray.Length);
for (int i = 0; i < topArray.Length; i++)
{
var midArray = topArray[i];
rtn.Add(midArray.Length);
for (int j = 0; j < midArray.Length; j++)
{
var botArray = midArray[j];
rtn.Add(botArray.Length);
}
}
return rtn.ToArray();
}
// Thanks #Dave Bish
public static T[] ToFlat<T>(this T[][][] jagged)
{
return jagged.SelectMany(inner =>
inner.SelectMany(innerInner => innerInner)).ToArray();
}
public static T[][][] FromFlatWithSizes<T>(this T[] flat, int[] sizes)
{
int inPtr = 0;
int sPtr = 0;
int topSize = sizes[sPtr++];
T[][][] rtn = new T[topSize][][];
for (int i = 0; i < topSize; i++)
{
int midSize = sizes[sPtr++];
T[][] mid = new T[midSize][];
rtn[i] = mid;
for (int j = 0; j < midSize; j++)
{
int botSize = sizes[sPtr++];
T[] bot = new T[botSize];
mid[j] = bot;
for (int k = 0; k < botSize; k++)
{
bot[k] = flat[inPtr++];
}
}
}
return rtn;
}
I don't think so Rory.
You may have been able to do this if it is a Class[,,] multidimensional array, but the fact that each array could be of different length is going to always be a stumbling block.
Assuming you serialize if as a Class[] + another class to give you the original dimensions, you'll be golden.

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