I'm trying to do a simple sorting of my own (I know Array.Sort() exists), receiving a user input array and then calling the method sortMyArray() to sort the numbers from smallest to largest. Which does what intended, except for when I try to find the smallest number of an array that contains 0.
As you will see: I'm initialising the variable smallest to the value int.MaxValue at each iteration, but if the array contains a 0, it stays set to to the int.MaxValue.
static int findSmallest(int[] original, int[] sorted, int smallest)
{
for (int i = 0; i < sorted.Length; i++)
{
if (original[i] < smallest & !sorted.Contains(original[i]))
{
smallest = original[i];
}
}
return smallest;
}
static int[] sortMyArray(int[] original)
{
int[] sorted = new int[original.Length];
for (int i = 0; i < sorted.Length; i++)
{
int smallest = int.MaxValue;
smallest = findSmallest(original, sorted, smallest);
sorted[i] = smallest;
}
return sorted;
}
sortMyArray(inputArray);
My question is, how can I make sure 0 is properly handled?
The code behaves as intended for positive and negative integer values, but what is causing the 0 to not work?
Edit: For example, if the inputArray contains {5, -1, 7, 0, 33}, then the method will return it sorted as such: {-1, 5, 7, 33, 2147483647}.
With !sorted.Contains(original[i]) you skip over any value that is already in the array. sorted is initialized to all 0's so it will never set smallest = 0. In your last iteration in sortMyArray, smallest will be equal to int.Max. Note, this will also happen when you have the same element twice. Since you want to implement your own sorting method (and not use Array.Sort), you should look into various sorting algorithms (i.e. Merge Sort, Quick Sort, etc.) as yours won't work as intended.
Related
So Ive been trying to compare given double values in an array with eachother to return the smallest one, but the way I do it does not seem to work consistently and very efficient. Im feeling lost.
public static double FindSmallestNum(double[] arr)
{
double max = 0;
for (int x=0;x<arr.Length-1;x++){
if ( arr[x]>= arr[x+1]){
if (max >= arr[x+1]){
max = arr[x+1];
}
}
else if (max >=arr[x]){
max = arr[x];
}
else {
max = arr[x];
}
}
return max;
}
If you are willing to use System.Linq (which it appears that you are, given the accepted answer), then you may as well just go straight to the Min() method:
public static double FindSmallestNum(double[] arr)
{
return arr.Min();
}
Although, given that it's a simple one-line method call, it's not clear that a helper method is really all that helpful in this case.
Problems with your code
In your sample code, it appears that the problem is that you set max = 0; (why do you call it max instead of min?) and then start doing comparisons to see if max is larger than items in the array. This can be problematic, since all positive numbers will be larger than max, so they will never be considered.
To fix this, first let's rename that variable to min, so we remember what we're doing, and then set it to the first value in the array. This way we know we're dealing with a number in our array, and all comparisons will be valid.
Next, we don't need to compare each item with the next item - that comparison is not relevant to finding the smallest of all the items. We only need to compare each item to the current value of min (and do the necessary reassignment if we find a lower number).
This would reduce the code to something like:
public static double FindSmallestNum(double[] input)
{
if (input == null) throw new ArgumentNullException(nameof(input));
if (input.Length == 0)
throw new InvalidOperationException("array contains no elements");
// Start with the first number
double smallest = input[0];
// Now compare the rest of the items with 'smallest'
for (int index = 1; index < input.Length; index++)
{
if (input[index] < smallest) smallest = input[index];
}
return smallest;
}
Your code can further be optimized. you can see the below logic. Complexity of this code is O(N)
static void GetSmallest(int[] arr)
{
int first, arr_size = arr.Length;
first = int.MaxValue;
for (int i = 0; i < arr_size; i++)
{
if (arr[i] < first)
{
first = arr[i];
}
}
}
You can use the below code also.
int[] arr = new int[5] { 1, 2, 3, 4, 5 };
int min = arr.Min();
Just use Linq:
var min = arr.OrderBy(v => v).FirstOrDefault();
min will be the smallest number in your array.
I have a measurement array of 1024 values. But in this array are some values wrong like noise/peaks. The array is normally like sinus so all values should be in a good line.
How can i create a filter to the array to remove these peaks and noise?
I heard something of an algorithm that compares always three values and creates the mean-value of it but I can't find an example of this.
The wrong values are "peaks" which are bigger than the value before so it is perhaps easier if i just compare the value with the value before for a given "Offset"?
But how to do this?
public int FilterArray(double[] Values, double Offset, out double[] Results)
{
int ArrLength = Values.Length;
Results = new double[ArrLength];
for (int i = 0; i < ArrLength; i++)
Values[i] = 0;
try
{
for (int i = 0; i < ArrLength; i++)
{
if (Values[i+1] + Offset) > (Values[i]
{
// here someting is needed
}
else
{
// nothing to do if next value is ok
}
}
}
return 0;
}
Thanks for all help
I suggest to use a List instead of an Array. If you need an Array to process your data you can use the ToArray() Method but removing/filtering items from a List is way more easy than resizing Arrays.
It seems you heard about Median Filter (due to phrase that compares always three values phrase). It works good when you have to remove rare peaks.
Example: for data point triplet [3, 100, 7] algorithm finds that median (not mean!) value of this triplet is 7, and (100) data point is replaced by (7) value.
public int FilterArray(List<double> Values, double Offset, out double[] Results)
{
foreach(double value in new List<double>(Values))
{
// some logic
Values.Remove(value);
}
return 0; //??
}
I need to find items count in the C# array which type is integer.
What I mean is;
int[] intArray=new int[10]
int[0]=34
int[1]=65
int[2]=98
Items count for intArray is 3.
I found the code for strArray below but It doesn't work for int arrays.
string[] strArray = new string[50];
...
int result = strArray.Count(s => s != null);
Well, first you have to decide what an invalid value would be. Is it 0? If so, you could do this:
int result = intArray.Count(i => i != 0);
Note that this only works because, by default, elements of an int array are initialized to zero. You'd have to fill the array with a different, invalid value beforehand if 0 ends up being valid in your situation.
Another way would be to use a nullable type:
int?[] intArray = new int?[10];
intArray[0] = 34;
intArray[1] = 65;
intArray[2] = 98;
int result = intArray.Count(i => i.HasValue);
While itsme86 provided you a good answer to your actual question, I suspect you may be better off reconsidering how you write this entirely.
If this is your goal, I would recommend thinking about this differently. Instead of allocating a fixed size array, and only assigning specific values to it, you might want to consider using a List<int>:
List<int> intList = new List<int>();
intList.Add(34);
intList.Add(65);
intList.Add(98);
The number of items will always be intList.Count, and you can add as many items as you wish this way, without worry about the "allocated size", since the list will automatically grow as needed. It also won't provide you bad results if you add 0 to the list as an actual value, where counting non-zero elements will not count a zero if it's a valid value.
Note that you can also access the items by index, just like you do with an array:
int secondValue = intList[1]; // Access like you do with arrays
int[] intArray=new int[3] // Edit: Changed this to 3 to make my answer work. :)
int[0]=34
int[1]=65
int[2]=98
int count = intArray.Length; // <-- Is this what you're after?
Edit:
Ahem. As was so humbly pointed out to me, Length will return the total number of elements in the array, which in your example would have been 10. If you are looking for the number of non-zero elements in the array, you should do as suggested in some of the other answers.
When you initialize an integer array without specifying any values, C# assigns a value of zero to every element. So if zero isn't a valid value for your array, you could always test for that.
Alternatively, you could initialize the elements of your array to some value that is invalid in your context (ie if negative numbers aren't valid, initialize to -1), and then loop through the array counting the valid elements.
If the array is guaranteed to only be accessed in sequence, you can beat the full iterative IEnumerable Count (for larger arrays) with a little divide and conquer, e.g.
static int DivideCount(int[] arr, int idx, int bottom, int top)
{
if (idx <= 0)
return 0;
else if (idx >= arr.Length - 1)
return arr.Length;
else if (arr[idx] == 0 && arr[idx - 1] != 0)
return idx;
else if (arr[idx] == 0 && arr[idx - 1] == 0)
return DivideCount(arr, bottom + ((idx - bottom) / 2), bottom, idx);
else if (arr[idx] != 0 && arr[idx - 1] != 0)
return DivideCount(arr, top - ((top - idx) / 2), idx, top);
else
return -1; // hello compiler
}
int[] intArray = new int[10];
intArray[0] = 35;
intArray[1] = 65;
intArray[2] = 98;
var count = DivideCount(intArray, intArray.Length / 2, 0, intArray.Length);
None of the previous solutions are optimal if someone other than you initialized the array (i.e. you don't have the option of initializing the array values to invalid values -- null, -1, etc.).
Suppose you have an array:
var arr = new[] {0, 10, 18, 0, 20, 0, 0, 0, 0, 0, 0, 0};
If you simply count the number of zero entries:
int result = arr.Count(i => i != 0);
Count() returns 3, when in reality 5 entries have been initialized. An example would be an array of raw bytes that were read out of an audio file into a buffer, and you want to know the index of the last element that was read.
An alternative that isn't perfect but could do what you're looking for is to look for the last non-zero entry, as described here: Linq - Get the Index of the Last Non-Zero Number of Array
What is the difference between these two methods and when would you use one instead of the other?
int[,] array = new int[4,3];
int length0 = array.GetLength(0);
int upperbound0 = array.GetUpperBound(0);
MSDN says that GetLength return the number of elements where as GetUpperBound determine the max index, but how could this be different since arrays are initialized with elements for each index?
Take a look at this (rarely used) method. From Docs:
public static Array CreateInstance(Type elementType, int[] lengths, int[] lowerBounds)
Creates a multidimensional Array of the specified Type and dimension lengths, with the specified lower bounds.
With it, you can create an array with indices from -5 ... +5. If you ever use this kind of array, then GetUpperBound() suddenly becomes a lot more useful than GetLength()-1. There also exists a GetLowerBound().
But the C# support for this kind of arrays is low, you cannot use []. You would only need those methods in combination with the Array.GetValue() and SetValue() methods.
Array.Length returns the length of the array (number of elements) you need
to subtract 1 from it to get the UpperBound.
Array.GetUpperBound(0) returns the upper bound of the array, you can use it
as is.
GetUpperBound returns the highest index in the array, the GetLength returns the number of elements of the array.
i.e. GetUpperBound = GetLength - 1
Generally, array.GetUpperBound(0) = array.Length - 1, but since we can create arrays that have a Nonzero lower bound, that is not always true.
I realise this is an old question but I think it's worth emphasising that GetUpperBound returns the upper boundary of the specified dimension. This is important for a multidimensional array as in that case the two functions are not equivalent.
// Given a simple two dimensional array
private static readonly int[,] USHolidays =
{
{ 1, 1 },
{ 7, 4 },
{ 12, 24 },
{ 12, 25 }
};
The Length property will output 8 as there are 8 elements in the array.
Console.WriteLine(USHolidays.Length);
However, the GetUpperBound() function will output 3 as the upper boundary of the first dimension is 3. In other words I can loop over array indexes 0, 1, 2 and 3.
Console.WriteLine(USHolidays.GetUpperBound(0));
for (var i = 0; i <= USHolidays.GetUpperBound(0); i++)
{
Console.WriteLine("{0}, {1}", USHolidays[i, 0], USHolidays[i, 1]);
}
if lower bound of your array is 0 then you can use either of them without any confusion but i would recommend array.length-1 as it is widely used. however, if the lower bound of your array is less than 0 then you should use array.GetUpperBound(0) because in this case array.length-1 != array.getUpperBound(0)
In a method I am calculating the longest row of elements. The 1-dimensional array is filled up with random values (0 or 1). The method looks up the longest row (being 0 or 1, whatever is the longest).
For example:
In 1110100 the longest row would be 3 (3 * 1)
In 0110000 the longest row would be 4 (4 * 0)
For 1110100 the position in the array would be 0 to 2.
For 0110000 the position in the array would be 3 to 6.
I have been trying with foreach loops, for loops, etc. but I cannot seem to get the proper indexes of both and cannot seem to display both positions properly.
The longest row of similar elements gets calculated as the following based on my previous question:
public int BerekenDeelrij (int [] table)
{
int count = 0;
int value = 0;
int largest = 0;
for (int i=0; i < tabel.Length; i++)
{
if (value == tabel[i])
counter + +;
else
{
largest = Math.Max largest (largest, counter);
final value = value
count = 1;
}
}
return Math.Max(largest, counter);
}
If you replace the foreach() with a regular for(;;) you immediately have your indices available at the moment you need them.
I'm not posting complete code, since this is tagged homework, but a completely different approach to solving this problem, would be to find all the occurrences of consecutive items, and aggregate them into a new array:
[0, 1, 1, 0, 0, 0, 0] => ["0", "11", "0000"]
Then you could just order that by item.Length, descending, select top 1 item, i.e. "0000"
After that, join the aggregated array
["0", "11", "0000"] => "0110000"
And from there, return joinedResult.IndexOf( longestItem ) and that index + longestItem.Length