I'd like some help in getting this program to work. The user must first input upper and lower bounds for the int[] array. Next, they input what numbers to exclude from said array and display. I'm having trouble getting/understanding how to remove these numbers. Any help would be greatly appreciated. Thank you
Code:
Console.WriteLine("Please enter the first integer for the lower bound now");
int lower = int.Parse(Console.ReadLine()); //Uses user input for lower array bound
Console.WriteLine("Now enter the second integer for the upper bound");
int upper = int.Parse(Console.ReadLine()); //Uses user input for upper array bound
Console.WriteLine("Finally, enter the integers you do not want to see in the range");
int[] exNums = new int[] {int.Parse(Console.ReadLine()) }; //User enters number to exclude from range
int[] numbers = Enumerable.Range(lower, upper).ToArray();
Random r = new Random();
int range = 0;
try
{
for (int i = 0; i < 50; i++)
{
range = r.Next(lower, upper);
Console.Write(range + ",");
}
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine("Upper bound cannot be lower than lower bound");
}
try
{
...
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine("Upper bound cannot be lower than lower bound");
}
Alright. Please, PLEASE don't write code like this. Rather than searching for an exception, check the values yourself.
if (upper < lower)
{
Console.WriteLine("Upper bound cannot be lower than lower bound");
return;
}
Let's correctly generate the IEnumerable<int> of numbers to start with. Enumerable.Range takes a starting number and an entry count, not the upper bounds.
IEnumerable<int> allNumbers = Enumerable.Range(lower, (upper - lower) + 1);
Assuming we have a collection of numbers to exclude:
int[] numbersToExclude = ...;
We can simply use the .Except() method of LINQ to take out what we don't want.
IEnumerable<int> filteredNumbers = allNumbers.Except(numbersToExclude);
.ToArray(), .ToList(), or foreach the results of filteredNumbers as you wish afterwards.
Just in case there is so miscommunication from the question title, "Removing integers from int[] array", you cannot remove entries from a c# array. Once you set the size of an array (the number of items that array can hold) you cannot change it.
The only way to add and remove items from an array is to create an entirely new array and copy over the elements you want to keep.
There are, however, different data structures that can add and remove entries without all this data management on your end, most popular is List<>.
Maybe there's some reason you need to use Arrays rather than Lists but why not something like... (Java example)
int[] answers = new int[upper];
int index=0;
for (int lower; lower<=upper; lower++){
// if current value is within excluded numbers array, skip
if (Arrays.binarySearch(excludes, lower) >= 0){
continue;
}
else{
//add to the answers array
answers[index] = lower;
index++;
}
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am new to programming. C# is my first programming language.
I have an assignment where I have to create and test out a bubble sort algorithm and a selection sort algorithm using arrays. I think I understand those now.
The next part of the assignment I am having some trouble on.
I have to write a program that will ask the user for a number (n) and create 1000 arrays of n size.
So if the user enters 5 for the number, my program has to create and sort 1000 arrays that are of length 5.
I have to use the bubble sort and the selection sort methods I created.
After I do that, I have to initiate a variable called running_time to 0. I have to create a for loop that iterates 1000 times and in the body of the loop i have to create an array of n random integers.
Then I have to get the time and set this to the start time. My professor said to notice that the sort is started after each array is built, so I should time the sort process only.
Then I have to get the time and set it to end time. I have to subtract the start time from end time and add the result to the total time.
Once the program has run, note
1. the number of items sorted
2. the average running time for each array (total time/1000)
Then I have to repeat the process using 500, 2500, and 5000 as the size of the array.
This is my code for creating one array with n number of spaces and filled with random integers.
//Asks the user for number
Console.WriteLine("Enter a number: ");
n = Convert.ToInt32(Console.ReadLine());
//Creates an array of the length of the user entered number
int[] randArray = new int[n];
//Brings in the random class so we can use it.
Random r = new Random();
Console.WriteLine("This is the array: ");
//For loop that will put in a random number for each spot in the array.
for (int i = 0; i < randArray.Length; i++) {
randArray[i] = r.Next(n);
Console.Write(randArray[i] + " ");
}
Console.WriteLine();
THIS IS MY CODE FOR THE BUBBLE SORT ALGORITHM:
//Now performing bubble sort algorithm:
for (int j = 0; j <= randArray.Length - 2; j++) {
for (int x = 0; x <= randArray.Length - 2; x++) {
if (randArray[x] > randArray[x + 1]) {
temp = randArray[x + 1];
randArray[x + 1] = randArray[x];
randArray[x] = temp;
}
}
}
//For each loop that will print out the sorted array
foreach (int array in randArray) {
Console.Write(array + " ");
}
Console.WriteLine();
THIS IS MY CODE FOR THE SELECTION SORT ALGORITHM:
//Now performing selection sort algorithm
for (int a = 0; a < randArray1.Length - 1; a++) {
minkey = a;
for (int b = a + 1; b < randArray1.Length; b++) {
if (randArray1[b] < randArray1[minkey]) {
minkey = b;
}
}
tempSS = randArray1[minkey];
randArray1[minkey] = randArray1[a];
randArray1[a] = tempSS;
}
//For loop that will print the array after it is sorted.
Console.WriteLine("This is the array after the selection sort algorithm.");
for (int c = 0; c < randArray1.Length; c++) {
Console.Write(randArray1[c] + " ");
}
Console.WriteLine();
This is very overwhelming as I am new to this and I am still learning this language.
Can someone guide me on the beginning on how to create 1000 different arrays filled with random numbers and then the rest. I would appreciate it greatly. Thank you.
So you have a several questions that has overwhelmed you.
Let's look at each one
Take user input
Console.WriteLine("Enter a length");
while (!int.TryParse(Console.ReadLine(), out var length))
Console.WriteLine("omg! you had one job");
Calling a method with an out argument
Starting with C# 7.0, you can declare the out variable in the argument
list of the method call, rather than in a separate variable
declaration. This produces more compact, readable code, and also
prevents you from inadvertently assigning a value to the variable
before the method call. The following example is like the previous
example, except that it defines the number variable in the call to the
Int32.TryParse method.
Fill Array
private static Random _rand = new Random();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
...
public static string RandomString(int length)
{
var result = Enumerable.Range(0, length)
.Select(s => chars[_rand.Next(length)])
.ToArray();
return new string(result);
}
Create array of random chars
var arr = Enumerable.Range(0, size)
.Select(i => RandomString(length)).ToArray();
How to time something
var sw = Stopwatch.StartNew();
// something to time
var milliseconds = sw.ElapsedMilliseconds
Now map it all together, I'll leave these details up to you
Additional Resources
Enumerable.Range(Int32, Int32) Method
Generates a sequence of integral numbers within a specified range.
Enumerable.Select Method
Projects each element of a sequence into a new form.
Stopwatch Class
Provides a set of methods and properties that you can use to
accurately measure elapsed time.
Random Class
Represents a pseudo-random number generator, which is a device that
produces a sequence of numbers that meet certain statistical
requirements for randomness.
So this is my code right now, and I need help so it won't makes duplicates. I need this for school so if you could explain a little bit too it would be helpful. Btw don't care about the comments it's on Swedish
int temp;
int[] myArray = new int[20]; // Array med 20 tal
Random random = new Random(); // Skapar metoden "Random"
for (int i = 0; i < myArray.Length; i++) // Forloop med 20 positioner
{
myArray[i] = random.Next(1, 100); // Ger random värden till dessa 20 positionerna
for (int j = 0; j < myArray.Length; j++)
{
if (myArray[i] > myArray[j]) // Array [i] större än Array [j]
{
//temp = myArray[j];
//myArray[j] = myArray[i];
//myArray[i] = temp;
}
}
Console.Write(myArray[i] + " ");
}
you can try linq to .Distinct() and to convert it to array use .ToArray()
var s = { 5, 7, 7, 4, 3};
var q = s.Distinct().ToArray();
At it's simplest, it looks like you probably want to
private static Random rng = new Random(); //class level definition
var myArray = Enumerable.Range(1, 20).OrderBy(X => rng.Next()).ToArray();
Alternatively, if this is for school and you need to justify your code... fill an array with the numbers 1 to 20, then use a Fisher-Yates shuffle to randomise the order of the array.
See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Since the array has exatly the size of the random value range (which is 20), you will get every number exactly once. It's easiest to create every number once using Enumerable.Range and only change the order in which they appear.
Changing the order can be done by OrderBy(), while random is used here.
This is all based on IEnumerable<T>. So it needs to be put into an array, which is simply done by calling ToArray().
public int[] RandomlyOrderedValues()
{
Random random = new Random();
return Enumerable.Range(1, 20).OrderBy(x => random.Next()).ToArray();
}
I'm not your teacher but hope you still play around by yourself, read the docs and finally express it in your own words.
Changed question, now the random range is larger than the array size.
It's always best to work with IEnumerable<T>, there you get the most powerful tools.
// let's create inifite number of random values:
// note that the Random instance needs to be created only once,
// so it's put into a field.
private Random random = new Random();
public IEnumerable<int> InfiniteRandomValues()
{
while (true)
{
yield return random.Next(1, 100);
}
}
public int[] GetUniqueRandomValues(int numberOfValues)
{
return InfiniteRandomValues()
// only uninque values
.Distinct()
// generate the requested number of distinct values
.Take(numberOfValues)
// put it into an array.
.ToArray();
}
How does it work? When you create random values, you don't know how many it will be, because you cannot know how many duplicates it will create. A generator for an infinite number of values has certainly enough values. Think of it as a factory. Only when the IEnumerable is iterated, the values are created.
This is called "deferred execution". Only when you iterate the IEnumerable, the values are requested by the source.
Distinct works like this. It returns only as many distinct values as are requested by its caller.
Which is Take. This one reduces the number of items that are taken, but still doesn't iterate itselves.
ToArray finally iterates its source and pulls as many values as there are. Read it backwards now: It takes all values from Take, which returns 20. Itselves it takes 20 values from Distinct, which iterates its source until it got 20 distinct values. Distinct takes its values from the InifiteRandomNumbers factory and can take as many as it needs.
When you finally understand how these things work, you can use it quite intuitively.
Another, more classic implemenation
private int[] GetRandomValues()
{
Random random = new Random();
int[] values = new int[20];
for(int i = 0; i < 20; i++)
{
// create random values until you found a distinct oune.
int nextValue;
do
{
nextValue = random.Next(1, 100);
} while (ContainsValue(values, i, nextValue))
values[i] = nextValue;
}
return values;
}
// When adding the values to a List instead of an array, it would be
// much easier, but need copying the vlaues to the array at the end.
// When using the array directly, you have to know which values you
// already generated, because it's initialized with zero.
// This method checks wether the value is in the array within
// the items until endIndex.
private bool ContainsValue(int[] values, int endIndex, int valueToFind)
{
// simple linq way:
// return values.Take(endIndex).Contains(valueToFind);
// classic way:
for(int i = 0; i < endIndex; i++)
{
if (values[i] = valueToFind) return true;
}
return false;
}
I'm working on a football league fixture project on C# Console Application.
I'm trying to choose random teams from the array which contains the teams which plays at their home and away.
When I'm trying to generate 9 random numbers, only 8 numbers are generated and 0 are not, so the code can't break the for loop.
I suppose that the problem is that the if statement does not allow to generate the same number and int array's elements' default value is 0.
Here is the code and the output:
C# Code Output
int randomHome; //Random number genetator for choosing a random iteration value from home array which containss the teams which plays at their home
int randomAway; //Random number genetator for choosing a random iteration value from awayarray which containss the teams which plays at away
Random randomNum = new Random();
int[] randomHomeNumArray = new int[home.Length]; //array will hold the randomHome values and home array is the array which is holding the team's iteration values which plays at their home
int[] randomAwayNumArray = new int[away.Length]; //array will hold the randomAway values and away array is the array which is holding the team's iteration values which plays at away
for (int homeArrayCounter = 0; homeArrayCounter < randomHomeNumArray.Length; homeArrayCounter++)
{
randomHome = randomNum.Next(home.Length)
if (!randomHomeNumArray.Contains(randomHome) )
{
randomHomeNumArray[homeArrayCounter] = randomHome; //It will hold the randomHome values
Console.WriteLine(homeArrayCounter + ". iterasyon in Home " + randomHomeNumArray[homeArrayCounter]);
}
else
{
homeArrayCounter--;
}
}
Console.WriteLine("\n\n");
for (int awayArrayCounter = 0; awayArrayCounter < randomAwayNumArray.Length; awayArrayCounter++)
{
randomAway = randomNum.Next(randomAwayNumArray.Length);
if (!randomAwayNumArray.Contains(randomAway))
{
randomAwayNumArray[awayArrayCounter] = randomAway; //It holds the random valures from away array which contains the teams which plays at away
Console.WriteLine(awayArrayCounter + ". iterasyon in Away " + randomAwayNumArray[awayArrayCounter]);
}
else
{
awayArrayCounter--;
}
}
When you initalize an array, it has the value 0 by default for each index. When you are using the random number, it always skips 0 because it already exists.
You can try like this:-
for(int i= 0; i<randomHomeNumArray.Length; i++){
randomHomeNumArray[i] = -1;
}
for (int homeArrayCounter = 0; homeArrayCounter < randomHomeNumArray.Length; homeArrayCounter++)
{
do{
randomHome = randomNum.Next(home.Length);
} while(!randomHomeNumArray.Contains(randomHome));
randomHomeNumArray[homeArrayCounter] = randomHome; //It will hold the randomHome values
Console.WriteLine(homeArrayCounter + ". iterasyon in Home " + randomHomeNumArray[homeArrayCounter]);
}
It appears you're trying to just randomize arrays.
Try this instead:
Random randomNum = new Random();
int[] randomHomeNumArray = Enumerable.Range(0, home.Length).OrderBy(_ => randomNum.Next()).ToArray();
int[] randomAwayNumArray = Enumerable.Range(0, away.Length).OrderBy(_ => randomNum.Next()).ToArray();
That's it. Done.
Your problem is the default initialization of your arrays:
int[] randomHomeNumArray = new int[home.Length];
This creates an array filled with 0s, because 0 is the default value for int.
So your if condition
if (!randomHomeNumArray.Contains(randomHome))
is always false for 0 because 0 is already contained in the array.
You may initialize your arrays instead like this:
int[] randomHomeNumArray = Enumerable.Repeat(-1, home.Length).ToArray();
So you fill it with -1 instead of 0 and your if condition works.
Because int is not a null-able data type, by default, an int[] gets initialized with zeroes. So even if you think it's an empty array, it's actually an array with all elements set to zero.
To rectify the problem, you can consider using an int?[] (null-able int array) instead. Or, you can initialize the array with either a negative integer or some integer greater than the maximum inclusive upper bound. Better yet, to achieve what you want, in a better way, use the solution provided by #Enigmativity, and mark his answer accepted, if it helped.
I am facing a very difficult situation, suppose I have a array of dynamic numbers. The condition is the array may contain 10 numbers to 20 numbers. It can contain 10, 12, 14, ... to 20 integers. Now based on the ArrayList.Count(), I am going to choose 3(if array contains 10 integers) to 6 (if array contain 20 integers) numbers out of this array, and add those numbers. say that number is "X".
Now I have to check if there exist any three integers in the list whose sum is equal to X, if its equal, then again I have to repeat the same procedure until I find a unique sum from the list.
So how can I do it? The best part is all the numbers in the array is unique, there is no repeat of the numbers in the array.
First Idea
I though of one idea, for 3 numbers, Suppose I generate a unique number.
foreach (var i in List) // values of i = 1, 5, 8 (Assume)
{
sum += listOfUniqueIntegers[i];
}
// Fix the first element as List[i]
for (int i = 0; i < List.Count()-2; i++)
{
// Fix the second element as List[j]
for (int j = i+1; j < List.Count()-1; j++)
{
// Now look for the third number
for (int k = j+1; k < List.Count(); k++)
{
if (List[i] + List[j] + List[k] == sum)
{
// Here I will again create one more unique value
// and assign it to sum and repeat i = 0, j = 0, k = 0;
}
}
}
}
But the problem with this approach is its time complexity os n^3 so if I have to generate a sum from 6 numbers when List size is 20, it will be n^6, which is not expected.
Second idea
I though I can sort the List, but then what logic shall I use to choose 3 integers so that it's sum is unique in the List.
Lets say I sort the list and choose three smallest number or choose from the sorted list 3rd 3+1=4 th and 3+2=5th element, and sum=List[3]+List[4]+List[5];
this is also not expected, any pattern to choose three numbers is not suggested. It should be randomly chosen and the sum should be unique.
So I am not getting any idea to generate a optimal solution for this.
Can anybody please help me.
Just use the 3 largest numbers.
I have an array of boolean values and need to randomly select a specific quantity of indices for values which are true.
What is the most efficient way to generate the array of indices?
For instance,
BitArray mask = GenerateSomeMask(length: 100000);
int[] randomIndices = RandomIndicesForTrue(mask, quantity: 10);
In this case the length of randomIndices would be 10.
There's a faster way to do this that requires only a single scan of the list.
Consider picking a line at random from a text file when you don't know how many lines are in the file, and the file is too large to fit in memory. The obvious solution is to read the file once to count the lines, pick a random number in the range of 0 to Count-1, and then read the file again up to the chosen line number. That works, but requires you to read the file twice.
A faster solution is to read the first line and save it as the selected line. You replace the selected line with the next line with probability 1/2. When you read the third line, you replace with probability 1/3, etc. When you've read the entire file, you have selected a line at random, and every line had equal probability of being selected. The code looks something like this:
string selectedLine = null;
int numLines = 0;
Random rnd = new Random();
foreach (var line in File.ReadLines(filename))
{
++numLines;
double prob = 1.0/numLines;
if (rnd.Next() >= prob)
selectedLine = line;
}
Now, what if you want to select 2 lines? You select the first two. Then, as each line is read the probability that it will replace one of the two lines is 2/n, where n is the number of lines already read. If you determine that you need to replace a line, you randomly select the line to be replaced. You can follow that same basic idea to select any number of lines at random. For example:
string[] selectedLines = new int[M];
int numLines = 0;
Random rnd = new Random();
foreach (var line in File.ReadLines(filename))
{
++numLines;
if (numLines <= M)
{
selectedLines[numLines-1] = line;
}
else
{
double prob = (double)M/numLines;
if (rnd.Next() >= prob)
{
int ix = rnd.Next(M);
selectedLines[ix] = line;
}
}
}
You can apply that to your BitArray quite easily:
int[] selected = new int[quantity];
int num = 0; // number of True items seen
Random rnd = new Random();
for (int i = 0; i < items.Length; ++i)
{
if (items[i])
{
++num;
if (num <= quantity)
{
selected[num-1] = i;
}
else
{
double prob = (double)quantity/num;
if (rnd.Next() > prob)
{
int ix = rnd.Next(quantity);
selected[ix] = i;
}
}
}
}
You'll need some special case code at the end to handle the case where there aren't quantity set bits in the array, but you'll need that with any solution.
This makes a single pass over the BitArray, and the only extra memory it uses is for the list of selected indexes. I'd be surprised if it wasn't significantly faster than the LINQ version.
Note that I used the probability calculation to illustrate the math. You can change the inner loop code in the first example to:
if (rnd.Next(numLines+1) == numLines)
{
selectedLine = line;
}
++numLines;
You can make a similar change to the other examples. That does the same thing as the probability calculation, and should execute a little faster because it eliminates a floating point divide for each item.
There are two families of approaches you can use: deterministic and non-deterministic. The first one involves finding all the eligible elements in the collection and then picking N at random; the second involves randomly reaching into the collection until you have found N eligible items.
Since the size of your collection is not negligible at 100K and you only want to pick a few out of those, at first sight non-deterministic sounds like it should be considered because it can give very good results in practice. However, since there is no guarantee that N true values even exist in the collection, going non-deterministic could put your program into an infinite loop (less catastrophically, it could just take a very long time to produce results).
Therefore I am going to suggest going for a deterministic approach, even though you are going to pay for the guarantees you need through the nose with resource usage. In particular, the operation will involve in-place sorting of an auxiliary collection; this will practically undo the nice space savings you got by using BitArray.
Theory aside, let's get to work. The standard way to handle this is:
Filter all eligible indices into an auxiliary collection.
Randomly shuffle the collection with Fisher-Yates (there's a convenient implementation on StackOverflow).
Pick the N first items of the shuffled collection. If there are less than N then your input cannot satisfy your requirements.
Translated into LINQ:
var results = mask
.Select((i, f) => Tuple.Create) // project into index/bool pairs
.Where(t => t.Item2) // keep only those where bool == true
.Select(t => t.Item1) // extract indices
.ToList() // prerequisite for next step
.Shuffle() // Fisher-Yates
.Take(quantity) // pick N
.ToArray(); // into an int[]
if (results.Length < quantity)
{
// not enough true values in input
}
If you have 10 indices to choose from, you could generate a random number from 0 to 2^10 - 1, and use that as you mask.