Pop values off Stack<T> [duplicate] - c#

This question already has answers here:
Adding items to a LIST<> of objects results in duplicate Objects when using a NEW in a Loop
(2 answers)
Closed 5 years ago.
So I'm trying to create a backtracking recursive algorithm for maze generation using the stack to store the coordinates of the last spot entered in an array of ints [x,y]. When I try to store the results of .Pop off the stack, it sets my variable for the first popped value but not off of the next.
public static void Main(string[] args)
{
//Your code goes here
Stack<int[]> myStack = new Stack<int[]>();
int[] pusher = new int[] {1,2};
myStack.Push(pusher);
pusher[0] = 3;
pusher[1] = 4;
myStack.Push(pusher);
while(myStack.Count > 0){
int[] test = myStack.Pop();
for(int i = 0; i < test.Length; i++){
Console.WriteLine(test[i]);
}
}
}
Wanted result would be that the console displays 3,4,1,2. Instead I'm getting back 3,4,3,4.

You are only creating one array - pusher. You are then simply replacing the numbers 1 and 2 at the indexes 0 and 1 of this array respectively.
If you create another array and add 3 and 4 to this one, you will get the expected results:
Stack<int[]> myStack = new Stack<int[]>();
int[] pusher = new int[] { 1, 2 };
myStack.Push(pusher);
int[] second = new int[2];
second[0] = 3;
second[1] = 4;
myStack.Push(second);
while (myStack.Count > 0)
{
int[] test = myStack.Pop();
for (int i = 0; i<test.Length; i++)
{
Console.WriteLine(test[i]);
}
}

Question answered by Lasse Vågsæther Karlsen in comments on question. Moving to answer.:
You're reusing the same array instance so you're in fact pushing the same array onto the stack twice. When you store 3 and 4 into the array you overwrite the 1 and 2 already there. Push does not make a copy of the array contents, only of the array reference, therefore you push the same array twice. If you want to push a copy, use myStack.Push(pusher.ToArray()); – Lasse Vågsæther Karlsen 4 hours ago

Related

Fill an array with unique random integers [duplicate]

This question already has answers here:
Randomize a List<T>
(28 answers)
Closed 5 years ago.
I want to fill a small array with unique values from a bigger array. How do I check the uniqueness?
Here's what I have:
int[] numbers45 = new int[45];
for (int i = 0; i <= 44; i++) // I create a big array
{
numbers45[i] = i + 1;
}
Random r = new Random();
int[] draw5 = new int[5]; //new small array
Console.WriteLine("The 5 draws are:");
for (int i = 1; i <= 4; i++)
{
draw5[i] = numbers45[r.Next(numbers45.Length)]; //I fill the small array with values from the big one. BUT the values might not be unique.
Console.WriteLine(draw5[i]);
}
There are multiple ways to do what you are asking.
First off, though, I would recommend to use one of the classes which wraps the array type and adds some extra functionality you could use (in this case a List would probably be a perfect structure to use)!
One way to handle this is to check if the value is already in the draw5 array. This can be done with (for example) the List<T>.Contains(T) function, and if it exists, try another.
Personally though, I would probably have randomized the first array with the OrderBy linq method and just return a random number, like:
numbers45.OrderBy(o => random.Next());
That way the numbers are already random and unique when it is supposed to be added to the second list.
And a side note: Remember that arrays indexes starts on index 0. In your second loop, you start at 1 and go to 4, that is, you wont set a value to the first index.
You could just run for (int i=0;i<5;i++) to get it right.
Inspired by Jite's answer, I changed to use Guid to randomize the numbers
var randomized = numbers45.OrderBy(o => Guid.NewGuid().ToString());
Then you could take the draws by:
var draws = randomized.Take(5).ToArray;
HashSet<int> hs = new HashSet<int>();
int next = random.next(45);
while(hs.Length <=5)
{
if(!hs.Contains(array[next]))
hs.Add(array[next]);
next = random next(45);
}

Looking to sort array from smallest to largest remove duplicates [duplicate]

