c# recursive step method - c#

i'm trying to make a recursive method to check if the last number (always 0) in an integer array (with all > 0 integers) is reachable by increasing (or decreasing) the index of the array with the value of the array element of the current index, while staying within the bounds of the array.
example:
say we have the following array, and the start index == 0:
int[] arr = {3, 6, 4, 1, 3, 4, 2, 5, 3, 0};
step 0 : index = 0, value = 3
step 1 : index = 3, value = 1
step 2 : index = 4, value = 3
step 3 : index = 7, value = 5
step 4 : index = 2, value = 4
step 5 : index = 6, value = 2
step 6 : index = 8, value = 3
step 7 : index = 5, value = 4
step 8 : index = 9, value = 0 -- end
my current code:
static bool Solveable(int index, int[] arr)
{
if (arr[index] == 0)
return true;
if (index + arr[index] < arr.Length)
return Solveable(index + arr[index], arr);
if (index - arr[index] >= 0)
return Solveable(index - arr[index], arr);
return false;
}
the thing with this is that it will only work with solveable cases, all other cases will result in a stackoverflow exception.
how would i be able to solve this problem WITHOUT using global variables to store previous results?
EDIT:
I can only use the parameters: (int index, int[] arr)

You are correct about stack overflow for unsolvable cases: the recursive code would behave like a dog chasing its own tail until, until it reaches the stack limit.
Fortunately, you can break this infinite recursion by observing that you have at most N steps to reach the end of the array, if you are to reach it at all. Therefore, you could add a third parameter to indicate how many steps you have taken already. If you reach zero before the number of steps passes N, you have a path; otherwise, you don't have a path.
static bool Solveable(int index, int[] arr, int stepsSoFar) {
if (arr[index] == 0)
return true;
if (stepsSoFar > arr.Length)
return false;
...
// The rest of your code; pass stepsSoFar+1 down to the next level
}
I can only use the two parameters i included in my code snippet
You can mark the indexes that you have visited in the arr itself by placing -1 into them. In order to preserve array's original state, store the old value in a local variable, and set it back into arr before returning:
static bool Solveable(int index, int[] arr) {
if (arr[index] == 0)
return true;
if (arr[index] == -1)
return false;
int oldArrAtIndex = arr[index];
arr[index] = -1;
try {
...
// The rest of your code
} finally {
arr[index] = oldArrAtIndex;
}
}

Pass a third argument that tracks the indices you've already traveled. Stop processing if you've already tried the current index.
Also, you may want to make a change to account for travelling in either direction:
var solvable = false;
//...
if (index + arr[index] < arr.Length)
solvable = Solveable(index + arr[index], arr);
if (!solvable && index - arr[index] >= 0)
solvable = Solveable(index - arr[index], arr);
return solvable;

School assignment or not, lesson on recursion without all the added complexity.
private static void Main()
{
int[] array = {3, 6, 4, 1, 3, 4, 2, 5, 3, 0};
Console.WriteLine(IsSolveable(array));
Console.ReadKey();
}
private static bool IsSolveable(int[] array)
{
if (array.Length <= 1)
return false;
int index = array[0];
if (index < array.Length && array[index] == 0)
return true;
// this is where the recursion magic happens
return IsSolveable(array.Skip(1).ToArray());
}

Instead of passing int index, you can pass an array, containing currently visited indexes, and if your next index is contained inside of array of visited, then you just break and return false.
High level idea of code is:
static void Main(string[] args)
{
int[] arr = { 3, 6, 4, 1, 3, 4, 2, 5, 3, 0 };
var result = Solveable(new[] {0}, arr);
Console.WriteLine(result);
Console.ReadLine();
}
static bool Solveable(int[] path, int[] arr)
{
var index = path.Last();
if (arr[index] == 0)
return true;
if (index + arr[index] < arr.Length)
{
var nextIndex = index + arr[index];
var nextStepPath = path.Concat(new[] { nextIndex }).ToArray();
if (path.Contains(nextIndex))
return false;
return Solveable(nextStepPath, arr);
}
if (index - arr[index] >= 0)
{
var nextIndex = index - arr[index];
var nextStepPath = path.Concat(new[] {nextIndex}).ToArray();
if (path.Contains(nextIndex))
return false;
return Solveable(nextStepPath, arr);
}
return false;
}
It need a bit of cleanup, but gives you high-level idea, and makes use of only 2 parameters without introducing classes/structs for your array.

