diff --git a/oficina-busca-binaria/binary-search.md b/oficina-busca-binaria/binary-search.md deleted file mode 100644 index 9e13762cfa97df66746c508b64f5a9a4d4c22e96..0000000000000000000000000000000000000000 --- a/oficina-busca-binaria/binary-search.md +++ /dev/null @@ -1,132 +0,0 @@ -# Busca Binária e suas diferentes implementações - -Implementação com intervalo [0, n-1] -```cpp -int lo = 0; -int hi = n - 1; -while (l <= r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] == target) { - return mid; - } else if (a[mid] > target) { - hi = mid - 1; - } else { - lo = mid + 1; - } -} - -return -1; -``` - -Implementação com intervalo [0, n) -```cpp -int lo = 0; -int hi = n; -while (l < r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] == target) { - return mid; - } else if (a[mid] > target) { - hi = mid; - } else { - lo = mid + 1; - } -} - -return -1; -``` - -Implementação com intervalo [0, n-1] e verificação no fim. Requer na média uma -iteração a mais. -```cpp -int lo = 0; -int hi = n - 1; -while (l < r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] > target) { - hi = mid + 1; - } else { - lo = mid; - } -} - -if (a[lo] == target) { - return lo; -} else { - return -1; -} -``` - -Implementação com intervalo [0, n) para achar o elemento mais a esquerda. -```cpp -int lo = 0; -int hi = n; -while (l < r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] >= target) { - hi = mid; - } else { - lo = mid + 1; - } -} - -return lo; -``` - -Implementação com intervalo [0, n-1] para achar o elemento mais a esquerda. -```cpp -int lo = 0; -int hi = n - 1; -while (l <= r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] >= target) { - hi = mid - 1; - } else { - lo = mid + 1; - } -} - -return lo; -``` - -Implementação com intervalo [0, n-1] para achar o elemento mais a esquerda. Errichto. -```cpp -int lo = 0; -int hi = n - 1; -int ans = -1; -while (l <= r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] >= target) { - ans = mid; - hi = mid - 1; - } else { - lo = mid + 1; - } -} - -return ans; -``` - -Implementação com intervalo [0, n) para achar o elemento mais a direita. -```cpp -int lo = 0; -int hi = n; -while (l < r) { - int mid = lo + (hi - lo) / 2; - if (a[mid] > target) { - hi = mid; - } else { - lo = mid + 1; - } -} - -return hi - 1; -``` - -# Tipos de busca binária -* Achar elemento exato -* Achar o primeiro elemento com alguma propriedade -* Achar o último elemento com alguma propriedade - -# Como formular um problema de busca binária -Pensar em um array particionado em verdadeiro e falso. diff --git a/oficina-busca-binaria/main.cpp b/oficina-busca-binaria/main.cpp index c172ebe5160c0fe184f5bdfcf9e055ba83888ce9..aeabec2eded56db3776992b672c51fd78fa857b7 100644 --- a/oficina-busca-binaria/main.cpp +++ b/oficina-busca-binaria/main.cpp @@ -53,12 +53,7 @@ int busca_intervalo_0_n_end (vector<int> a, int n, int target) { } } - if (0 <= lo && lo < n) { - comp++; - return a[lo] == target ? lo : -1; - } else { - return -1; - } + return (n != 0 && a[lo] == target) ? lo : -1; } int busca_intervalo__1_n (vector<int> a, int n, int target) { @@ -243,6 +238,22 @@ int esquerda_intervalo_0_n_1_aux (vector<int> a, int n, int target) { return ans; } +int esquerda_for (vector<int> a, int n, int target) { + int i = -1; + for (int p = n; p >= 1; p /= 2) { + while (i+p < n && a[i+p] < target) { comp++; i += p; } + } + return i + 1; +} + +int esquerda_for_rev (vector<int> a, int n, int target) { + int i = n; + for (int p = n; p >= 1; p /= 2) { + while (i-p >= 0 && a[i-p] >= target) { comp++; i -= p; } + } + return i; +} + int esquerda_lower_bound (vector<int> a, int n, int target) { return lower_bound(a.begin(), a.begin() + n, target) - a.begin(); } @@ -308,7 +319,7 @@ int direita_intervalo__1_n_hi (vector<int> a, int n, int target) { } } - return lo + 1; + return hi; } int direita_intervalo_0_n_1_lo (vector<int> a, int n, int target) { @@ -395,6 +406,22 @@ int direita_intervalo_0_n_1_aux (vector<int> a, int n, int target) { return ans; } +int direita_for (vector<int> a, int n, int target) { + int i = -1; + for (int p = n; p >= 1; p /= 2) { + while (i+p < n && a[i+p] <= target) { comp++; i += p; } + } + return i + 1; +} + +int direita_for_rev (vector<int> a, int n, int target) { + int i = n; + for (int p = n; p >= 1; p /= 2) { + while (i-p >= 0 && a[i-p] > target) { comp++; i -= p; } + } + return i; +} + int direita_upper_bound (vector<int> a, int n, int target) { return upper_bound(a.begin(), a.begin() + n, target) - a.begin(); } @@ -408,7 +435,7 @@ string not_found_if_array_is_empty(binary_search_function impl) { string found_if_in_odd_array(binary_search_function impl) { vector<int> a { 0, 2, 4, 6, 8, 10, 12, 14, 16 }; - for (int i = 0; i < 9; i++) if (impl(a, 9, a[i]) == -1) { return "false"; } + for (int i = 0; i < a.size(); i++) if (impl(a, a.size(), a[i]) == -1) { return "false"; } return ""; } @@ -426,7 +453,7 @@ string found_if_in_odd_random_array(binary_search_function impl) { string found_if_in_even_array(binary_search_function impl) { vector<int> a { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 }; - for (int i = 0; i < 10; i++) if (impl(a, 10, a[i]) == -1) { return "false"; } + for (int i = 0; i < a.size(); i++) if (impl(a, a.size(), a[i]) == -1) { return "false"; } return ""; } @@ -441,8 +468,8 @@ string found_if_in_even_random_array(binary_search_function impl) { string found_left_in_odd_array(binary_search_function impl) { vector<int> a { 2, 2, 4, 4, 4, 6, 8, 8, 10 }; vector<int> r { 0, 0, 0, 2, 2, 5, 5, 6, 6, 8, 8, 9 }; - for (int i = 0; i < 12; i++) if (impl(a, 9, i) != r[i]) { - return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, 9, i)); + for (int i = 0; i < r.size(); i++) if (impl(a, a.size(), i) != r[i]) { + return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, a.size(), i)); } return ""; } @@ -450,17 +477,26 @@ string found_left_in_odd_array(binary_search_function impl) { string found_left_in_even_array(binary_search_function impl) { vector<int> a { 2, 2, 4, 4, 4, 6, 8, 8, 10, 10 }; vector<int> r { 0, 0, 0, 2, 2, 5, 5, 6, 6, 8, 8, 10, 10 }; - for (int i = 0; i < 13; i++) if (impl(a, 10, i) != r[i]) { - return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, 10, i)); + for (int i = 0; i < r.size(); i++) if (impl(a, a.size(), i) != r[i]) { + return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, a.size(), i)); + } + return ""; +} + +string found_left_in_array(binary_search_function impl) { + vector<int> a { 2, 2, 2, 2, 4, 4, 4, 6, 6, 6, 6, 8, 9, 10 }; + vector<int> r { 0, 0, 0, 4, 4, 7, 7, 11, 11, 12, 13, 14 }; + for (int i = 0; i < r.size(); i++) if (impl(a, a.size(), i) != r[i]) { + return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, a.size(), i)); } return ""; } string found_right_in_odd_array(binary_search_function impl) { vector<int> a { 2, 2, 4, 4, 6, 6, 8, 8, 10 }; - vector<int> r { 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10 }; - for (int i = 0; i < 10; i++) if (impl(a, 9, i) != r[i]) { - return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, 9, i)); + vector<int> r { 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 9 }; + for (int i = 0; i < r.size(); i++) if (impl(a, a.size(), i) != r[i]) { + return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, a.size(), i)); } return ""; } @@ -468,24 +504,33 @@ string found_right_in_odd_array(binary_search_function impl) { string found_right_in_even_array(binary_search_function impl) { vector<int> a { 2, 2, 4, 4, 6, 6, 8, 8, 10, 10 }; vector<int> r { 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10 }; - for (int i = 0; i < 11; i++) if (impl(a, 10, i) != r[i]) { - return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, 10, i)); + for (int i = 0; i < r.size(); i++) if (impl(a, a.size(), i) != r[i]) { + return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, a.size(), i)); + } + return ""; +} + +string found_right_in_array(binary_search_function impl) { + vector<int> a { 2, 2, 2, 2, 4, 4, 4, 6, 6, 6, 6, 8, 9, 10 }; + vector<int> r { 0, 0, 4, 4, 7, 7, 11, 11, 12, 13, 14, 14 }; + for (int i = 0; i < r.size(); i++) if (impl(a, a.size(), i) != r[i]) { + return "esperava encontrar item " + to_string(i) + " na posição " + to_string(r[i]) + " mas obtive " + to_string(impl(a, a.size(), i)); } return ""; } string not_found_if_not_found_in_odd_array(binary_search_function impl) { vector<int> a { 0, 2, 4, 6, 8, 10, 12, 14, 16 }; - for (int i = 0; i < 9; i++) if (impl(a, 9, a[i]+1) != -1) { - return "esperava não encontrar item " + to_string(a[i]+1) + " mas obtive " + to_string(impl(a, 9, a[i]+1)); + for (int i = 0; i < a.size(); i++) if (impl(a, a.size(), a[i]+1) != -1) { + return "esperava não encontrar item " + to_string(a[i]+1) + " mas obtive " + to_string(impl(a, a.size(), a[i]+1)); } return ""; } string not_found_if_not_found_in_even_array(binary_search_function impl) { vector<int> a { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 }; - for (int i = 0; i < 10; i++) if (impl(a, 10, a[i]+1) != -1) { - return "esperava não encontrar item " + to_string(a[i]+1) + " mas obtive " + to_string(impl(a, 10, a[i]+1)); + for (int i = 0; i < a.size(); i++) if (impl(a, a.size(), a[i]+1) != -1) { + return "esperava não encontrar item " + to_string(a[i]+1) + " mas obtive " + to_string(impl(a, a.size(), a[i]+1)); } return ""; } @@ -586,10 +631,14 @@ int main() { esquerda_intervalo_0_n_1_ceil_lo), make_pair("Esquerda: Intervalo [0, n-1], teto, resposta hi", esquerda_intervalo_0_n_1_ceil_hi), - make_pair("Esquerda: Intervalo [0, n-1], teto, variável auxiliar", + make_pair("Esquerda: Intervalo (-1, n), resposta lo", esquerda_intervalo__1_n_lo), make_pair("Esquerda: Intervalo (-1, n), resposta hi", - esquerda_intervalo__1_n_lo), + esquerda_intervalo__1_n_hi), + make_pair("Esquerda: Passo binário", + esquerda_for), + make_pair("Esquerda: Passo binário reverso", + esquerda_for_rev), make_pair("Esquerda: lower_bound", esquerda_lower_bound) }; @@ -628,6 +677,8 @@ int main() { esquerda_intervalo__1_n_lo), make_pair("Esquerda: Intervalo (-1, n), resposta hi", esquerda_intervalo__1_n_lo), + make_pair("Esquerda: For", + esquerda_for), make_pair("Esquerda: lower_bound", esquerda_lower_bound), }; @@ -637,6 +688,8 @@ int main() { found_left_in_odd_array), make_pair("Elemento mais a esquerda em vetor par", found_left_in_even_array), + make_pair("Elemento mais a esquerda em vetor", + found_left_in_array), make_pair("Elemento encontrado em vetor ímpar", found_if_in_odd_array), make_pair("Elemento encontrado em vetor par", @@ -662,10 +715,14 @@ int main() { direita_intervalo_0_n_1_ceil_lo), make_pair("Direita: Intervalo [0, n-1], teto, resposta hi", direita_intervalo_0_n_1_ceil_hi), - make_pair("Direita: Intervalo [0, n-1], teto, variável auxiliar", + make_pair("Direita: Intervalo (-1, n), resposta lo", direita_intervalo__1_n_lo), make_pair("Direita: Intervalo (-1, n), resposta hi", direita_intervalo__1_n_hi), + make_pair("Direita: Passo binário", + direita_for), + make_pair("Direita: Passo binário reverso", + direita_for_rev), make_pair("Direita: upper_bound", direita_upper_bound), }; @@ -675,6 +732,8 @@ int main() { found_right_in_odd_array), make_pair("Elemento mais a direita em vetor par", found_right_in_even_array), + make_pair("Elemento mais a direita em vetor", + found_right_in_array), make_pair("Elemento encontrado em vetor ímpar", found_if_in_odd_array), make_pair("Elemento encontrado em vetor par",