Recursion Function in Graph Path Finding - c#

I scripted the following recursion function to calculate all of the possible paths from a target node to a start node in a graph using adjacency matrix.
private Stack<string> TestCaseGeneration(int TargetStateIndex, double[,] adjacancy, Stack<string> TotalResults = null, Stack<string> CarrierStack = null, int StartStateIndex = 0)
{
Stack<string> Result = CarrierStack;
Result.Push(TargetStateIndex.ToString() + " - ");
if (TargetStateIndex == StartStateIndex)
{
TotalResults.Push(StackToSingleString(Result));
return TotalResults;
}
else
{
List<string> neighbours = ListNeighbourLeadingToTargetNode(TargetStateIndex, adjacancy, EventIndex);
int NumberOfNeighbours = neighbours.Count;
if (NumberOfNeighbours != 0)
{
for (int i = 0; i < NumberOfNeighbours; i++)
{
return TestCaseGeneration(int.Parse(neighbours[i].ToString()), adjacancy, TotalResults, Result, StartStateIndex);
}
}
}
else return null;
}
The issue is return int the for loop, how can I fix it?

If you don't want to return anything set the return null; before the last }
If you put the return null; in a if else statement the compiler knows not all code paths return a value!
EDIT
I see your problem now sorry.
You need to create a variable wich you return at the end.
In the if statement you can edit the variable.
If the variable is never edited the default value of the variable is returned!

The think your code will always return a value. I suggest you throw an exception just before the last } of the method: It will compile and you get a nice chance to see your code in action! If it throws the exception, you know when it was not going to return a value.

As it has been pointed out your else statement does nothing. Consider laying out your method in layman's terms:
method(){
if(something){
// do stuff
return value
}
else{
// do something else but,
// never do anything with this information
}
return null
}
This is basically what your method looks like when you break it down. The else statement does things, but those things are never used anywhere.
Suppose inside that else statement you call the recursive function which recursively calls 1000 more times. At the end of this loop it will return either null or some value back to the else statement.
That else statement then does nothing with the return value, then returns null.
That recursive call is basically useless unless it, too, is returned.
Consider trying:
private Stack<string> TestCaseGeneration(int TargetStateIndex, double[,] adjacancy, Stack<string> TotalResults = null, Stack<string> CarrierStack = null, int StartStateIndex = 0)
{
Stack<string> Result = CarrierStack;
Result.Push(TargetStateIndex.ToString() + " - ");
if (TargetStateIndex == StartStateIndex)
{
TotalResults.Push(StackToSingleString(Result));
return TotalResults;
}
else
{
int NumberOfNeighbours = ListNeighbourLeadingToTargetNode(TargetStateIndex, adjacancy, EventIndex).Count;
if (NumberOfNeighbours != 0)
{
for (int i = 0; i < NumberOfNeighbours; i++)
{
return TestCaseGeneration(i, adjacancy, TotalResults, Result, StartStateIndex);
}
}
}
return null;
}
Note that I added a return statement to the recursive call within the else statement.

Related

I am getting a 'not all code paths return a value' error in my c# code

I have written a c# extension method that returns any duplicate values in an array of ints and it is telling me that 'not all code paths return a value'. Here is my code:
public static int? FindDuplicate(this int[] arrayToFindDuplicateIn)
{
int previousint = int.MaxValue;
arrayToFindDuplicateIn = arrayToFindDuplicateIn.OrderByDescending(x => x).ToArray();
foreach (int number in arrayToFindDuplicateIn)
{
if (number == previousint)
{
return number;
}
else
{
return null;
}
previousint = number;
}
}
I think what you want is to remove your else return null; and put the return null; outside your foreach. Otherwise it will only loop once everytime.
If the array is empty, no value is returned, so just return something at the end or check the input array with arrayToFindDuplicateIn.Any()

Finding odd or even in an C# array

