Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Надо прямым перебором с созданием нового массива! Только хардор!
Dim arr() As Integer = {1, 2, 5, 6, 3, 8, 4, 9, 7}
Dim result = From b In arr Order By b
'результат: 1,2,3,4,5,6,7,8,9
return -(1 + left);using System;
using System.Collections.Generic;
using System.Text;
namespace ObfuscatedNamespace
{
public class List<T> : System.Collections.Generic.List<T>
{
public List() : base() {}
public List(IEnumerable<T> collection) : base(collection) { }
public List(int capacity) : base(capacity) { }
public int BinarySearchFirst(T item)
{
return BinarySearchFirst(0, Count, item, null);
}
public int BinarySearchFirst(T item, IComparer<T> comparer)
{
return BinarySearchFirst(0, Count, item, comparer);
}
public int BinarySearchFirst(int index, int count, T item, IComparer<T> comparer)
{
if (index < 0 || count < 0) throw new ArgumentOutOfRangeException();
if (index + count > Count) throw new ArgumentException();
if (comparer == null)
comparer = Comparer<T>.Default;
if (comparer == null) throw new InvalidOperationException();
int low = index;
if (count == 0)
return ~index;
int middle;
int len = count;
int half;
while (len > 0)
{
half = len / 2;
middle = low + half;
if (comparer.Compare(this[middle], item) < 0)
{
low = middle + 1;
len = len - half - 1;
}
else
len = half;
}
if (low >= count || comparer.Compare(this[low], item) != 0)
return ~low;
else
return low;
}
public int BinarySearchLast(int index, int count, T item, IComparer<T> comparer)
{
if (index < 0 || count < 0) throw new ArgumentOutOfRangeException();
if (index + count > Count) throw new ArgumentException();
if (comparer == null)
comparer = Comparer<T>.Default;
if (comparer == null) throw new InvalidOperationException();
int low = index;
if (count == 0)
return ~index;
int middle;
int r;
int len = count;
int half;
while (len > 0)
{
half = len / 2;
middle = low + half;
r = comparer.Compare(item, this[middle]);
if (r < 0)
len = half;
else
{
low = middle + 1;
len = len - half - 1;
}
}
if (low > 0)
{
r = comparer.Compare(item, this[low - 1]);
if (r == 0)
return low - 1;
else
return ~low;
}
else
return ~low;
}
public int BinarySearchLast(T item)
{
return BinarySearchLast(0, Count, item, null);
}
public int BinarySearchLast(T item, IComparer<T> comparer)
{
return BinarySearchLast(0, Count, item, comparer);
}
}
}
return ~left;
return -(1+left);
return ~left; // -(1+left); premature optimization int[] a = { 1, 3, 4, 6, 8, 4, 7, 8, 2, 3, 6, 1 };
Action<int, int> f = null;
f = delegate (int L, int R)
{
if (R - L == 1) return;
int pilot = a[L]; // (L+R)/2 заметно осложняет анализ. Если у нас есть предположение, что числа случайные, то никаких преимуществ одного перед другим нет.
int l = L, r = R;
// примем что для всех a[L..l) < pilot и a[r..R) >= pilot . Это условие должно выполняться на входе в цикл, по окончании каждой итерации, и на выходе из цикла.
// на каждой итерации должно происходить только одно из трёх: либо уменьшаться r , либо увеличиваться l, либо происходить обмен.
while (l != r) // только хардкор! никаких l <= r.
if (a[l] < pilot) l++;
else if (a[r-1] >= pilot) r--;
else
{
int t = a[l]; a[l] = a[r-1]; a[r-1] = t;
}
if (a[L] == pilot) // если pilot остался на своём месте, то pilot -- наименьший элемент во всём a[L,R). Просто пропускаем. Это тот самый случай вырождения в O(NN)
f(L + 1, R);
else
{ // помним, что после выхода из цикла l и r не менялись, следовательно, всё ещё l == r, все условия корректности выполняются
f(L, l);
f(r, R);
}
};
f(0, a.Length );
foreach(var e in a) System.Console.WriteLine(e);// Pre: (0 <= left) and (right < v.size()) and (v is sorted in an ascending order)
// Post: returns a number i, left<=i<=right and v[i]==x.
// If there is no element x in v[], returns -1.
int position(double x, const vector<double>& v, int left, int right) {
if (left > right) return -1;
int pos = (left + right)/2; // the middle of v[left,right]
if (x < v[pos]) return position(x, v, left, pos - 1);
if (x > v[pos]) return position(x, v, pos + 1, right);
return pos;
}
function bsearch($hs, $nee) {
$i1 = 0;
$i2 = count($hs);
do {
$i = floor(($i1 + $i2) / 2);
if ($hs[$i] == $nee) return $i;
if ($hs[$i] < $nee) $i1 = $i;
else $i2 = $i;
} while($i2 - $i1 > 1 || $i1 != $i);
return -1;
}
function bsearch_nearest($hs, $nee) {
for ($i1 = 0, $i2 = count($hs), $i = -1; $i2 - $i1 > 1 || $i1 != $i; ) {
$i = floor(($i1 + $i2) / 2);
if ($hs[$i] == $nee) return $i;
$hs[$i] < $nee? ($i1 = $i): ($i2 = $i);
}
return $i;
}
function bsearch($hs, $nee) {
$i = bsearch_nearest($hs, $nee);
while($i > 0 && $hs[$i - 1] == $nee) $i--; //return lowest index if there are few matching
return array(($hs[$i] == $nee? $i: -1), $i); //returns array: [0] => lowest matching index (or -1); [1] => nearest index
}
int[] data;
int getIndex(int left, int right, int x) {
while (right-left>1) {
int middle=(left+right)/2; // обычно не нужно больше 10^9 элементов.
if (data[middle]>=x) {
left=middle;
} else {
right=middle;
}
}
return left;
}
from bisect import bisect_left
# our default binary search based on bisect_left() from stdlib
def bin_search_left(a, x):
i = bisect_left(a, x)
if i != len(a) and a[i] == x:
return i
raise ValueError
# reverse list in O(1): [1, 2, 3] -> [-3, -2, -1]
class RevList():
def __init__(self, list): self.list = list
def __len__(self): return len(self.list)
def __getitem__(self, key): return -self.list[len(self.list) - key - 1]
# rightmost occurrence in terms of bin_search_left
def bin_search_right(a, x):
return len(a) - 1 - bin_search_left(RevList(a), -x)
# and action!
arr = [2, 3, 5, 5, 5, 7, 11]
print bin_search_left(arr, 5) # 2
print bin_search_right(arr, 5) # 4
# coding: utf-8
class Element:
def __init__(self, key, value):
self.key = key
self.value = value
def __str__(self):
return "%d (%s)" % (self.key, self.value)
# Обычный бинарный поиск
def BinSearch(arr, elem, l, u):
if not arr:
return -1
while True:
if u < l:
return -1
i = (l + u) / 2
if elem.key < arr[i].key:
u = i - 1
elif elem.key > arr[i].key:
l = i + 1
else:
return i
array = [Element(key, chr((key % 26) + 65,) ) for key in [1, 7, 11, 12, 24, 123]]
key = 12
print "array =", map(str, array)
print "key = %d" % key
print "index =", BinSearch(array, Element(key, "value"), 0, len(array) - 1)
raw_input("Press any key...")
array = ['1 (B)', '7 (H)', '11 (L)', '12 (M)', '24 (Y)', '123 (T)']
key = 12
index = 3
Press any key...
template<typename FwdIter, typename T, typename Comp>
FwdIter lower_bound(FwdIter first, FwdIter last, T const& x, Comp comp)
{
// если интервал пустой, то его и возвращаем
if (first == last)
return first;
// вычислим позицию среднего элемента
FwdIter middle = first;
std::advance(middle, std::distance(first, last) / 2);
// Если средний элемент меньше искомого, т.е. искомый больше среднего элемента,
// то т.к. последовательность отсортирована по возрастанию,
// искомый элемент должен находиться справа от среднего, иначе — слева
if (comp(*middle, x))
return lower_bound(++middle, last, x, comp);
else
return lower_bound(first, middle, x, comp);
}
template<typename FwdIter, typename T, typename Comp>
FwdIter upper_bound(FwdIter first, FwdIter last, T const& x, Comp comp)
{
typedef typename std::iterator_traits<FwdIter>::value_type value_type;
auto less_equal = [&comp](value_type const& a, T const& b){return !comp(b, a);};
return lower_bound(first,last, x, less_equal);
}
template<typename FwdIter, typename T, typename Comp>
FwdIter binary_search(FwdIter first, FwdIter last, T const& x, Comp comp)
{
FwdIter found = lower_bound(first, last, x, comp);
// Если элемент не найден, found может оказаться равен правой границе.
// Если found указывает на существующий элемент, то он не меньше искомого.
// Т.е. *found или больше или равен x, если больше, то x не нашелся.
if (found == last || comp(x, *found))
{
// Элемент не найден.
// Вернем верхнюю границу диапазона в качестве индикатора.
return last;
}
return found;
}
static int BinSearch(int[] m,int a,int kf) {
int len=m.Length;
int cf=0;
if(len==0) return -1;
if(m[0]>m[len-1]) {
a=~a; cf=-1;
}
int x1=-1,x2=len;
while(x2-x1>1) {
int x3=x1+(x2-x1)/2;
int h=m[x3]^cf;
if(h==a && kf==0) return x3;
if(kf<0 ? h>=a : h>a) x2=x3;
else x1=x3;
}
if(kf<0) {
if(x2<len && (m[x2]^cf)==a) return x2;
} else {
if(x1>=0 && (m[x1]^cf)==a) return x1;
}
return ~x2;
}
static int BinSearch(int[] m,int a,int kf,Comparison<int>cmp) {
int len=m.Length;
if(len==0) return -1;
int cf=cmp(m[0],m[len-1])<=0 ? 1 : -1;
int x1=-1,x2=len;
while(x2-x1>1) {
int x3=x1+(x2-x1)/2;
int h=cf*cmp(m[x3],a);
if(h==0 && kf==0) return x3;
if(kf<0 ? h>=0 : h>0) x2=x3;
else x1=x3;
}
if(kf<0) {
if(x2<len && cmp(m[x2],a)==0) return x2;
} else {
if(x1>=0 && cmp(m[x1],a)==0) return x1;
}
return ~x2;
}
unsigned int left = 0, right = hashlist_count;
// now binary search
while (left < right)
{
unsigned int middle = left + (right - left) / 2;
if (a < hashlist[2*middle] ||
a == hashlist[2*middle] && b <= hashlist[2*middle+1])
{
right = middle;
}
else
{
left = middle + 1;
}
}
if (a == hashlist[2*right] && b == hashlist[2*right+1])
{
// matched!
unsigned int add = 1 << (output_index % 32);
atomicAdd(&(((unsigned int*)match_out)[output_index / 32]), add);
}
unsigned int left = 0, right = hashlist_count;
// now binary search
while (left < right)
{
unsigned int middle = left + (right - left) / 2;
if (x < hashlist[middle])
{
right = middle;
}
else
{
left = middle + 1;
}
}
if (x == hashlist[right])
{
// matched!
}
static int BinarySearch(List<int> list, int num, Tuple<int, int> range)
{
int midleIndex = (range.Item1 + range.Item2) / 2;
Func<int>[,] funcs = new Func<int>[,]
{
{
() => -1, () => -1, () => -1
},
{
() => BinarySearch(list, num, new Tuple<int, int>(range.Item1, midleIndex)),
() => midleIndex,
() => BinarySearch(list, num, new Tuple<int, int>(midleIndex + 1, range.Item2))
}
};
return funcs[(1 + Math.Sign(1 + 2 * (list.Count - range.Item2))) * Math.Sign(range.Item2 - range.Item1) / 2, Math.Sign(num - list[midleIndex]) + 1]();
}
mov ebx,eax
neg ebx
or ebx,eax
sar ebx,31
sar eax,31
add eax,eax
inc eax
and eax,ebx
ret
int BinSearch(int[] arr,int val){
return BinSearch(arr,val,-1,arr.Length);
}
int BinSearch(int[] arr,int val,int left,int right){
return (new Func<int>[]{()=>~right,()=>BinSearchNE(arr,val,left,right)})[Math.Min(right-left-1,1)]();
}
int BinSearchNE(int[] arr,int val,int left,int right){
int mid=left+(right-left)/2;
return (new Func<int>[]{
()=>BinSearch(arr,val,left,mid),
()=>mid,
()=>BinSearch(arr,val,mid,right))
}[Math.Sign((long)val-arr[mid])+1]();
}
static int BinarySearch(List<int> list, int num, Tuple<int, int> range)
{
int midleIndex = (range.Item1 + range.Item2 - 1) / 2;
Func<int>[,] funcs = new Func<int>[,]
{
{
() => -1, () => -1, () => -1
},
{
() => BinarySearch(list, num, new Tuple<int, int>(range.Item1, midleIndex)),
() => midleIndex,
() => BinarySearch(list, num, new Tuple<int, int>(midleIndex + 1, range.Item2))
}
};
return funcs[Math.Sign(range.Item2 - range.Item1), Math.Sign(num - list[midleIndex]) + 1]();
}
#include <vector>
#include <iterator>
#include <iostream>
namespace bs {
namespace impl {
template<typename E, bool find_first>
typename std::vector<E>::const_iterator find(const std::vector<E>& where, const E& what, const typename std::vector<E>::const_iterator& begin, const typename std::vector<E>::const_iterator& end)
{
typename std::vector<E>::const_iterator::difference_type size = std::distance(begin, end);
if (size == 0)
return where.end();
typename std::vector<E>::const_iterator center = begin + size / 2;
if (what < *center)
return find<E, find_first>(where, what, begin, center);
if (*center < what)
return find<E, find_first>(where, what, center+1, end);
if (find_first) {
typename std::vector<E>::const_iterator leftmost = find<E, find_first>(where, what, begin, center);
if (leftmost != where.end())
return leftmost;
}
return center;
}
};
template<typename E, bool find_first>
typename std::vector<E>::const_iterator find(const std::vector<E>& where, const E& what)
{
return impl::find<E, find_first>(where, what, where.begin(), where.end());
}
};
int main(int argc, char* argv[])
{
std::vector<int> input = { 10, 21, 34, 34, 34, 35, 41, 45, 49, 67, 102, 120, 120, 120, 120, 120, 120, 201 };
std::copy(input.begin(), input.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl << std::endl;
int what;
for(;;) {
std::cout << "Find what: ";
std::cin >> what;
typename std::vector<int>::const_iterator found = bs::find<int, true>(input, what);
if (found == input.end()) {
std::cout << "Not found" << std::endl;
continue;
}
std::cout << "Found at " << std::distance(static_cast<std::vector<int>::const_iterator>(input.begin()), found) << std::endl;
}
return 0;
}
как раз таки средний выбрасывать не надо: если он не превосходит х — сделаем его левым концом
if (array[middle] <= x)
left = middle; // include middle
else
right = middle; // exclude middle
if (array[middle] < x)
left = middle + 1; // exclude middle
else
right = middle + 1; // include middle
Я не могу написать бинарный поиск