c# wrong number of indices inside [] expected 2 - c#

I am doing PrimSparse algorithm and it says I need two indices in my for loop
private Node z;
adj = new int[V + 1, V + 1];
Node t;
for (t = adj[v]; t != z; t = t.next)
{
if (t.wgt < dist[u])
{
//puts the distance between the two vertex as the current data
dist[v] = t.wgt;
parent[u] = v;
//making sure when the vertex is == 0 then insert the vertex
if (hPos[u] == 0)
{
h.insert(t.vert);
}
else
{
//or otherwise just move up the position of the vertex
h.siftUp(hPos[t.vert]);
}
}
}
the very first line is giving me the CS0022 error, absolutely no idea why, when i put in a second it says "cannot convert int to Graph.node"
any ideas?

The answer is relatively straightforward:
CS0022 is "Wrong number of indices inside []"
adj is declared as a 2D array of ints, so you will need to supply two indices when you dereference it, not one. This is just how arrays work.
You seem to have correctly diagnosed that issue - so onto the 2nd:
Dereferencing an adj gives you an int. You're then trying to assign an int to t, which has a type of "node" There's no conversion defined between "int" and "node", thus the 2nd error message. You can read it as straight English, "Cannot convert an int to a node" - but you have to make one more logical step. Why is a conversion from int to node necessary? Because you're trying to do assignment. Maybe a more verbose error message would be "Cannot assign an int to a variable of type Node because there is no conversion specified"
Some Lurking issues:
Comparing T and Z should be no problem. They're both Nodes. You may need to provide your own equality operator though. By default, != is going to do a reference compare. You may or may not want to compare references.
Finally, assuming the type of t.next is also a node, the last part of your for loop should be OK too.

Related

How to compare a data value against values in an list

I'm trying to search through a list of values, which could be any type (int, string, bool, and so-on), and I can't find a way to compare a given value against values in the list.
My code so far:
public void Countin(T data)
{
int numbersOf = 0;
Node pTmp = first;
while (pTmp != null)
{
if (pTmp.Equals(data))
{
numbersOf++
pTmp = pTmp.Next;
}
else
{
pTmp = pTmp.Next;
}
}
Console.WriteLine($"There are {numbersOf} {data} in the list.");
}
With a list of
"I" "am" "getting" "really" "really" "tired" "of" "this",
I keep getting the output of "There are 0 really in the list". And when I swap the numbersOf++ from to the 'else', I get "There are 8 really in the list."
The rest of the code works fine, it's just that "pTmp.Equals(data)" isn't doing what I think it should be doing, but I can't just use pTmp == data, due to 'data' being an element in a list.
Any help?
Every part of the above code works fine EXCEPT FOR COMPARING pTmp TO data! Nothing else needs help! I just need a way to compare the data variable to the values in the list.
FINAL EDIT:
All I had to do was change the boolean to if (Equals(pTmp.Data),data), and it worked. All I needed as an answer was 'Equals(x,y) will do what you want'. Thanks guys.

Array Questions

Recently had a quiz in my C# class and got some things wrong. I think I have the answers but I want to make sure I am right.
First one:
Explain the result
int[] myArray = {5,10,15,20,25};
DoWork(myArray);
void DoWork(int[] theArray)
{
for (int c = 0; c < theArray.Length; c++)
{
theArray[c] = 1;
}
theArray = null;
}
For this one, I only got half of it right. I said that the loop would set the value for each element in the array to 1. So my question is, what happens when you set the array to null?
Second one:
Explain the result
int[] myArray = {5,10,15,20,25};
DoWork(myArray[1]);
void DoWork(int theItem)
{
theItem = -1;
}
This one I got completely wrong. The correction was that myArray[1] = 10 still. Is this because it is not being passed by reference? This just confused me a lot because I ran a little test program on the first one (without the null part) and all the values were set to 1 in the array but I was not passing by reference.
Q: what happens when you set the array to null?
A: "theArray" (inside the routine) is set to null. But "myArray" (outside of the routine) is UNCHANGED. The reason is that "myArray" is an object reference, which is passed by value into DoWork().
Q: Is this because it is not being passed by reference?
A: Yes, exactly. From the link above:
https://msdn.microsoft.com/en-us/library/9t0za5es.aspx
Any changes to the parameter that take place inside the method have no
affect on the original data stored in the argument variable.
These links explain further:
C# Parameter Passing, Ref and Out
C# - Passing Parameters by Reference

Referring to an object defined by a variable

