I need your help. It's easy question, I think.
So. I work in C# with array.
var TinArr = new List<double>();
Next I have some elements in it. For example:
TinArr[0]=0.5;
TinArr[1]=0.6;
TinArr[2]=1.1;
TinArr[3]=1.5;
Ok. Then I have cycle for remove some of them:
for (var j = 0; j < TinArr.Count; j++)
{
if (TinArr[j] <= 1)
{
TinArr.RemoveAt(j);
}
}
As I understand, when I'll remove element with index "0", next element with index "1" after this action will have index "0". Maybe I'm wrong. How can I save index? Or maybe I should start cycle from the beginning? NEED YOU HELP! THANKS!
You could simply use the RemoveAll method:
TinArr.RemoveAll(x => x <= 1);
But if using a for-loop is a requirement, you should start from the end:
for (var j = TinArr.Count - 1; j >= 0; j--)
{
if (TinArr[j] <= 1)
{
TinArr.RemoveAt(j);
}
}
Do it in reverse rather, something like
for (var j =TinArr.Count - 1; j >= 0; j--)
{
if (TinArr[j] <= 1)
{
TinArr.RemoveAt(j);
}
}
You almost did it yourself, only missing post-decrement:
for (var j = 0; j < TinArr.Count; j++)
if (TinArr[j] <= 1)
TinArr.RemoveAt(j--);
Related
just started to learn programming and I need 2D array without duplicates. This code (well edited for 1D) worked just fine for 1D but doesn't for 2D and have no clue why.
Would be very happy if someone helped me. Thanks.
Random r = new Random();
int[,] array = new int[10, 8];
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = r.Next(10, 100);
for (int k = 0; k < i; k++)
{
for (int l = 0; l < j; l++)
{
if (array[i,j] == array[k,l])
{
i--;
j--;
break;
}
}
}
}
}
With the nested j loop you are filling the entire second dimension for each i, but in the k and l loops you are only checking the grid to the upper and left of current cell. You could place a number twice because you are not checking every previously filled location.
If we change the code to this:
for (int k = 0; k < array.GetLength(0); k++)
{
for (int l = 0; l < array.GetLength(1); l++)
{
if (i != k && j != l && array[i, j] == array[k, l])
{
i--;
j--;
break;
}
}
}
Then you eliminate that problem, but you very quickly find that you get a IndexOutOfRangeException because you're decrementing both i & j at the same time. That's not moving you to the previous value - it's jumping back a whole row and left one cell - and that's ultimately sending i or j to -1 and that's not good.
If you want to do it like you're attempting then you need to have a way to simply move back to the previously filled cell, regardless of the row or column you're on.
Try this:
for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++)
{
array[x % array.GetLength(0), x / array.GetLength(0)] = r.Next(10, 100);
for (int y = 0; y < x; y++)
{
if (array[x % array.GetLength(0), x / array.GetLength(0)] == array[y % array.GetLength(0), y / array.GetLength(0)])
{
x--;
break;
};
}
}
However, that's not very efficient. Try this instead:
var values = Enumerable.Range(10, 90).OrderBy(_ => r.Next()).ToArray();
for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++)
{
array[x % array.GetLength(0), x / array.GetLength(0)] = values[x];
}
So, first of all, that just seems inefficient. Not sure why you want to do it this way, but then again, don't know the reason. Looks like a programming assignment.
My guess, you need a sort of double break going on. When you break finding a match, you don't break out to the "k" for loop, so you continue looking for a match even though you found one. Try setting a boolean value to say it's found, then use that in the criteria for the for loop for k. That'll break it out and let you start over on the outside loops for i and j.
Even then, it won't work because you indescriminately subtracted i and j. So if you're on position 1,2 you will jump back to 0,1 rather than 1,2. So you need to subtract j, if it drops below 0, then subtract from i and add "array.GetLength(1)" to j.
This solution depends on HashSet's property of containing unique elements. It has an Add method that returns false when we try to add existing elements.
Random r = new Random();
int[,] array = new int[10, 8];
var usedValues = new HashSet<int>();
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
int uniqueValue;
while (true)
{
uniqueValue = r.Next(10, 100);
if (usedValues.Add(uniqueValue)) break; // It is unique indeed
// It is not unique, try again.
}
array[i, j] = uniqueValue;
}
}
The above solution is more suitable when the range of the acceptable unique values is large. In this specific case the range is very small (10-99), and the solution offered by #Enigmativity is preferable.
I initialized an object:
object[,] A = new object[range.RowCount() + 1, range.ColumnCount() + 1];
After filling this I need to iterate all elements of object in loop.
How to iterate this in for loop?
I tried to do: for(var i = 0; i < A.Count(); i++){}
But there is not property Count() for object, also this is matrix.
For things like this you might want nested loops, like so:
for (int i = 0; i < A.GetLength(0); i++)
{
for (int j = 0; j < A.GetLength(1); j++)
{
//do your magic
}
}
Arrays have Length property:
for (var i = 0; i < A.Length; i++)
{
var b = A[i, 1];
}
Count() is a method of IEnumerable
Its been bugging me for hours because it is always returning 0 at numbers[i] and I cant figure out the problem. code worked for a different program but I had to change it so it could have a custom array size and that's when everything went wrong.
any help would be great.
Thanks in advance.
int[] numbers = new int[Convert.ToInt16(TxtArray.Text)];
int j = 0;
for (j = numbers.Length; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 1; i++)
{
string NumbersInput = Microsoft.VisualBasic.Interaction.InputBox("Enter Numbers to be sorted",
"Numbers Input", "", -1, -1);
numbers[i] = Convert.ToInt16(NumbersInput);
//returns 0 in if statement
if (numbers[i] < numbers[i + 1])
{
int intTemp = 0;
intTemp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = intTemp;
}
}
}
for (int i = 0; i < numbers.Length; i++)
{
LstNumbers.Items.Add(numbers[i]);
}
private void button1_Click(object sender, EventArgs e)
{
int sizeOfArrayInt = Convert.ToInt32(arraySize.Text);
int[] array = new int[sizeOfArrayInt];
string numbers = arrayValues.Text;
string[] numbersSplit = numbers.Split(',');
int count = 0;
foreach (string character in numbersSplit)
{
int value;
bool parse = Int32.TryParse(character, out value);
if (value != null)
{
array[count] = value;
}
count++;
}
array = this.SortArray(array);
foreach (int item in array)
{
this.listBox.Items.Add(item);
}
}
private int[] SortArray(int[] arrayToSort)
{
//int[] sortedArray = new int[arrayToSort.Length];
int count = arrayToSort.Length;
for (int j = count; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 2; i++)
{
if (arrayToSort[i] < arrayToSort[i + 1])
{
int intTemp = 0;
intTemp = arrayToSort[i];
arrayToSort[i] = arrayToSort[i + 1];
arrayToSort[i + 1] = intTemp;
}
}
}
return arrayToSort;
}
strong text
This I got to work as a Windows Form and the output displays in the list box as each array item or individual i iteration over the array. Of course there is no error checking. Hope that helps.
Setting aside the strangeness of how you are working with text boxes, your problem with throwing an exception would happen even without them because it lies here, in your inner loop:
for (i = 0; i <= j - 1; i++)
Suppose that numbers.Length == 2. This means that j == 2. So on the first time through the outer loop, you hit the inner loop with these conditions. The first time through, i == 0. You get to the if statement:
if (numbers[i] < numbers[i + 1])
numbers[0] exists, and numbers[1] exists, so this iteration goes through fine and i is incremented.
Now i == 1. Now the loop checks its boundary condition. i <= j - 1 == true, so the loop continues. Now when you hit that if statement, it tries to access numbers[i + 1], i.e., numbers[2], which does not exist, throwing an IndexOutOfRangeException.
Edit: Came back and realized that I left out the solution (to the exception, anyway). For the bubble sort to work, your inner loop's boundary condition should be i <= j - 2, because j's initial value is == numbers.Length, which is not zero-based, while array indexes are.
Second Edit: Note that just using a List won't actually solve this problem. You have to use the right boundary condition. Trying to access list[list.Count()] will throw an ArgumentOutOfRangeException. Just because a List will dynamically resize doesn't mean that it will somehow let you access items that don't exist. You should always take time to check your boundary conditions, no matter what data structure you use.
Could anyone tell me why the nested for loop in the code below doesn't execute? I.e. The "Hello World" is not printed. The first loop is being executed.
for (int i = 0; i < data.Length; i++)
{// Loop through array
**for (int j = data.Length - 1; j < i; j--)**
{
// Loop backwards through array
**Console.WriteLine("Hello World");**
double subTotal = 0; //Keeps track of current subsequence's value
subTotal += data[j];
if (bbestTotal < subTotal)
{
bbestTotal = subTotal;
}
}
}
The loop is not executing because the loop condition
j < i
is false right at the beginning of the loop.
Since your loop advances j down, you should change the condition to
for (int j = data.Length - 1 ; j >= i ; j--)
The inner loop variable j is initialized with top value and it is greater then i so use j > i instead of j < i in loop condition part.
Change
for (int j = data.Length - 1; j < i; j--)
to
for (int j = data.Length - 1; j > i; j--)
The root cause of the problem is that the condition j < i for the 2nd for loop is always false for all values of i. So it never goes inside the body of the 2nd for loop.
This should fix the problem:
for (int j = data.Length - 1; j > i; j--)
I have been looking for the reason why I get this error message for several days now! And I need help to solve this or to improve the code. It's hard to understand why this error happens and find the reason, when it just happens sometimes and not all the time! But my guess is that it has to do with the list and the numbers of items in the lists. It's in the second part of the code where the error event happens. I have also tried to add the objects that I want to remove in a special "to remove list", but why should this not work? Help is appreciated! Thanks!
public void CollisionControlMissileHitAsteroid(ContentManager content)
{
for (int i = 0; i < missilesList.Count(); i++)
{
// Stora asteroider
for (int j = 0; j < asteroidsBigList.Count(); j++)
{
if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsBigList.ElementAt(j).Bounds())) // Fel här ??
{
for(int x = 0; x < 2; x++)
AddNewSmallAsteroidToList(new AsteroidSmall(content, asteroidsBigList.ElementAt(j).Position));
missilesList.RemoveAt(i);
i--;
asteroidsBigList.RemoveAt(j);
j--;
}
}
if (missilesList.Count() > 0 && asteroidsSmallList.Count > 0)
{
for (int k = 0; k < asteroidsSmallList.Count(); k++)
{
if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsSmallList.ElementAt(k).Bounds())) // THIS IS WHERE THE ERROR EVENT HAPPENS!
{
missilesList.RemoveAt(i);
i--;
asteroidsSmallList.RemoveAt(k);
k--;
}
}
}
}
}
EDIT:
Is this where I should place the break? Ask beacause it still happens! I can play for five minutes until it happens!
if (missilesList.Count() > 0 && asteroidsSmallList.Count() > 0)
{
for (int k = 0; k < asteroidsSmallList.Count(); k++)
{
if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsSmallList.ElementAt(k).Bounds()))
{
missilesList.RemoveAt(i);
i--;
asteroidsSmallList.RemoveAt(k);
k--;
break; // ???????
}
}
}
You are right in thinking that it's to do with the bounds of the list. I've never come up with a satisfactory way of removing listitems or array elements within a loop other than, as you say, building up a list of indexes and removing them outside of the loop.
Having said that, have you tried going through the list backwards, like -
for (int k = asteroidsSmallList.Count() - 1; k >= 0; k--)
{
...
Suppose you start off with one missile and two asteroids. The missile (i=0) hits the first asteroid (j=0) - but you're then continuing with i=-1 and j=0. You should be breaking out of the inner loop and continue with the next iteration of the outer loop there instead. After all, you're "done" with the missile - it can't hit any other asteroids, big or small.
(And yes, as per xanatos's comments, it would be more idiomatic to use the Count property instead of the Count() method.)
I think that the problem is obvious because your code runs in a for loop. In the first for loop you got i=0. Read my comments inside
for (int i = 0; i < missilesList.Count(); i++)
{
// Stora asteroider
for (int j = 0; j < asteroidsBigList.Count(); j++)
{
if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsBigList.ElementAt(j).Bounds())) // Fel här ??
{
for(int x = 0; x < 2; x++)
AddNewSmallAsteroidToList(new AsteroidSmall(content, asteroidsBigList.ElementAt(j).Position));
missilesList.RemoveAt(i);
// In the first iteration of the outer for loop i=0, so what if the line below is executed
// you will get negative index Hope this help
i--;
asteroidsBigList.RemoveAt(j);
j--;
}
}