Here is an algorithm that does not modify the state:
static bool Solveable(int index, int[] arr)
{
if (arr[index] == 0)
return true;
int nextIndex = index + arr[index];
if (nextIndex < arr.Length)
return Solveable(nextIndex, arr);
// Search for a previous index that leads to a different path
int prevIndex;
while (true)
{
prevIndex = index - arr[index];
if (prevIndex < 0)
return false; // Not found, we are done
if (prevIndex + arr[prevIndex] != index)
return Solveable(prevIndex, arr); // Process the other path
index = prevIndex; // Keep searching
}
}
The essential part is the non recursive back step processing part (see the comments inside the code).

Related

inserting element into a list, if condition is met with C#

How to insert some number into the middle of the list, if there is no such number present?
In the example below I'm trying to insert number 4
List<int> list1 = new List<int>(){ 0, 1, 2, 3, 5, 6 };
int must_enter = 4;
if (!list1.Contains(must_enter))
{
list1.Add(must_enter);
}
As the result number will be entered at the end of the list, but I want it right after 3 (before 5).
please note that due to project's specifics I can't use sorted list, but all numbers in the list are guaranteed to be in ascending order (0,2,6,9,10,...)
EDIT: I knew about an error and that's what I did:
List<int> list0 = new List<int>() { 1, 2, 3, 5, 6 };
int must_enter = 7;
if (!list0.Contains(must_enter))
{
if (must_enter < list0.Max())
{
int result = list0.FindIndex(item => item > must_enter || must_enter > list0.Max());
list0.Insert(result, must_enter);
}
else
{
list0.Add(must_enter);
}
}
edit2: anyway I've switched to BinarySearch method due to several factors. Everyone thanks for your help!
You could do something like this:
int index = list1.BinarySearch(must_enter);
if (index < 0)
list1.Insert(~index, must_enter);
This way you will keep the list sorted with the best possible performance.
You can do:
list1.Add(must_enter);
And then order the list:
list1 = list1.OrderBy(n => n).ToList();
The result will be:
0, 1, 2, 3, 4, 5, 6
EDIT:
Or use an extesion method:
static class Utility
{
public static void InsertElement(this List<int> list, int n)
{
if(!list.Contains(n))
{
for(int i = 0; i < list.Count; i++)
{
if(list[i] > n)
{
list.Insert(i-1, n);
break;
}
if(i == list.Count - 1)
list.Add(n);
}
}
}
}
And then:
list1.InsertElement(must_enter);
You are looking for
list1.Insert(index, must_enter);
To insert an element at a specific index rather than at the end of the list.
You'll have to find the index to insert at first which is easily done with a binary search. Start with the value in the middle of the list and compare it to your number to insert. If it's greater, search the lower half of the list, if it's more, search the upper half of the list. Repeat the process, dividing the list in half each time until you find the spot where the item before is less than the one you are inserting and the item after is more than the one you are inserting. (edit: of course, if you list is always very small, it's probably less hassle just to iterate through the list from the beginning to find the right spot!)
List<int> list1 = new List<int>() { 0, 1, 2, 3, 5, 6 };
int must_enter = 4;
for (int i = 0; i < list1.Count; i++)
{
if (must_enter >= list1[i])
{
list1.Insert(i + 1, must_enter);
}
}
Edit: I like sarwar026, implementation better.
list1.Insert(4, 4)
List<T>.Insert Method - Inserts an element into the List at the specified index.
Quick Note-
the Insert instance method on the List type does not have good performance in many cases. because for Insert, list has to adjust the following elements.
here is the original post from where i got this answer try it out may help you : Finding best position for element in list
List<int> list = new List<int>{0,2,6,9,10};
for (int i = 0; i < list1.Count; i++)
{
int index = list.BinarySearch(i);
if( i < 0)
{
int insertIndex = ~index;
list.Insert(insertIndex, i);
}
}
just for one missing element as op needs
int index = list.BinarySearch(4);
if( index < 0)
{
int insertIndex = ~index;
list.Insert(insertIndex, 4);
}
or
List<int> list1 = new List<int>() { 0,2,6,9,10 };
int must_enter = 4;
for (int i = 0; i < list1.Count; i++)
{
if (!list1.Contains(i))
{
list1.Insert(i , i);
}
}
just for one element as op needs
if (!list1.Contains(4))
{
list1.Insert(4 , 4);
}
List<int> list1 = new List<int>(){ 0, 1, 2, 3, 5, 6 };
int must_enter = 4;
if (!list1.Contains(must_enter))
{
int result = list.FindIndex(item => item > must_enter);
if(result!=-1)
list1.Insert(result, must_enter);
else // must_enter is not found
{
if(must_enter > list.Max()) // must_enter > max value of list
list1.Add(must_enter);
else if(must_enter < list.Min()) // must_enter < min value of list
list1.Insert(0, must_enter);
}
}
First, find the index of the number which is greater than must_enter(4) and then insert the must_enter to that position
if (!list1.Contains(must_enter))
{
SortedSet<int> sorted = new SortedSet<int>( list1 );
sorted.Add( must_enter );
list1 = sorted.ToList();
}

