问题
I want to modify this algorithm so that it can find values within an array which has been sorted in descending order. This currently only works for ascending.
public static int interpo(double[] array, double key, int order)
{
int low = 0, high = array.Length - 1;
int pos = 0;
int count = 0;
while ((low <= high) && (key >= array[low]) && (key <= array[high]))
{
count++;
pos = Convert.ToInt32(low + (high - low) / (array[high] - array[low]) *
(key - array[low]));
if (array[pos] == key)
{
// Write out the position and the value of whats in the position
Console.WriteLine("\n {0} : {1}", pos, array[pos]);
break;
}
if (array[pos] < key)
low = pos + 1;
else
high = pos - 1;
// If the count is greater than the array size, do the following
if (count > array.Length)
{
// Pass through the position within the array to the close element
// method, which will display the closest values within the array
closeelement(array, key, pos);
// Return nothing
return -2;
}
}
return -1;
}
回答1:
Assuming you want to be able to pass the order in which the array has been sorted in the parameter order
, you just need to change your termination condition, like so (using 0=descending, 1=ascending):
public static int interpo(double[] array, double key, int order)
{
int low = 0, high = array.Length - 1;
int pos = 0;
int count = 0;
while ((low <= high) && ((order == 1 && (key >= array[low]) && (key <= array[high])) || (order == 0 && (key <= array[low]) && (key >= array[high]))))
{
count++;
pos = Convert.ToInt32(low + (high - low) / (array[high] - array[low]) *
(key - array[low]));
if (array[pos] == key)
{
// Write out the position and the value of whats in the position
Console.WriteLine("\n {0} : {1}", pos, array[pos]);
break;
}
if (array[pos] < key)
low = pos + 1;
else
high = pos - 1;
// If the count is greater than the array size, do the following
if (count > array.Length)
{
// Pass through the position within the array to the close element
// method, which will display the closest values within the array
closeelement(array, key, pos);
// Return nothing
return -2;
}
}
return -1;
}
EDIT
If you need the function to only be able to find values in a descending array, just change your termination condition like so:
public static int interpo(double[] array, double key, int order)
{
int low = 0, high = array.Length - 1;
int pos = 0;
int count = 0;
while ((low <= high) && ((key <= array[low]) && (key >= array[high])))
{
count++;
pos = Convert.ToInt32(low + (high - low) / (array[high] - array[low]) *
(key - array[low]));
if (array[pos] == key)
{
// Write out the position and the value of whats in the position
Console.WriteLine("\n {0} : {1}", pos, array[pos]);
break;
}
if (array[pos] < key)
low = pos + 1;
else
high = pos - 1;
// If the count is greater than the array size, do the following
if (count > array.Length)
{
// Pass through the position within the array to the close element
// method, which will display the closest values within the array
closeelement(array, key, pos);
// Return nothing
return -2;
}
}
return - 1;
}
回答2:
Since you are saying this algorithm works for in ascending order sorted arrays, I can think of the following approaches:
Switch the index accesses, i.e. instead of accessing the element at index
i
, access the element atarray.Length - i - 1
Example:
Instead of writing
array[low]
writearray[array.Length - 1 - low]
. You can simplify this by introducing a variable at the beginning of the method:int l = array.Length - 1;
Then in your code do for example:
while ((low <= high) && (key >= array[l - low]) && (key <= array[l - high])) { /* ... */ }
Reverse the array before you execute the algorithm. You can do this using
Array.Reverse()
.
来源:https://stackoverflow.com/questions/50048866/interpolation-search-searching-on-a-descending-array