I'm supposed to create a method that takes an array and tells if the number is odd or even. I think I'm close to the answer but when I ran the code, it popped up with "Index is outside the bounds of the array". Is there a way to fix that?
private static string OddOrEven(int[] integerArray, string[] numAssign)
{
foreach (int i in integerArray)
{
if (integerArray[i] % 2==0)
{
numAssign[i] = " is even";
string returnValue = integerArray[i] + numAssign[i];
return returnValue;
}
else
{
numAssign[i] = " is odd";
string returnValue = integerArray[i] + numAssign[i];
return returnValue;
}
}
return "";
}
I'm still new to c# so any help is really appreciated.
Your mistake here is with how foreach works. I'll provide a different example to help you understand:
List<Person> people = GetPeople();
foreach (Person p in people)
{
Console.WriteLine(p.Name);
}
As you can see, the variable in the foreach actually receives each item, not its index. It's just that you have a list of int so it's not so obvious for you.
It seems like you want a regular for loop:
for(int i = 0; i < integerArray.Length; ++i)
{
if (integerArray[i] % 2==0)
{
numAssign[i] = " is even";
string returnValue = integerArray[i] + numAssign[i];
return returnValue;
}
else
{
numAssign[i] = " is odd";
string returnValue = integerArray[i] + numAssign[i];
return returnValue;
}
}
The next curious thing is your return returnValue; - the if statement can only ever enter one or the other, so it will always return a string for the first item only. It won't go on to the second, third, fourth, etc. item as it has already left the method before the loop has a chance to move on to the next value.
Speculation
I expect you want an array of results like this:
private static string[] OddOrEven(int[] integerArray)
{
string[] resultValues = new string[integerArray.Length];
for (int i = 0; i < integerArray.Length; ++i)
{
if (integerArray[i] % 2==0)
{
string numAssign = " is even";
resultValues[i] = integerArray[i] + numAssign;
}
else
{
string numAssign = " is odd";
resultValues[i] = integerArray[i] + numAssign;
}
}
return resultValues;
}
Note that I've removed the numAssign incoming array from the method parameters, and now just build it within the method itself.
This would produce a result like this.

Return string when inside a while loop