I have a problem, which I couldn't solve recently.
I have this code
foreach (Hashtable i in (ArrayList)inv["database"])
{
if (i != null)
{
if (i["type"].ToString() == "1")
{
if (i["dataValue"].ToString() != "0")
{
inv{nn}.Image = Program.Properties.Resources._i["type"].ToString()+"-"+i["dataValue"].ToString();
}
else
{
inv{nn}.Image = Program.Properties.Resources._i["type"].ToString()
}
}
}
nn++;
}
I have 36 controls(it's a class i have in my project, so not "vanilla" one), and each one of them is a single "picturebox". I have 505 images in the following syntax:
If the data value is 0, then it's {typeID}.png, if the data value is above 0, then {typeID}-{dataValue}.png
So for example if it's the first loop, i["type"].ToString() = 1 and i["dataValue"].ToString() = 3, the Image of inv0 changes to Program.Proporties.Resources._1-3
When the second loop comes the image of inv1 changes etc. ... till inv35
Is such thing possible? I tried
InterpolationBox x = Form1.FindControl("inv"+nn)
and I seem not to have such thing as FindControl (FrameWork 4) with System.Web.UI used.
I tried
InterpolationBox x = this.Controls.Find("inv" + nn, false);
And I got Unable to cast object of type 'System.Windows.Forms.Control[]' to type 'Program.InterpolatedBox'. And anyway, if I'd get rid of that error, would I be able to change that actual picturebox, not just the copied 'x' one?
InterpolationBox x = this.Controls.Find("inv" + nn, false);
Is where your problem lies.
The error you got is telling:
Unable to cast object of type 'System.Windows.Forms.Control[]' to type
'Program.InterpolatedBox'.
You can see it's saying it can't cast an array of System.Windows.Forms.Control to a Program.InterpolationBox which is sensible given InterpolationBox is a single control.
The Find method returns an array of controls, not just one, so you need to then look in the array and pull out the one you're after (even if it's just the first one).
As for your question about whether changing x would change the control you got given using Controls.Find() the answer is YES.
Objects in .NET are by reference, which means x isn't an InterpolationBox it's a reference to an InterpolationBox in memory.
You could even do:
var a = x;
var b = a;
var c = b;
c.DoSomething();
The code you call against c will operate against the same object, they're all just references pointing to the same thing.

How to check if key pair in 2D array exists?

I have this 2d array or struct
public struct MapCell
{
public string tile;
}
public MapCell[,] worldMap;
But there's no way to check if key pair is exists in this array or not... No methods for that available.
I tried to do it like this
if (worldMap[tileX, tileY] != null) {
}
it doesnt work:
Error 1 Operator '!=' cannot be applied to operands of type 'Warudo.MapCell' and '<null>'
and for
if (worldMap[tileX, tileY].tile != null) {
it doesn't work either (exception pops up when it hits non existing element).
Index was outside the bounds of the array.
So, how do I check if key pair is exists or not?
You never mentioned which error you are getting -- array out of bounds or a null reference. If you are getting array out of bounds you should precede your null check with something along the lines of...
// make sure we're not referencing cells out of bounds of the array
if (tileX < arr.GetLength(0) && tileY < arr.GetLength(1))
{
// logic
}
Of course, it's best to just store the maximum array bounds instead of getting their lengths each time.
I also second (third?) the recommendation for using a class and not a struct.
Edit: Are you ever actually initializing this field? You haven't included it in your code sample. For example worldMap = new MapCell[100,100];, and then fill up the array...
If you're using an array of struct values, they always exist (once the array is constructed), but have their default value until you set them.
I would recommend using a class here instead of a struct. This will allow you to check for null, as well as act more in an expected fashion if you're going to be changing values (which, given the names, I expect...)
That being said, you could check for whether the string within the struct is null:
if (worldMap[tileX, tileY].tile != null)
{
// You've set the "tile" field inside of this "cell"...
This works because the default value of a struct is initialized with all references, including strings, to null.

Converting a List<> to an Array - I get "Attempted to access an element as a type incompatible with the array."

I'm trying to walk through a bunch of items, each item has an array of List<> objects that I want to convert to an array of arrays.. Here's the code to do that:
foreach (IngredientNode i in _snapshot._ingredientMap.Values)
{
for (int c = 0; c < NUM_TAGS; c++)
{
if (i.RecipesByTag[c] == null) continue;
i.RecipesByTag[c] = i.RecipesByTag[c].ToArray<RecipeNode>();
} <--- EXCEPTION
}
RecipesByTag has a static type of IEnumerable<RecipeNode>[]. However, its dynamic type is List<RecipeNode>[]. I want to go through each one of those and convert the dynamic type of RecopeNode[]. Under the debugger, this works and i.RecipesByTag gets converted. However, the last curly brace then throws the exception:
Attempted to access an element as a type incompatible with the array.
I have a feeling there's some sort of stack corruption going on. Can someone explain what's happening at a technical level here? Thanks!
Mike
You shouldn't have to specify the type argument for the ToArray method, it should be inferred from it's usage, if you are using strongly typed collections. This is a generic type casting problem. You are trying to put elements in an array of some incompatible type.
Your problem should boil to this (these arrays are covariant):
object[] obj = new string[1];
obj[0] = 5; // compiles fine, yields runtime error
Now, the same thing, with different types (these arrays are also covariant):
IEnumerable<int>[] x = new List<int>[1];
x[0] = new int[1]; // compiles fine, yields runtime error
It should be obvious why the type system doesn't like this. Basically, you look at it as if it was an array of IEnumerable<int> but it's actually an array of List<int>. You can not put an unrelated type array of int, into that array.
I believe Eric Lippert explains this very well on his blog.
Okay I think I figured out what's going on.. I have an array of Enumerables. At first, this was an array of pointers to list objects. I instead made this an array of other arrays, in other words I converted my array into a multidimentional array. Since a multidimentional array is consecutive in memory (as opposed to an array of pointers to other arrays), doing this completely corrupted the array in memory. At least that's my theory.
What I did is completely recreate i.RecipesByTag from scratch. Something like this:
List<RecipeNode[]> temp = new List<RecipeNode[]>();
for (int c = 0; c < NUM_TAGS; c++)
{
RecipeNode[] nodes = (i.RecipesByTag[c] == null) ? null : i.RecipesByTag[c].ToArray<RecipeNode>();
temp.Add(nodes);
}
i.RecipesByTag = temp.ToArray();
This works perfectly.

Categories