How to determine that one array is a part of another one?

For instance: I have array
var src = new byte[] {1, 2, 3, 4, 5};
var tag = new byte[] {3, 4};
Who know fast method to find index of tag's array?
I need something as following:
int FindIndexOfSeq(byte[] src, byte[] sequence);
a sequence can be in more than one times in src.
Solution: How to find index of sublist in list?
The best you can get is O(m), but that I slightly complex implementation. If you satisfy with a solution that has O(m*n) as worst case you can go with the solution below. If your sequences are ordered and the starting item in the tag array is only present one time in src this will also result in O(m).
class Program
{
static void Main(string[] args)
{
var src = new byte[] { 1, 2, 3, 4, 5 };
var tag = new byte[] { 3, 4 };
var index = FindIndexOfSeq(src, tag);
Console.WriteLine(index);
Console.ReadLine();
}
static int FindIndexOfSeq<T>(T[] src, T[] seq)
{
int index = -1;
for (int i = 0; i < src.Length - seq.Length + 1; i++)
{
bool foundSeq = true;
for (int j = 0; j < seq.Length; j++)
{
foundSeq = foundSeq && src[i + j].Equals(seq[j]);
}
if (foundSeq)
{
index = i;
break;
}
}
return index;
}
}
I assumed the sequence have to be in that order and I have only compiled it in firefox, so not sure if it works :). Also, I made it generic so it handles any type of arrays not just bytes.
UPDATE: The updated code compiles and work... or my simple test worked.
Here's one way to the get the index
for (int i = 0; i < (src.Length - tag.Length); i++ )
{
if (tag.SequenceEqual(src.Skip(i).Take(tag.Length)))
Console.WriteLine("It's at position " + i);
}
Unfortunately it's very slow.
If you just want to know if all of items in tag can be found in src (in any order) then
var src = new byte[] { 1, 2, 3, 4, 5 };
var tag = new byte[] { 4, 3 };
if (src.Intersect(tag).Count() == tag.Length)
Console.WriteLine("tag can be found in src!");
int FindIndexOfSeq<T>(byte[] src, byte[] tag)
{
Int32 tagCount = tag.Count();
// If `tag` is not empty and `src` contains `tag`
if (tagCount > 0 && src.Intersect(tag).Count() == tagCount)
{
// Find index of first element in `tag`
Int32 tagStartIndex = Array.IndexOf(src, tag.First());
// Get the matching slice of `tag` from `src`
var newSrc = src.Skip(tagStartIndex).Take(tag.Count()).ToList();
// Zip them together using their difference
var sum = Enumerable.Zip(tag, newSrc, (i1, i2) => Convert.ToInt32(i2 - i1)).Sum();
// If total of their differences is zero, both sequences match
if (sum == 0)
{
// return starting index of `tag` in `src`
return tagStartIndex;
}
}
// return `Not Found`
return -1;
}
This task is equal to searching substring in string. For this you may use any KMP algorithm for better performance:
http://exclusiveminds.com/2009/12/09/kmp-string-searching-algorithm-in-c/
Solution found.
How to find index of sublist in list?