This question already has answers here:
How do I remove duplicates from a C# array?
(28 answers)
Closed 5 years ago.
As the title says, I'm taking a free online course in C# and I've been stuck on this question for a bit. It's asking to write function with an array that sorts from smallest to largest and removes duplicate entries. The course has gone over arrays and sorting, but not how to remove duplicates so far. If you could help with this I'd appreciate it greatly.
There are a couple of ways to accomplish the task at hand, However, the quickest way is probably using Linq:
int[] array = { 3, 5, 1, -9, 4, 8, 23, -657, 54 };
array = array.Distinct().OrderBy(x => x).ToArray();
While there may be some more efficient methods, to help you understand the concepts a bit more, here's a simple technique.
You'll need to keep track of what entries you've already seen. Create a new list, and add the first number in the array to it. Then, take the second number in the array, and compare it to every number in your list. If it ever shows up in this list, it's a duplicate, so you can skip this number and move to the next element in the array.
ArrayList list = new ArrayList();
for (int i = 0; i < yourUnsortedArray.length; ++i) {
bool hasDuplicate = false;
for (int entry in list ) {
if (yourUnsortedArray[i] == entry) {
hasDuplicate = true;
break;
}
}
if (hasDuplicate == false) {
list.Add(yourUnsortedArray[i]);
}
}
//list will have no duplicates here.
Bonus optimization: It will help if you sort the array first. This way, you only ever have to look at the most recently added number in your list, instead of walking down the entire list every single time.
ArrayList list = new ArrayList();
for (int i = 0; i < yourSortedArray.length; ++i) {
if (list.length == 0 || list[list.length - 1] != yourSortedArray[i]) {
list.Add(yourSortedArray[i]);
}
}

how to create a random int[] [duplicate]

This question already has answers here:
Most efficient way to randomly "sort" (Shuffle) a list of integers in C#
(13 answers)
Closed 5 years ago.
I need to create a random array of int with certain parameters.
int[] test = new int[80];
Random random = new Random();
I need to assign 1's and 0's, randomly to the array. I know how to do that.
test[position] = Random.Next(0,2);//obviously with a for loop
But I need to have exactly 20 1's, but they need to be randomly positioned in the array. I don't know how to make sure that the 1's are randomly positioned, AND that there are exactly 20 1's. The rest of the positions in the array would be assigned 0.
I think you need to turn your thinking around.
Consider:
var cnt = 20;
while (cnt > 0) {
var r = Random.Next(0, 80);
if (test[r] != 1) {
test[r] = 1;
cnt--;
}
}
Expanding explanation based on comments from CodeCaster. Rather than generate a random value to place in the array, this code generates and index to set. Since C# automatically initializes the test array to 0 these values are already set. So all you need is to add your 1 values. The code generates a random index, tests it to see if it isn't 1, if so it sets the array element and decrements a count (cnt). Once count reaches zero the loop terminates.
This won't properly function if you need more values than 0 and 1 that is true. Of course the questions explicitly stated that these were the needed values.
"This causes horrible runtime performance". What!? Can you produce any prove of that? There is a chance that the index generated will collide with an existing entry. This chance increases as more 1's are added. Worst case is there is a 19/80 (~23%) chance of collision.
If you know you need exactly 20 of one value, a better way to go about this is to pre-populate the array with the required values and then shuffle it.
Something like this should work:
int[] array = new int[80];
for (int i = 0; i < 80; i++)
{
int val = 0;
if (i < 20)
{
val = 1;
}
array[i] = val;
}
Random rnd = new Random();
int[] shuffledArray = array.OrderBy(x => rnd.Next()).ToArray();
You can do
for (int i = 0; i < 20; i++)
{
var rand = random.Next(0,80);
if (test[rand] == 1)
{
i--;
continue;
}
test[rand] = 1;
}
Remaining are automatically zero.

