Я читаю бинарный поиск по массиву чисел, и я считаю, что знаю, как это работает и как его реализовать. Теперь мне нужно знать, как выполнять бинарный поиск в массиве строк? Я знаю, что бинарный поиск требует, чтобы массив был отсортирован уже. предположим, что у меня есть массив строк, уже отсортированный, как мне реализовать бинарный поиск? Я знаю, если бы это был массив чисел, я бы пошел к среднему индексу массива и определил, будет ли требуемый поиск no слева или справа и сделать это рекурсивно. Как я могу это сделать для строк?Бинарный поиск по строкам вместо цифр
ответ
До тех пор, пока понятие типа «оно равно» и «оно меньше» определено для типа, над которым вы работаете, вы можете реализовать алгоритм. Не имеет значения, являются ли значения числами, буквами или пользовательскими объектами. Следующий пример демонстрирует эту концепцию:
template<typename Iterator>
Iterator search(Iterator initial, Iterator final, const typename Iterator::value_type& value) {
if(value < *initial) {
// bail out immediately
return final;
}
while(initial != final) {
auto mid = std::next(initial, std::distance(initial, final)/2);
if(*mid == value) {
return mid;
} else if(*mid < value) {
initial = std::next(mid);
} else {
final = std::prev(mid);
}
}
return final;
}
Покуда операций *mid == value
и *mid < value
определены, можно найти в контейнере любого типа (другое требование является то, что я должен быть в состоянии случайным образом получить доступ к своему итератору).
Это отнюдь не полный ответ, и есть много других деталей, но, надеюсь, вы получите эту идею.
Полный пример программы:
#include <vector>
#include <list>
#include <iostream>
template<typename Iterator>
Iterator search(Iterator initial, Iterator final, const typename Iterator::value_type& value) {
if(value < *initial) {
// bail out immediately
return final;
}
while(initial != final) {
auto mid = std::next(initial, std::distance(initial, final)/2);
if(*mid == value) {
return mid;
} else if(*mid < value) {
initial = std::next(mid);
} else {
final = std::prev(mid);
}
}
return final;
}
int main() {
{
std::vector<int> v {1, 2, 3, 4, 5};
auto it = search(v.begin(), v.end(), 3);
if(it == v.end()) {
std::cout << "Not Found!" << std::endl;
} else {
std::cout << "Found in position: " << std::distance(v.begin(), it)
<< " (value is : " << *it << ")" << std::endl;
}
}
{
std::vector<char> v {'a', 'b', 'c', 'd', 'e'};
auto it = search(v.begin(), v.end(), 'd');
if(it == v.end()) {
std::cout << "Not Found!" << std::endl;
} else {
std::cout << "Found in position: " << std::distance(v.begin(), it)
<< " (value is : " << *it << ")" << std::endl;
}
}
{
std::list<float> v {-1, 0, 1, 2, 3, 4};
auto it = search(v.begin(), v.end(), 0);
if(it == v.end()) {
std::cout << "Not Found!" << std::endl;
} else {
std::cout << "Found in position: " << std::distance(v.begin(), it)
<< " (value is : " << *it << ")" << std::endl;
}
}
{
std::vector<char> v {'a', 'b', 'c', 'd', 'e'};
auto it = search(v.begin(), v.end(), 'f');
if(it == v.end()) {
std::cout << "Not Found!" << std::endl;
} else {
std::cout << "Found in position: " << std::distance(v.begin(), it)
<< " (value is : " << *it << ")" << std::endl;
}
}
}
Образец Run:
Found in position: 2 (value is : 3)
Found in position: 3 (value is : d)
Found in position: 1 (value is : 0)
Not Found!
Наивный подход состоит в том, чтобы присвоить уникальное значение каждой букве (если вы делаете английский, это легко, всего 26 значений) и сравнивайте значения первой буквы каждой строки. Если буквы совпадают, тогда вы сравниваете вторую букву и так далее.
Можно ли, например, использовать код ASCII для этого? И затем, если следовать этому, используйте либо 'strcmp', либо' std :: string :: operastor <', чтобы на самом деле провести сравнение ... –
@MatsPetersson, что имеет смысл. Спасибо, что освободили это. Http://www.cplusplus.com/reference/string/string/operators/ Я видел, что класс строк имеет реляционные операторы. Не могли бы вы объяснить, как они работают. Предположительно новый ответ – Rajeshwar
Если вы используете массив std::string
, то все равно, так как вы все сравниваете операторы.
, поэтому вам просто нужно заменить тип массива, и вы можете выполнить поиск как есть для чисел.
Точно так же. Если вы используете std::string
, у него уже есть operator==
и operator <
, которые вам нужны только для двоичного поиска. Если у вас есть указатели на символы, вы можете использовать strcmp
, где отрицательное значение меньше, а 0 равно.
- 1. Бинарный поиск по строкам
- 2. Поиск по строкам - Python
- 3. Поиск файла по строкам
- 4. Бинарный поиск по диапазонам DateTime
- 5. Бинарный поиск по адресам IPv6?
- 6. Поиск по интерполяции по строкам
- 7. Поиск списка массивов по строкам
- 8. Несколько цифр с фиктивным столбцом по строкам
- 9. Поиск по строкам в панд
- 10. Быстрый поиск по строкам QTableWidget
- 11. Поиск по строкам в DTS
- 12. Поиск многомерных массивов по строкам
- 13. Поиск последовательных значений по строкам
- 14. Бинарный поиск строковых массивов
- 15. питона: поиск 5 цифр вместо конкретного числа
- 16. бинарный поиск C
- 17. бинарный поиск по массиву с префиксом строки
- 18. бинарный поиск по одному связанному списку
- 19. javascript/lodash бинарный поиск по функциям
- 20. Бинарный поиск CompareTo Java
- 21. Дискретный бинарный поиск
- 22. Бинарный поиск через битмаскирование?
- 23. бинарный поиск в OCaml?
- 24. бинарный поиск и последовательный поиск
- 25. Бинарный поиск - ошибка
- 26. Учитывая матричную структуру целых чисел, отсортированную по строкам, как реализовать бинарный поиск?
- 27. Бинарный поиск в php над списком строк
- 28. Бинарный поиск математической функции
- 29. Бинарный поиск python 3.5
- 30. Бинарный поиск в массиве
Таким же образом. –
Это может быть точно так же. Строки C - это просто большие числа. –
Вы имеете в виду, что у вас есть массив строк? Если это так, это одно и то же. Если вы имеете в виду «поиск значения внутри строки», если вы не сортируете символы в строке, вам будет более или менее нужно искать строку из начала до конца. [Существует алгоритм Boyer-Moore, который довольно популярен для LARGE string ищет, но для небольших строк обычно нечего просто искать прямо через] –