рд╣рд╛рд▓ рд╣реА рдореЗрдВ (рд╕рдЪрдореБрдЪ рджреЛ рд╕рд╛рд▓ рдкрд╣рд▓реЗ), рдПрдХ рд▓реЗрдЦ рдпрд╣рд╛рдВ рд╕реЗ рдЪрд▓рд╛ред
рдХреЗрд╡рд▓ 10% рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╣реА рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВ ред рдмрд╛рдЗрдирд░реА рдЦреЛрдЬ рдПрдХ
рдХреНрд▓рд╛рд╕рд┐рдХ рдЦреЛрдЬ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА
рд╕рд░рд▓ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬрд┐рд╕реЗ рдмрд╣реБрдд рдЖрд╕рд╛рдиреА рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рд╣рдо рдПрдХ рдХреНрд░рдордмрджреНрдз рд╕рд░рдгреА рд▓реЗрддреЗ рд╣реИрдВ, рдмреАрдЪ рдореЗрдВ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЕрдЧрд░ рд╣рдореЗрдВ рд╡рд╣рд╛рдВ рдХреЛрдИ рд╕рдВрдЦреНрдпрд╛ рдирд╣реАрдВ рдорд┐рд▓рддреА рд╣реИ, рддреЛ рдпрд╣ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдмреАрдЪ рдореЗрдВ рдХреНрдпрд╛ рд╣реИ - рд╣рдо рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдпрд╛ рддреЛ рдмрд╛рдИрдВ рдУрд░ рдПрдХ рд╣реА рд╡рд┐рдзрд┐ рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ, рдпрд╛ рджрд╛рдИрдВ рдУрд░, рдордзреНрдп рддрддреНрд╡ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ред рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рднреА, рдмрд╕ рдПрдХ рд╕рд░рдгреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╛рд░реЛрд╣ рд╣реИред рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд▓рдЧрднрдЧ рд╣рд░ рдЬрдЧрд╣ рд╡рд░реНрдгрд┐рдд рд╣реИ, рд╕рднреА рдХреАрдбрд╝реЗ рдкрдХрдбрд╝реЗ рдЧрдП рдФрд░ рд╡рд░реНрдгрд┐рдд рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП, рдореИрдВ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред рдореЗрд░реЗ рд▓рд┐рдП, рд╡рд╣ рдереЛрдбрд╝рд╛ рддреБрдЪреНрдЫ рдирд╣реАрдВ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдПрдХ рдирдХрд▓реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╣реВрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╣реИ, рдореИрдВ рд╕рд┐рд░реНрдл рдПрдХ рдЫрд╛рддреНрд░ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдИ рдмрд╣рд╛рдирд╛ рдирд╣реАрдВ рд╣реИ? рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдореИрдВ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рд╣реА рд╕реБрдВрджрд░ рдмрд╛рдЗрдирд░реА рдЦреЛрдЬ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред рд╣рд░ рд╕рдордп рдореБрдЭреЗ рд╕рдорд╕реНрдпрд╛ рдпрд╛ рддреЛ рд╢реБрджреНрдзрддрд╛ рдХреЗ рд╕рд╛рде, рдпрд╛ рдкреВрд░реНрд╡рд╛рдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде, рдпрд╛ рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рдорд┐рд▓рддреА рд╣реИред рддреЛ, рд╣рд╛рдБ, рд╢реАрд░реНрд╖рдХ рдереЛрдбрд╝рд╛ рдкреАрд▓рд╛ рд╣реИред
рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рдкрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рдХреЗ рдЕрдкрдиреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓рд┐рдЦреЗрдВ - рдПрдХ рдХреНрд░рдордмрджреНрдз рд╕рд░рдгреА рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЦреЛрдЬ рдХреЛ рдкрд╣рд▓реЗ рддрддреНрд╡, рдпрд╛ рдХрд┐рд╕реА рднреА рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рд▓рд┐рдЦреЗрдВ
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ C # рдореЗрдВ рдХреЛрдб рд▓рд┐рдЦреВрдВрдЧрд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдкреНрд░рд╢рдВрд╕рдХ рдореЗрд░реЗ рдХреЛрдб рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдордЭ рдкрд╛рдПрдВрдЧреЗред рдореИрдВ рдЦреЛрдЬ рдХреА рд╕реАрдорд╛рдУрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдЖрдзреЗ-рдЕрдВрддрд░рд╛рд▓ [рдмрд╛рдПрдВ] рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░реВрдВрдЧрд╛; рджрд╛рдпреЗрдВ), рдЕрд░реНрдерд╛рддреНред рдмрд╛рдПрдВ рдмрд┐рдВрджреБ рдЪрд╛рд▓реВ рд╣реИ, рдФрд░ рджрд╛рдпрд╛рдВ рдмрд┐рдВрджреБ рдмрдВрдж рд╣реИред рдЖрдзреЗ-рдЕрдВрддрд░рд╛рд▓ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИрдВ, рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдирдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд┐рднрд┐рдиреНрди рдПрд▓реНрдЧреЛрд░рд┐рджрдо (рдЬреЛ рд╣рдо рдмрд╛рдж рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ) рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдЖрдзреЗ-рдЕрдВрддрд░рд╛рд▓ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдХреБрдЫ рдлрд╛рдпрджреЗ рд╣реИрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, "рдПрдХреАрдХреГрдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╢реИрд▓реА" рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрдзреЗ-рдЕрдВрддрд░рд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕рд╣реА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓реВрдк рд▓рд┐рдЦрддрд╛ рд╣реВрдВ:
for (int i = 0; i < array.Length; i++)
:
for (int i = 0; i <= array.Length - 1; i++)
, , . :
static int BinarySearch_Rec_Wrapper(int[] array, int element)
{
BinarySearch_Rec(array, element, 0, array.Length);
}
, . , . , ,
int mid = (left + right) / 2
, (. ):
int mid = left + (right - left) / 2
, .
off-by-one. , :
, [0, 3) [4, 7), .. [left, mid) [mid + 1, right). , ┬л┬╗ ( ), , , , . , , , , .
, : [left, right], [left, mid тАФ 1] [mid + 1; right] ( , , ).
1 ( , ), тАФ 2 тАФ , .
, ( [left, mid) [mid, right)), 1 ( [left, mid] [mid + 1, right], [left, mid тАФ 1] [mid, right]).
, , , , (array[mid]), (key). тАФ , , , , :-). - . , , ┬л┬╗.
:
static int BinarySearch_Rec(int[] array, int key, int left, int right)
{
int mid = left + (right - left) / 2;
if (array[mid] == key)
return mid;
else if (array[mid] > key)
return BinarySearch_Rec(array, key, left, mid);
else
return BinarySearch_Rec(array, key, mid + 1, right);
}
:
static int BinarySearch_Iter(int[] array, int key)
{
int left = 0;
int right = array.Length;
while (true)
{
int mid = left + (right - left) / 2;
if (array[mid] == key)
return mid;
if (array[mid] > key)
right = mid;
else
left = mid + 1;
}
}
:
, , , . while(true), , . , , . , .
, , . - , ? - . ? ( , -1)? int int? null? (int? c# тАФ , null). , - , ? - ? тАж , ┬л ?┬╗. , , : , . , , , null, null.
-(1 + left), , , , . , тАФ , . DRY, - , . , .
, left == right, .., тАФ [left, right). , right тАФ left < 1 right тАФ left <= 0. , , , - ( , ).
:
static int BinarySearch_Rec(int[] array, int key, int left, int right)
{
int mid = left + (right - left) / 2;
if (left >= right)
return -(1 + left);
if (array[mid] == key)
return mid;
else if (array[mid] > key)
return BinarySearch_Rec(array, key, left, mid);
else
return BinarySearch_Rec(array, key, mid + 1, right);
}
:
static int BinarySearch_Iter(int[] array, int key)
{
int left = 0;
int right = array.Length;
int mid = 0;
while (!(left >= right))
{
mid = left + (right - left) / 2;
if (array[mid] == key)
return mid;
if (array[mid] > key)
right = mid;
else
left = mid + 1;
}
return -(1 + left);
}
:
, . , , . , - , .
тДЦ3
, . ||, &&, ,
XOR':
descendingOrder | array[mid] > key | XOR |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
.. descendingOrder , , , . ┬л┬╗, , - . , .
:
static int BinarySearch_Rec(int[] array, bool descendingOrder, int key, int left, int right)
{
int mid = left + (right - left) / 2;
if (left >= right)
return -(1 + left);
if (array[mid] == key)
return mid;
else if ((array[mid] > key) ^ descendingOrder)
return BinarySearch_Rec(array, descendingOrder, key, left, mid);
else
return BinarySearch_Rec(array, descendingOrder, key, mid + 1, right);
}
static int BinarySearch_Rec_Wrapper(int[] array, int key)
{
if (array.Length == 0)
return -1;
bool descendingOrder = array[0] > array[array.Length - 1];
return BinarySearch_Rec(array, descendingOrder, key, 0, array.Length);
}
:
static int BinarySearch_Iter(int[] array, bool descendingOrder, int key)
{
int left = 0;
int right = array.Length;
int mid = 0;
while (!(left >= right))
{
mid = left + (right - left) / 2;
if (array[mid] == key)
return mid;
if ((array[mid] > key) ^ descendingOrder)
right = mid;
else
left = mid + 1;
}
return -(1 + left);
}
static int BinarySearch_Iter_Wrapper(int[] array, int key)
{
if (array.Length == 0)
return -1;
bool descendingOrder = array[0] > array[array.Length - 1];
return BinarySearch_Iter(array, descendingOrder, key);
}
:
: , . .
тДЦ4
, . ┬л┬╗ тАФ , . , , тАж .
, , :
, , , . , , . , , . (. )
:
static int BinarySearch_Rec(int[] array, bool descendingOrder, int key, int left, int right)
{
int mid = left + (right - left) / 2;
if (left >= right)
return -(1 + left);
if (array[left] == key)
return left;
if (array[mid] == key)
{
if (mid == left + 1)
return mid;
else
return BinarySearch_Rec(array, descendingOrder, key, left, mid + 1);
}
else if ((array[mid] > key) ^ descendingOrder)
return BinarySearch_Rec(array, descendingOrder, key, left, mid);
else
return BinarySearch_Rec(array, descendingOrder, key, mid + 1, right);
}
static int BinarySearch_Rec_Wrapper(int[] array, int key)
{
if (array.Length == 0)
return -1;
bool descendingOrder = array[0] > array[array.Length - 1];
return BinarySearch_Rec(array, descendingOrder, key, 0, array.Length);
}
:
static int BinarySearch_Iter(int[] array, bool descendingOrder, int key)
{
int left = 0;
int right = array.Length;
int mid = 0;
while (!(left >= right))
{
mid = left + (right - left) / 2;
if (array[left] == key)
return left;
if (array[mid] == key)
{
if (mid == left + 1)
return mid;
else
right = mid + 1;
}
else if ((array[mid] > key) ^ descendingOrder)
right = mid;
else
left = mid + 1;
}
return -(1 + left);
}
static int BinarySearch_Iter_Wrapper(int[] array, int key)
{
if (array.Length == 0)
return -1;
bool descendingOrder = array[0] > array[array.Length - 1];
return BinarySearch_Iter(array, descendingOrder, key);
}
тДЦ5
, , , , . , , :
??
enum ElementToChoose
{
First,
Last,
NoCare
}
static int binarySearch(int value, int[] array, bool ascendingOrder, ElementToChoose elementToChoose, int low, int high) {
if (low >= high)
return -(low + 1);
if (elementToChoose == ElementToChoose.First)
if (value == array[low])
return low;
int last = high - 1;
if (elementToChoose == ElementToChoose.Last)
if (value == array[last])
return last;
int mid = low + (high - low) / 2;
if (value == array[mid]) {
switch (elementToChoose) {
case ElementToChoose.NoCare:
return mid;
case ElementToChoose.First:
if (mid - low <= 1)
return mid;
else
return binarySearch(value, array, ascendingOrder, elementToChoose, low, mid + 1);
case ElementToChoose.Last:
if (last - mid <= 1)
return mid;
else
return binarySearch(value, array, ascendingOrder, elementToChoose, mid, high);
}
}
if ((value < array[mid]) ^ !ascendingOrder)
return binarySearch(value, array, ascendingOrder, elementToChoose, low, mid);
else
return binarySearch(value, array, ascendingOrder, elementToChoose, mid + 1, high);
}
, ? , 3 , ? , , , ( ).
, , / getFirstHalf, getSecondHalf ( ), getStartPoint/getLastPoint ( / ), increaseLength/decreaseLength ( ), moveStartPoint. - . , .
, , . тАж , ┬л ┬╗, . :
static float BinarySearch_Func(Func<float, float> func, bool descendingOrder, float key, float left, float right)
{
float mid = (left + right) / 2;
if (left == mid || mid == right)
return mid;
if ((func(mid) > key) ^ descendingOrder)
return BinarySearch_Func(func, descendingOrder, key, left, mid);
else
return BinarySearch_Func(func, descendingOrder, key, mid, right);
}
static float BinarySearch_Func_Wrapper(Func<float, float> func, float key, float left, float right)
{
if (left > right)
return float.NaN;
bool descendingOrder = func(left) > func(right);
bool isOk = true;
if (!descendingOrder)
isOk = func(left) <= key && key <= func(right);
else
isOk = func(right) <= key && key <= func(left);
if (isOk)
return BinarySearch_Func(func, descendingOrder, key, left, right);
else
return float.NaN;
}
. ? ? float'? ( ,
?, , - ).
? left; right? [left, right], [left, right), (left, right], (left, right)? . :
Console.WriteLine(BinarySearch_Func_Wrapper(x => x, 0.7f, 0.7f, 100.0f));
Console.WriteLine(BinarySearch_Func_Wrapper(x => x, 0.8f, 0.8f, 100.0f));
Console.WriteLine(BinarySearch_Func_Wrapper(x => x, 0.9f, 0.9f, 100.0f));
Console.WriteLine("{0:0.00000000}",0.8f);
, left . right (). .. a b, a, b, - . .
, , , mid /. .
- , func(left) == key func(right) == key, .
, : , .
, , - . , - .
, - , : , тАФ , a/b. : a b . -: O(lgn).
, : - тАФ , // , , ?
P.S: , . ,
P.P.S: ?
UPD1:
fox_anthony -(1 + left) ~left. :
~, msdn, c#