How to resolve an "IndexOutOfRange exception" error? [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 6 years ago.
I can't understand what's wrong.
static int WinningColumn()
{
Random rnd = new Random(46);
int[] winningnumbers = new int[6];
int[] Check = new int[46];
int i;
for (i = 0; i < winningnumbers.Length; i++)
{
winningnumbers[i] = rnd.Next(46);
Check[winningnumbers[i]]++;
if (Check[winningnumbers[i]] > 1)
{
i--;
continue;
}
The error happens here:
}
return winningnumbers[i];
}
When you exit from the for loop the indexer variable i has a value bigger than the max index possible (It is the condition that breaks the loop).
In your case the variable i has the value of 6 but the max index possible for the array winningnumbers is 5. (0 to 5 are six integer elements).
It is not clear what is your intent but supposing that your purpose is to generate six winning numbers ranging from 0 to 45 then your code should be rewritten and simplified in this way
static List<int> WinningColumn()
{
// Do not initialize Random with a fixed value
// You will get always the same 'random' sequence
Random rnd = new Random();
// Create a list to store the winners
List<int> winningnumbers = new List<int>();
int i = 0;
while(i < 6)
{
int newNumber = rnd.Next(46);
if(!winningnumbers.Contains(newNumber))
{
// If the list doesn't contain the number the add it and increment i
// Otherwise run the loop again....
winningnumbers.Add(newNumber);
i++;
}
}
// This returns the whole list to the caller,
// you can use it as an array
return winningnumbers;
}
Notice that your actual code contains a bug in the declaration of the Random number generator. You pass an initial seed and thus, everytime you call this method, the random generator starts again with the same sequence of numbers. The result would be an identical list of numbers. Not very random to me
If you don't pass anything then the generator is initialized with the system time and thus should be different every time you call this method.
I don't know what you want to achieve here.
But the loop would terminate when i becomes 6.
So you are basically trying to access winningnumbers[6] which is incorrect since winningnumbers array has length 6 so you can use index from 0 till 5.
You may try with winningnumbers [i-1]

How do I remove elements from an array in First In First Out manner [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
C# beginner here...
I have
int[] numbers = new int[10];
I would like to add 50 numbers to this array. Once the array is full, the first added number will be removed and the new number will be added. I would like to display the last added number on the top of the array. Such as
[5,4,3,2,1...]
not
[1,2,3,4,5,...]
How can I achieve this?
Thanks in advance
This is what I have tried
....
dataArray = new int[10];
....
Queue<int> numbers = new Queue<int>();
....
if (numbers.Count == 10)
{
numbers.Dequeue();
}
numbers.Enqueue(i);
numbers.CopyTo(dataArray, numbers.Count);
I keep getting " Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection" error
Array.Copy provides good performance for what you're trying to accomplish.
int[] newArray = new int[10];
newArray[0] = 4; // new value
Array.Copy(numbers, 0, newArray, 1, numbers.Length - 1);
Be careful with array lengths though with this as any bound issues with throw exceptions.
I think you should be using queue and then you can convert it into array if you want
class Program
{
static void Main(string[] args)
{
const int CAPACITY = 10;
Queue<int> queue = new Queue<int>(CAPACITY);
for (int i = 0; i < 50; i++)
{
if (queue.Count == CAPACITY)
queue.Dequeue();
queue.Enqueue(i);
}
queue.ToArray();
Console.WriteLine(queue.Count);
Console.ReadKey();
}
}
Take a look at the generic Queue class, that has the functionality that you are looking for with FILO structure. Doing this just with arrays...
int[] numbers=new int[50];
for(int i=0; i<numbers.length; i++) numbers[i]=i;
//fill the array with 1, 2, 3, 4...
//To reverse this order, swap elements in reverse
//numbers.length-1 is the last index of the array
// j<numbers.length/2,each time you swap you change two values, so only done half the length of the array
for(int j=numbers.length-1; j>numbers.length/2; j--) swap(numbers, j, numbers.length-j);
//swaps the values of different indexes in the array
void swap(int[] array, int index1, int index2) {
int temp=array[index1];
array[index1}=array[index2];
array[index2}=temp;
}
This should reverse the arrays

Categories