Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
We are doing currently C# in Arrays.And I have to get the second largest number from the Input. But i dont know the function of this code. Can someone explain this for me. For the whole code please have a view here
Code to explain:
static int ztgzahl(int[] ZL)
{
int MinZ = Int16.MinValue;
int MaxZ = Int16.MinValue;
for(int i = 0; i < ZL.Length; i++)
{
if (ZL[i] > MaxZ)
{
MinZ = MaxZ;
MaxZ = ZL[i];
}
else if (ZL[i] > MinZ)
{
MinZ = ZL[i];
}
}
return MinZ;
}
This code itterates over the array, trying to find the two highest numbers. However it uses completely messed up Variable names MinZ and MaxZ for that. It should be MaxA and MaxB or something like that.
And for each number it checks if the number is larger then the current MaxZ (the highest). If yes, it hands the previous second largest down to MinZ. If not it additionally checks if it just smaler then MinZ (as a number can be bigger the MaxZ, and still smaler then MinZ).
I am not 100% sure this works. Personally I would just sort the Arrays and get the 2nd from the right side. Or if this was a Database, get the 2nd from Bottom using a query. This kind of logic is notoriously prone for messing up.
Int16.MinValue
This will get the minimal value allowed for Int16
Then it iterates the ZL array, if it finds a value highest than the highest value found, it replaces the variable value, if not, it checks if it's place is possible as second highest value.
Please find my comments against the snippet below
static int ztgzahl(int[] ZL)
{
int MinZ = Int16.MinValue; // Min value of Int16 is -32768
int MaxZ = Int16.MinValue;
for(int i = 0; i < ZL.Length; i++) //Iterating over each index of array
{
if (ZL[i] > MaxZ) //If current element is greater than MaxZ
{
MinZ = MaxZ; //MinZ remainsthe same
MaxZ = ZL[i]; //MaxZ is the current element
}
else if (ZL[i] > MinZ) //If current element is greater than MinZ
{
MinZ = ZL[i]; //MinZ is current element
}
}
return MinZ;
}
Based on the full snipet, there will not be any negative elements in the array. So considering a short array of 4 elements {3,1,5,7}
1st Iteration:
Both MinZ and MaxZ = -1
MinZ = -1
MaxZ = 3
2nd Interation:
MinZ = 1
3rd Iteration:
MinZ = 3
MaxZ = 5
4th Iteration:
MinZ = 5
MaxZ = 7
Therefore the second largest element is 5, which is returned by MinZ
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have got a "project" where I am only allowed to use arrays. In this project, I have to read data from a txt file then for example find the second-best lap time among runners and etc.
I can always calculate the correct answer, but I am not sure about my array management.
As you know, in C# you have to provide the length of the array at initialization. Since there are tasks where I don't know the size of the array what I did was declare a far bigger array then use this function:
private static string[] ArraySimplyfier(string[] strs, int index)
{
string[] returnStr = new string[index];
for (int i = 0; i < returnStr.Length; i++)
{
returnStr[i] = strs[i];
}
return returnStr;
}
As you can see it "clears" the nulls from the array, but the thing is I have to create it for every type of array which is not ideal. Do you have any other ideas for my problem?
Creating new, bigger arrays and copying is the way to go. You are on the right track there. This is basically what List is doing under the hood (in an optimized way).
If you need this for multiple types, you could look into generic methods. Generics allow you to specify classes and methods for multiple types.
A List will double in size when it gets too small, you can do the same. Check the "Add/EnsureCapacity" implementation for List on github.
// Adds the given object to the end of this list. The size of the list is
// increased by one. If required, the capacity of the list is doubled
// before adding the new element.
//
public void Add(T item) {
if (_size == _items.Length) EnsureCapacity(_size + 1);
_items[_size++] = item;
_version++;
}
// Ensures that the capacity of this list is at least the given minimum
// value. If the currect capacity of the list is less than min, the
// capacity is increased to twice the current capacity or to min,
// whichever is larger.
private void EnsureCapacity(int min) {
if (_items.Length < min) {
int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
if (newCapacity < min) newCapacity = min;
Capacity = newCapacity;
}
}
So your question seems to be "when filtering an array, how do I know the number of elements on beforehand, to get the size of the target array?" - you don't.
Either loop twice over the source array, once to get the count and then do the copy, or start with an equally sized array, keep the count and truncate the array by copying it to a new one with the size capped to the number of results.
You can use generics. That way u have one method for every array type.
Your method would look like this:
private static T[] ArraySimplyfier<T>(T[] array, int index)
{
T[] result = new T[index];
for (int i = 0; i < result.Length; i++)
{
result[i] = array[i];
}
return result;
}
and u can call this method like this:
//example for a string array
ArraySimplyfier<string>(new string[45], 17); //replace 'new string[45]' with your array
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Hi I need to work out the average of 10 integers stored in a database.
This is what I've got so far.
private void getAverage()
{
StudentsDataSet.StudentsRow courseMarks = studentsDataSet.Students.Course[10];
average = 0;
int[] array;
for (int index = 0; index < 10 ; index++)
{
average += array[index];
}
average = average / 10;
averageBox.Text = average.ToString();
}
As you can see I have no idea what I'm doing... any pointers??
There are a couple of issues with your code, which I will address one by one:
You are always getting the data from row 11 of your data table (studentsDataSet.Students.Course[10]). That's probably not what you want.
You are declaring your array but you are not initializing it.
You need to fill the array before you loop over it.
You are repeating the number of courses (10) in many places in your code (e.g. the for loop and the divisor of the average). This will be a source of errors when the number of courses changes.
Be careful to choose good names for your variables. average should be sum (that's what it actually stores) and array is a poor choice, because it does not describe the content of the variable, but its format.
According to the C# naming convention methods are in PascalCase.
Here is some code that will do the job. I have added comments to explain exactly what is happening:
//The method that will add the average to the text box. You need to provide the row index.
//One common way to get the row index would be the SelectedIndex of your data grid
private void GetAverage(int rowIndex)
{
//Get the row whose data you want to process
DataRow courseMarks = studentsDataSet.Students.Rows[rowIndex];
//Initialize an array with the names of the source columns
string[] courseColumnNames = { "Course1", "Course2", "Course3", "Course4", "Course5",
"Course6", "Course7", "Course8", "Course9", "Course10" };
//Declare and initialize the array for the marks
int[] markValues = new int[courseColumnNames.Length];
//Fill the array with data
for (int index = 0; index < courseMarks.Length ; index++)
{
//Get the column name of the current course
string columnName = courseColumnNames[index];
//Copy the column value into the array
markValues[index] = (int)courseMarks[columnName];
}
//Calculate the sum
int sum = 0;
for (int index = 0; index < courseMarks.Length ; index++)
{
sum += markValues[index];
}
//Calculate the average from the sum
//Note: Since it's an integer division there will be no decimals
int average = sum / courseMarks.Length;
//Display the data
averageBox.Text = average.ToString();
}
Note that of course you could merge the two loops into one (and even drop the array, since you could just directly add to the sum variable). I have not done that to keep every step of the process clearly separated. You could also use the LINQ method Average, but that would quite miss the point here.
Instead of all your codes, you may try this:
private double GetAverage()
{
StudentsDataSet.StudentsRow courseMarks = studentsDataSet.Students.Course[10];
var average=courseMarks.Average(x =>(double) x["*YourDataColumnName*"]);
return average;
}
Where YourDataColumnName is the column of your row which contains the value you want to get average of that
You could do the following :
int average = studentsDataSet.Students.Course.Average();
You would have to add using System.Linq; for this to work.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Let's consider a maze represented by a matrix of ints: 0 - not visited, 1 - obstacles (blocked positions), 2 - visited, -1 - output, (x,y) - start position. I want to find a path from start to some output by using recursion.
int[] x_dir = new int[] { 0, 0, -1, 1 }; // x, x, x-1, x + 1
int[] y_dir = new int[] { -1, 1, 0, 0 }; // y-1, y+1, y, y
bool dfs(int[,] maze, int x, int y, int[] x_dir, int[] y_dir)
{
if (maze[x, y] == -1) { return true; } // output cell marked -1
int i = 0;
while (i < 4 && !dfs(maze, x + x_dir[i], y + y_dir[i], x_dir, y_dir))
{
++i;
}
return (i > 4) ? false : true;
}
I have two problem: I don't know how to handle edge cases(IndexOutOfRangeException inside maze[x,y]) and how to print a path.
Please, help me.
To print a path, you need to keep track of it, which suggests adding a parameter for that purpose. Care must be taken to not include wrong turns in it, or at least to remove them once you know that is what they are.
Alternatively, if you print out the step you took for each call to dfs that returned true, you would have the path, but in reverse.
As for the edge (not corner) cases: you need to check that x+x_dir[i] and y+y_dir[i] are valid indices into the maze before trying to access those locations in the maze.
for printing path , you can create an additional matrix and store information in it.Same as in longest subsequence problem solved with dynamic programming.
OR
rather than creating some additional matrix,you can use the same matrix.To keep track of path,just save the state when you find an output cell.
while (i < 4)
{
if(!dfs(maze, x + x_dir[i], y + y_dir[i], x_dir, y_dir))
++i;
else
maze[x][y]=255;
}
then follow the cell with elements 255.
Hope this helps.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am removing the rightmost zeros in a list of integers (they can only be 0 or 1) as follows:
For i As Integer = Product.Count - 1 To 0 Step -1
If Product(i) = 0 Then
Product.RemoveAt(i)
Else
Exit For
End If
Next
Could you suggest a solution less awkward and possibly more efficient of what I am currently doing.
If possible I'd like also to see an alternative solution for preserving 1 zero, if the list contains 1 zero and 1 zero only. Thank you (language, c# of vb.net is immaterial).
(PS. Note that "efficiency", which is part of the question, is an objective criterion, not based on opinions.)
If the values can only be 0 or 1, you could search for the last 1 and remove everything after that.
Dim index As Integer
index = Product.LastIndexOf(1) + 1
Product.RemoveRange(index, Product.Count - index)
If the list only contains 0 the index will be equal to 0, so you could add an if statment right before the RemoveRange.
Dim index As Integer
index = Product.LastIndexOf(1) + 1
If index = 0 Then index = 1
Product.RemoveRange(index, Product.Count - index)
(This might crash if there are no items in the list)
Update
Since it's searching for 1, the index of the first 0 will be the index returned +1. This also fix the issue of the function returning -1 when it's all zeros.
I'd do this:
public void RemoveTrailingZeros( List<int> digits )
{
int i = digits.Count ;
while ( --i >= 0 && digits[i] == 0 )
{
digits.RemoveAt(i) ;
}
return ;
}
Even tidier:
static void RemoveTrailingZeroes( List<int> digits )
{
int i = 1 + digits.FindLastIndex( x => x != 0 ) ;
digits.RemoveRange(i,digits.Count-i) ;
return ;
}
I'm not sure its any more elegant, but it does use LINQ!
int lastOne = i.IndexOf(i.Last(n => n == 1));
List<int> trimmedList = i.Take(lastOne + 1); //Account for zero-based index
To get the single zero, I would use LastOrDefault
int lastOne = i.IndexOf(i.LastOrDefault(n => n == 1));
List<int> trimmedList = i.Take(lastOne + 1); //Account for zero-based index
By far the "coolest" LINQ method, as suggested by Alexi Levenkov:
Reverse().SkipWhile(i=> i==0).Reverse();
This will remove the single zero case, in which case I would use a ternary:
i.All(n => n == 0) ? i.Take(1) : i.Reverse().SkipWhile(i=> i==0).Reverse();
Just trim :)
Product.TrimEnd('0');
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
I have created a recursive function to calculate the max path of a binary tree. I got as feedback that it does not work, but according to me test it provide the correct result. Can someone help me please?
private long PathSum(int row, int column, Pyramid pyramid)
{
// Base case, stop recurse when first row is reached.
if (row == 0) return pyramid[row, column];
// Set level to the current cell and add to the end result.
long value = pyramid[row, column];
// Continue to the next row.
if (row != 0)
{
// Continue to the next left level.
long left = pyramid[row - 1, column];
// Continue to the next right level.
long right = pyramid[row - 1, column + 1];
// Get the highest of the left and right.
long highest = Math.Max(left, right);
// Get the index of the hightest path.
int nextColumn = highest == left ? column : column + 1;
// Recurse to the next level and add results together.
value += GetTotal(row – 1, nextColumn, pyramid);
}
// Return result to the caller.
return value;
}
You have a critical mistake in your algorithm: you only walk through the 'pyramid' once and select the based case based on the next result, without looking at underlying nodes.
To illustrate what you are doing, consider the following pyramid:
1
2 3
311 6 3
Assuming that you start at 1, the following will be executed:
Look at the max out of the underlying nodes (2 and 3).
Go down to the next node (3) and repeat.
Your algorithm will return 10 (1 + 3 + 6) while the maximum value in my example is 311 + 2 + 1, because it doesn't look ahead.
You require a strategy to look further than one step ahead in order to determine the best path.
Edit: look at Euler project #18 approach for more hints.
I think what you are describing is not a binary tree but a pyramid of numbers, and the problem is best solved using dynamic programming instead of tree traversal. Here is a sample code for dynamic programming. It is not compiled and I don't know C# by the way:
private long DP(int maxRow, Pyramid pyramid)
{
int maxColumn = maxRow;
Pyramid result;
clear_pyramid(result);
for (int j=0; i<maxColumn; i++) {
result[0, j] = pyramid[0, j];
}
for (int i=1; i<maxRow; i++) {
for (int j=0; j<maxColumn-i; j++) {
result[i,j] = Math.max(result[i-1,j], result[i-1,j+1]) + pyramid[i,j];
}
}
return result[maxRow-1, 0];
}