I've tried google, and the advance search here. No luck.
Class SomeClass
{
public string MethodName()
{
//Some Code
While(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
}
}
I get a 'not all code paths return a value' error. I'm sure I can work around this but I'd like to know how to solve this for future reference.
Think if while loop condition is not met, would your method return string? So put the return just before end of method to ensure that your method will always return string, this MSDN error page not all code paths return a value would further help you to understand.
I believe the sample code is just to show the problem as it does not make much sense to me.
public string MethodName()
{
//Some Code
While(conditions) {
//More Code
string X;
X = "string stuff";
return X;
}
return "somestringifnotX";
}
You are getting error because you are trying to return value from while loop which is not possible
Problem here if your while loop condition is not satisfied than no value get return that is the reason compiler giving you error.
Solution to this is , return empty string outside while loop that you function is returning value.
public string functionname
{
while(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
return string.Empty;
}
The problem is that the compiler believes there is a path where conditions is NOT met on the first time it hits the while:
//Some Code
while(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
.. Problem!
return "not found"; // or throw new Exception("I'm not supposed to be here")
What you need to do is also return (or throw!) in the instance where conditions aren't met at all.
I think you mean this
static void Main(string[] args)
{
for (int i = 0; i < MethodName().Count; i++ )
{
var result = MethodName()[i] as string;
Console.WriteLine(result);
}
Console.ReadLine();
}
private static List<string> MethodName()
{
var items = new List<string>();
while (Condition)
{
items.Add("SString to return");
}
return items;
}
I hope it will help
Your problem is that you will not return anything when you don't pass your while loop
Class SomeClass
{
public string MethodName()
{
//Some Code
While(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
return "Nothing to return Actually";
//OR
Throw new Exception("Conditions where false");
}
}
Imagine you're conditions = false and you never entered the while. This means you will never get to the return. your function on the other hand needs one. End your statement with a return or throw an error when you don't want that behaviour.
public static string binarySearch(int [] dataArray, int dataDicari)
{
int first = 0;
int last = list.length – 1;
int mid;
while (first <= last)
{
mid = (first+last)/2;
if (dataArray[mid] == dataDicari)
return ......; //ISIAN 1
else if (dataArray[mid] < dataDicari)
first = mid + 1;
else if (dataArray[mid] > dataDicari)
last = mid – 1;
}
return .....; //ISIAN 2
}

Unreachable Code #2

I'm having a hard time identifying the issue with the following method I've written. It will not currently compile due to error "Not all code paths return a value":
private static int compareVersionNumbers(string installedVersion, string requiredVersion)
{
if (installedVersion.Equals(requiredVersion))
{
Console.WriteLine("Versions are identical.");
return 0;
}
else if (installedVersion != (requiredVersion))
{
// Split version strings into arrays.
List<string> versionArray = installedVersion.Split('.').ToList<string>();
List<string> otherVersionArray = requiredVersion.Split('.').ToList<string>();
int count = 0;
while ((count < versionArray.Count()) && (count < otherVersionArray.Count()))
{
// Fetch current version component
int currentPart = Convert.ToInt32(versionArray.ElementAt(count));
int otherPart = Convert.ToInt32(otherVersionArray.ElementAt(count));
if (currentPart > otherPart)
{
Console.WriteLine(installedVersion + " is greater than " + requiredVersion);
return 1;
break;
}
else if (currentPart < otherPart)
{
Console.WriteLine(installedVersion + " is less than " + requiredVersion);
return -1;
break;
}
count++;
}
}
}
In general, are there any helpful tools in VisualStudio's debugger for troubleshooting unreachable code?
You have one if and one else if statement. But you don't have an else statement which means if your all conditions are false then your function won't return value.Change your elseif statement to else statement if it's just the opposite of your if statement (which seems like that), or return a value end of your function.
The problem you get means that the compiler has found at least one way where your function will not return a value. These particular cases are the following:
No return value after the while loop. It might be that the while will not even run.
After the else if block put an else return -1;
Your function have 2 if clause and retrun instruction only inside if clause. You should have 1 else clause for the 2nd if clause.
I think the problem is the compiler analyzing your code in blocks.
And it find a block (the inner else if) that doesn't return the required integer
Also if all of the inner paths of the while returns something the compiler still complains because the else if block doesn't return anything
Let me show a contrived example based on your code above with some of the fixes proposed:
int Test()
{
int a = 10;
if(a < 10)
{
// Always false but the compiler is happy here
// because this block returns the integer
return 1;
}
else if(a==10)
{
// We always enter here but the compiler doesn't check at this point
// if the condition is true or not neither what happen inside the while block
// It looks at the else if and conclude that you don't return the integer
while(a < 20)
{
// Again, we know that we always enter the while block but
// the analysis is not executing our code and
// it is already been decided that something is wrong
if(a < 15)
return 2;
else if(a < 18)
return 3;
else
return 4; // Adding this else doens't make any difference
a++;
}
??????? here the compiler wants something to return
}
else
{
// happy here because the block returns the integer
// but, again, adding this else doesn't make any difference
return 5;
}
}
Still the error isn't gone away, for the compiler, the inner if else doesn't return an integer while our logic tells us that this is impossible
Turns out I simply needed another return after the if / if else if blocks:
private static int compareVersionNumbers(string installedVersion, string requiredVersion)
{
if (installedVersion.Equals(requiredVersion))
{
Console.WriteLine("Versions are identical.");
return 0;
}
else if (installedVersion != (requiredVersion))
{
// Split version strings into arrays.
List<string> versionArray = installedVersion.Split('.').ToList<string>();
List<string> otherVersionArray = requiredVersion.Split('.').ToList<string>();
int count = 0;
while ((count < versionArray.Count()) && (count < otherVersionArray.Count()))
{
// Fetch current version component
int currentPart = Convert.ToInt32(versionArray.ElementAt(count));
int otherPart = Convert.ToInt32(otherVersionArray.ElementAt(count));
if (currentPart > otherPart)
{
Console.WriteLine(installedVersion + " is greater than " + requiredVersion);
return 1;
break;
}
else if (currentPart < otherPart)
{
Console.WriteLine(installedVersion + " is less than " + requiredVersion);
return -1;
break;
}
count++;
}
}
return 0;
}

How to set a return value if array has some value which is not set

I have a code like this
int rpindex = allObjects.Find(new Guid(policyGuid));
if (rpindex != -1)
{
rp = (ResourcePolicy)allObjects.GetAt(rpindex);
}
and this is Find method
public virtual int Find(Guid guid)
{
try
{
for (int i=0; i<this.Count; i++)
{
if (guid.Equals(this[i].Guid))
{
return i;
}
}
}
catch(System.Exception exception)
{
SpoDebug.DebugTraceSevere(func, "Exception Occurred: " + exception.ToString() );
}
SpoDebug.DebugTraceVerbose(func, "no find. guid=" + guid.ToString());
return -1;
}
As of now the existing function Find() outcome is -1 or some integer value[i]. The -1 value will come in two situations , that is if the input is empty [ null value] and if the input is some value which is not in the database or in the current list, i need change here.That mean if the input to Find() is empty or null that time only it should return -1, otherwise if input has some value and it is not maching then it shud return return -2.SO there should be three outcomes one is -1 second is -2 and third is integer value ,Can any body guide me here
if i add else loop, i am not sure what return value i can use here other than -1, and integer value
Just place extra return statements, or am I missing something?
i.e.
try
{
for (int i=0; i<this.Count; i++)
{
if (guid.Equals(this[i].Guid))
{
return i;
}
}
return somethingElseHere;
}
just after the for loop check
if(i == this.Count) //i reached the end of the loop but no matches found
{
return -2;
}
I think it will be more readable to throw an exception in case the list is empty, right after the start of the method:
if (this.Count==0)
throw new InvalidArgumentException();
//rest as before
Having more than one integer value for error is very unclear.

Categories

Resources