Find the smallest window of input array that contains all the elements of query array

Problem: Given an input array of integers of size n, and a query array of integers of size k, find the smallest window of input array that contains all the elements of query array and also in the same order.
I have tried below approach.
int[] inputArray = new int[] { 2, 5, 2, 8, 0, 1, 4, 7 };
int[] queryArray = new int[] { 2, 1, 7 };
Will find the position of all query array element in inputArray.
public static void SmallestWindow(int[] inputArray, int[] queryArray)
{
Dictionary<int, HashSet<int>> dict = new Dictionary<int, HashSet<int>>();
int index = 0;
foreach (int i in queryArray)
{
HashSet<int> hash = new HashSet<int>();
foreach (int j in inputArray)
{
index++;
if (i == j)
hash.Add(index);
}
dict.Add(i, hash);
index = 0;
}
// Need to perform action in above dictionary.??
}
I got following dictionary
int 2--> position {1, 3}
int 1 --> position {6}
int 7 --> position {8}
Now I want to perform following step to findout minimum window
Compare int 2 position to int 1 position. As (6-3) < (6-1)..So I will store 3, 6 in a hashmap.
Will compare the position of int 1 and int 7 same like above.
I cannot understand how I will compare two consecutive value of a dictionary. Please help.
The algorithm:
For each element in the query array, store in a map M (V → (I,P)), V is the element, I is an index into the input array, P is the position in the query array. (The index into the input array for some P is the largest such that query[0..P] is a subsequence of input[I..curr])
Iterate through the array.
If the value is the first term in the query array: Store the current index as I.
Else: Store the value of the index of the previous element in the query array, e.g. M[currVal].I = M[query[M[currVal].P-1]].I.
If the value is the last term: Check if [I..curr] is a new best.
Complexity
The complexity of this is O(N), where N is the size of the input array.
N.B.
This code expects that no elements are repeated in the query array. To cater for this, we can use a map M (V → listOf((I,P))). This is O(NhC(Q)), where hC(Q) is the count of the mode for the query array..
Even better would be to use M (V → listOf((linkedList(I), P))). Where repeated elements occur consecutively in the query array, we use a linked list. Updating those values then becomes O(1). The complexity is then O(NhC(D(Q))), where D(Q) is Q with consecutive terms merged.
Implementation
Sample java implementation is available here. This does not work for repeated elements in the query array, nor do error checking, etc.
I don't see how using HashSet and Dictionary will help you in this. Were I faced with this problem, I'd go about it quite differently.
One way to do it (not the most efficient way) is shown below. This code makes the assumption that queryArray contains at least two items.
int FindInArray(int[] a, int start, int value)
{
for (int i = start; i < a.Length; ++i)
{
if (a[i] == value)
return i;
}
return -1;
}
struct Pair
{
int first;
int last;
}
List<Pair> foundPairs = new List<Pair>();
int startPos = 0;
bool found = true;
while (found)
{
found = false;
// find next occurrence of queryArray[0] in inputArray
startPos = FindInArray(inputArray, startPos, queryArray[0]);
if (startPos == -1)
{
// no more occurrences of the first item
break;
}
Pair p = new Pair();
p.first = startPos;
++startPos;
int nextPos = startPos;
// now find occurrences of remaining items
for (int i = 1; i < queryArray.Length; ++i)
{
nextPos = FindInArray(inputArray, nextPos, queryArray[i]);
if (nextPos == -1)
{
break; // didn't find it
}
else
{
p.last = nextPos++;
found = (i == queryArray.Length-1);
}
}
if (found)
{
foundPairs.Add(p);
}
}
// At this point, the foundPairs list contains the (start, end) of all
// sublists that contain the items in order.
// You can then iterate through that list, subtract (last-first), and take
// the item that has the smallest value. That will be the shortest sublist
// that matches the criteria.
With some work, this could be made more efficient. For example, if 'queryArray' contains [1, 2, 3] and inputArray contains [1, 7, 4, 9, 1, 3, 6, 4, 1, 8, 2, 3], the above code will find three matches (starting at positions 0, 4, and 8). Slightly smarter code could determine that when the 1 at position 4 is found, since no 2 was found prior to it, that any sequence starting at the first position would be longer than the sequence starting at position 4, and therefore short-circuit the first sequence and start over at the new position. That complicates the code a bit, though.
You want not a HashSet but a (sorted) tree or array as the value in the dictionary; the dictionary contains mappings from values you find in the input array to the (sorted) list of indices where that value appears.
Then you do the following
Look up the first entry in the query. Pick the lowest index where it appears.
Look up the second entry; pick the lowest entry greater than the index of the first.
Look up the third; pick the lowest greater than the second. (Etc.)
When you reach the last entry in the query, (1 + last index - first index) is the size of the smallest match.
Now pick the second index of the first query, repeat, etc.
Pick the smallest match found from any of the starting indices.
(Note that the "lowest entry greater" is an operation supplied with sorted trees, or can be found via binary search on a sorted array.)
The complexity of this is approximately O(M*n*log n) where M is the length of the query and n is the average number of indices at which a given value appears in the input array. You can modify the strategy by picking that query array value that appears least often for the starting point and going up and down from there; if there are k of those entries (k <= n) then the complexity is O(M*k*log n).
After you got all the positions(indexes) in the inputArray:
2 --> position {0,2} // note: I change them to 0-based array
1 --> position {5,6} // I suppose it's {5,6} to make it more complex, in your code it's only {5}
7 --> position {7}
I use a recursion to get all possible paths. [0->5->7] [0->6->7] [2->5->7] [2->6->7]. The total is 2*2*1=4 possible paths. Obviously the one who has Min(Last-First) is the shortest path(smallest window), those numbers in the middle of the path don't matter. Here comes the code.
struct Pair
{
public int Number; // the number in queryArray
public int[] Indexes; // the positions of the number
}
static List<int[]> results = new List<int[]>(); //store all possible paths
static Stack<int> currResult = new Stack<int>(); // the container of current path
static int[] inputArray, queryArray;
static Pair[] pairs;
After the data structures, here is the Main.
inputArray = new int[] { 2, 7, 1, 5, 2, 8, 0, 1, 4, 7 }; //my test case
queryArray = new int[] { 2, 1, 7 };
pairs = (from n in queryArray
select new Pair { Number = n, Indexes = inputArray.FindAllIndexes(i => i == n) }).ToArray();
Go(0);
FindAllIndexes is an extension method to help find all the indexes.
public static int[] FindAllIndexes<T>(this IEnumerable<T> source, Func<T,bool> predicate)
{
//do necessary check here, then
Queue<int> indexes = new Queue<int>();
for (int i = 0;i<source.Count();i++)
if (predicate(source.ElementAt(i))) indexes.Enqueue(i);
return indexes.ToArray();
}
The recursion method:
static void Go(int depth)
{
if (depth == pairs.Length)
{
results.Add(currResult.Reverse().ToArray());
}
else
{
var indexes = pairs[depth].Indexes;
for (int i = 0; i < indexes.Length; i++)
{
if (depth == 0 || indexes[i] > currResult.Last())
{
currResult.Push(indexes[i]);
Go(depth + 1);
currResult.Pop();
}
}
}
}
At last, a loop of results can find the Min(Last-First) result(shortest window).
Algorithm:
get all indexes into the inputArray
of all queryArray values
order them ascending by index
using each index (x) as a starting
point find the first higher index
(y) such that the segment
inputArray[x-y] contains all
queryArray values
keep only those segments that have the queryArray items in order
order the segments by their lengths,
ascending
c# implementation:
First get all indexes into the inputArray of all queryArray values and order them ascending by index.
public static int[] SmallestWindow(int[] inputArray, int[] queryArray)
{
var indexed = queryArray
.SelectMany(x => inputArray
.Select((y, i) => new
{
Value = y,
Index = i
})
.Where(y => y.Value == x))
.OrderBy(x => x.Index)
.ToList();
Next, using each index (x) as a starting point find the first higher index (y) such that the segment inputArray[x-y] contains all queryArray values.
var segments = indexed
.Select(x =>
{
var unique = new HashSet<int>();
return new
{
Item = x,
Followers = indexed
.Where(y => y.Index >= x.Index)
.TakeWhile(y => unique.Count != queryArray.Length)
.Select(y =>
{
unique.Add(y.Value);
return y;
})
.ToList(),
IsComplete = unique.Count == queryArray.Length
};
})
.Where(x => x.IsComplete);
Now keep only those segments that have the queryArray items in order.
var queryIndexed = segments
.Select(x => x.Followers.Select(y => new
{
QIndex = Array.IndexOf(queryArray, y.Value),
y.Index,
y.Value
}).ToArray());
var queryOrdered = queryIndexed
.Where(item =>
{
var qindex = item.Select(x => x.QIndex).ToList();
bool changed;
do
{
changed = false;
for (int i = 1; i < qindex.Count; i++)
{
if (qindex[i] <= qindex[i - 1])
{
qindex.RemoveAt(i);
changed = true;
}
}
} while (changed);
return qindex.Count == queryArray.Length;
});
Finally, order the segments by their lengths, ascending. The first segment in the result is the smallest window into inputArray that contains all queryArray values in the order of queryArray.
var result = queryOrdered
.Select(x => new[]
{
x.First().Index,
x.Last().Index
})
.OrderBy(x => x[1] - x[0]);
var best = result.FirstOrDefault();
return best;
}
test it with
public void Test()
{
var inputArray = new[] { 2, 1, 5, 6, 8, 1, 8, 6, 2, 9, 2, 9, 1, 2 };
var queryArray = new[] { 6, 1, 2 };
var result = SmallestWindow(inputArray, queryArray);
if (result == null)
{
Console.WriteLine("no matching window");
}
else
{
Console.WriteLine("Smallest window is indexes " + result[0] + " to " + result[1]);
}
}
output:
Smallest window is indexes 3 to 8
Thank you everyone for your inputs. I have changed my code a bit and find it working. Though it might not be very efficient but I'm happy to solve using my head :). Please give your feedback
Here is my Pair class with having number and position as variable
public class Pair
{
public int Number;
public List<int> Position;
}
Here is a method which will return the list of all Pairs.
public static Pair[] GetIndex(int[] inputArray, int[] query)
{
Pair[] pairList = new Pair[query.Length];
int pairIndex = 0;
foreach (int i in query)
{
Pair pair = new Pair();
int index = 0;
pair.Position = new List<int>();
foreach (int j in inputArray)
{
if (i == j)
{
pair.Position.Add(index);
}
index++;
}
pair.Number = i;
pairList[pairIndex] = pair;
pairIndex++;
}
return pairList;
}
Here is the line of code in Main method
Pair[] pairs = NewCollection.GetIndex(array, intQuery);
List<int> minWindow = new List<int>();
for (int i = 0; i <pairs.Length - 1; i++)
{
List<int> first = pairs[i].Position;
List<int> second = pairs[i + 1].Position;
int? temp = null;
int? temp1 = null;
foreach(int m in first)
{
foreach (int n in second)
{
if (n > m)
{
temp = m;
temp1 = n;
}
}
}
if (temp.HasValue && temp1.HasValue)
{
if (!minWindow.Contains((int)temp))
minWindow.Add((int)temp);
if (!minWindow.Contains((int)temp1))
minWindow.Add((int)temp1);
}
else
{
Console.WriteLine(" Bad Query array");
minWindow.Clear();
break;
}
}
if(minWindow.Count > 0)
{
Console.WriteLine("Minimum Window is :");
foreach(int i in minWindow)
{
Console.WriteLine(i + " ");
}
}
It is worth noting that this problem is related to the longest common subsequence problem, so coming up with algorithms that run in better than O(n^2) time in the general case with duplicates would be challenging.
Just in case someone is interested in C++ implementation with O(nlog(k))
void findMinWindow(const vector<int>& input, const vector<int>& query) {
map<int, int> qtree;
for(vector<int>::const_iterator itr=query.begin(); itr!=query.end(); itr++) {
qtree[*itr] = 0;
}
int first_ptr=0;
int begin_ptr=0;
int index1 = 0;
int queptr = 0;
int flip = 0;
while(true) {
//check if value is in query
if(qtree.find(input[index1]) != qtree.end()) {
int x = qtree[input[index1]];
if(0 == x) {
flip++;
}
qtree[input[index1]] = ++x;
}
//remove all nodes that are not required and
//yet satisfy the all query condition.
while(query.size() == flip) {
//done nothing more
if(queptr == input.size()) {
break;
}
//check if queptr is pointing to node in the query
if(qtree.find(input[queptr]) != qtree.end()) {
int y = qtree[input[queptr]];
//more nodes and the queue is pointing to deleteable node
//condense the nodes
if(y > 1) {
qtree[input[queptr]] = --y;
queptr++;
} else {
//cant condense more just keep that memory
if((!first_ptr && !begin_ptr) ||
((first_ptr-begin_ptr)>(index1-queptr))) {
first_ptr=index1;
begin_ptr=queptr;
}
break;
}
} else {
queptr++;
}
}
index1++;
if(index1==input.size()) {
break;
}
}
cout<<"["<<begin_ptr<<" - "<<first_ptr<<"]"<<endl;
}
here the main for calling it.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main() {
vector<int> input;
input.push_back(2);
input.push_back(5);
input.push_back(2);
input.push_back(8);
input.push_back(0);
input.push_back(1);
input.push_back(4);
input.push_back(7);
vector<int> query1;
query1.push_back(2);
query1.push_back(8);
query1.push_back(0);
vector<int> query2;
query2.push_back(2);
query2.push_back(1);
query2.push_back(7);
vector<int> query3;
query3.push_back(1);
query3.push_back(4);
findMinWindow(input, query1);
findMinWindow(input, query2);
findMinWindow(input, query3);
}

Finding the last index of an array

How do you retrieve the last element of an array in C#?
LINQ provides Last():
csharp> int[] nums = {1,2,3,4,5};
csharp> nums.Last();
5
This is handy when you don't want to make a variable unnecessarily.
string lastName = "Abraham Lincoln".Split().Last();
With C# 8:
int[] array = { 1, 3, 5 };
var lastItem = array[^1]; // 5
The array has a Length property that will give you the length of the array. Since the array indices are zero-based, the last item will be at Length - 1.
string[] items = GetAllItems();
string lastItem = items[items.Length - 1];
int arrayLength = array.Length;
When declaring an array in C#, the number you give is the length of the array:
string[] items = new string[5]; // five items, index ranging from 0 to 4.
New in C# 8.0 you can use the so-called "hat" (^) operator! This is useful for when you want to do something in one line!
var mystr = "Hello World!";
var lastword = mystr.Split(" ")[^1];
Console.WriteLine(lastword);
// World!
instead of the old way:
var mystr = "Hello World";
var split = mystr.Split(" ");
var lastword = split[split.Length - 1];
Console.WriteLine(lastword);
// World!
It doesn't save much space, but it looks much clearer (maybe I only think this because I came from python?). This is also much better than calling a method like .Last() or .Reverse() Read more at MSDN
Edit: You can add this functionality to your class like so:
public class MyClass
{
public object this[Index indx]
{
get
{
// Do indexing here, this is just an example of the .IsFromEnd property
if (indx.IsFromEnd)
{
Console.WriteLine("Negative Index!")
}
else
{
Console.WriteLine("Positive Index!")
}
}
}
}
The Index.IsFromEnd will tell you if someone is using the 'hat' (^) operator
Use Array.GetUpperBound(0). Array.Length contains the number of items in the array, so reading Length -1 only works on the assumption that the array is zero based.
To compute the index of the last item:
int index = array.Length - 1;
Will get you -1 if the array is empty - you should treat it as a special case.
To access the last index:
array[array.Length - 1] = ...
or
... = array[array.Length - 1]
will cause an exception if the array is actually empty (Length is 0).
Also, starting with .NET Core 3.0 (and .NET Standard 2.1) (C# 8) you can use Index type to keep array's indexes from end:
var lastElementIndexInAnyArraySize = ^1;
var lastElement = array[lastElementIndexInAnyArraySize];
You can use this index to get last array value in any length of array. For example:
var firstArray = new[] {0, 1, 1, 2, 2};
var secondArray = new[] {3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5};
var index = ^1;
var firstArrayLastValue = firstArray[index]; // 2
var secondArrayLastValue = secondArray[index]; // 5
For more information check documentation
The following will return NULL if the array is empty, else the last element.
var item = (arr.Length == 0) ? null : arr[arr.Length - 1]
say your array is called arr
do
arr[arr.Length - 1]
Is this worth mentioning?
var item = new Stack(arr).Pop();
Array starts from index 0 and ends at n-1.
static void Main(string[] args)
{
int[] arr = { 1, 2, 3, 4, 5 };
int length = arr.Length - 1; // starts from 0 to n-1
Console.WriteLine(length); // this will give the last index.
Console.Read();
}
static void Main(string[] args)
{
int size = 6;
int[] arr = new int[6] { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < size; i++)
{
Console.WriteLine("The last element is {0}", GetLastArrayIndex(arr));
Console.ReadLine();
}
}
//Get Last Index
static int GetLastArrayIndex(int[] arr)
{
try
{
int lastNum;
lastNum = arr.Length - 1;
return lastNum;
}
catch (Exception ex)
{
return 0;
}
}
This is simplest and works on all versions.
int[] array = { 1, 3, 5 };
int last = array[array.Length - 1];
Console.WriteLine(last);
// 5

Using arrays with recursion

Now that I am using recursion to calcuate the sum of numbers, I want to do something slightly different. The following is my code that will sum the numbers 1,2,3,4,5. How would I modify my code to place the numbers 1, 2, 3, 4, 5 into an array and then use it in the recursion method? I have tried so many different attempts and I am apparently missing something. I know that in the recursion method, that I want to use the Length property of the array to control it.
Susan
static void Main(string[] args)
{
Console.WriteLine(Sum(5));
Console.Read();
}
static int Sum(int value)
{
if (value > 0)
{
return value + Sum(value - 1);
}
else
{
return 0;
}
}
let seq = [1;2;3;4;5]
let rec samp nums =
match nums with
| [] -> 0
| h::t -> h + samp t
static int Sum(int[] a, int index = 0)
{
if (a[index] == a[a.Length - 1])
{
return a[a.Length - 1];
}
return a[index] + Sum(a, index + 1);
}
static void Main()
{
int[] arr = {1, 2, 3, 9, 15};
Console.WriteLine(Sum(arr));
}
I'm a beginner too but this is my solution and it works for me.
What about using a Stack?:
Stack<int> stack = new Stack<int>(new int [] {1,2,3,4,5});
Console.WriteLine(SumStack(stack));
public static int SumStack(Stack<int> input)
{
return input.Count > 0 ? input.Pop() + SumStack(input) : 0;
}
Sniff, sniff, smells like homework to me.
However, a hint. Adding all the elements of an array of length 'n' is the same as adding all the elements of an array of length 'n-1', then adding the value of element 'n'.
The result of adding all the elements of an array of length '1' is just the value of the one element
I believe that you need to pass the array and the index in your Sum function to control the recursivity.
Of if your no good with lambda expressions or you only have .net 2.0, this is simple enough;
static void Main(string[] args)
{
int[] myArray = new int[5] {1,2,3,4,5 };
Console.WriteLine(Sum1(myArray));
Console.Read();
}
private static int Sum1(int[] myArray)
{
if (myArray.Length > 0)
{
int lengthZeroAdjusted = myArray.Length - 1;
int element = myArray[lengthZeroAdjusted];
Array.Resize<int>(ref myArray, lengthZeroAdjusted);
return element + Sum1(myArray);
}
else
{
return 0;
}
}
You're wanting to perform an operation that is commonly referred to as "fold" a.k.a. "reduce".
Luckily, the .NET team did your (home)work for you!
static int sum(int[] values)
{
return values.Aggregate<int>((hd, tl) => hd + tl);
}
You can rewrite it for easier readability if you like. ;)
EDIT: usage example
int[] values = new int[]{1,2,3,4,5};
Console.WriteLine(sum(values));
Recursion essentially means doing the small part, and giving the larger part to somebody else.
Now if you have to 'n' elements of array, you ask somebody to give you sum of last n-1 elements,
and just first one yourself ... just handle the case where there is nothing to be done ...
a pseudo code would be :
sum array start_index = if ( start_index >= length(array) ) return 0
else return array[start_index] = sum array (start_index + 1)
print (sum array 0 )

Categories