Проблема с функцией c ++ binary_search с отсортированным массивом (поиск популярных имен) - PullRequest
1 голос
/ 10 июля 2020

Ниже мой код и текстовые файлы (игнорируйте закомментированные строки). У меня проблемы с правильной работой метода двоичного поиска. У меня есть отсортированный вектор. У меня даже есть оператор for для распечатки проверок, используемых в методе двоичного поиска, и проверок внутри for l oop, а оператор печати говорит, что он должен возвращать true. Спасибо за любую помощь! Подсказки / улучшения в других частях кода также приветствуются, спасибо!

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

vector<string> getVector(const string&);
string getName(const string&);
void selectionSort(vector<string>&);
bool search(const string&, const vector<string>&);


int main()
{
    string boyName, girlName;
    bool boyNameFound, girlNameFound;  
    vector<string> boyNames(getVector("BoyNames.txt"));   
    vector<string> girlNames(getVector("GirlNames.txt"));
    
     /* debugging 
    
   for (vector<string>::const_iterator i = boyNames.begin(); i != boyNames.end(); ++i)
    {
        cout << *i << endl;
    }
    for (vector<string>::const_iterator i = girlNames.begin(); i != girlNames.end(); ++i)
    {
        cout << *i << endl;
    }
    
    */
    
    boyName = getName("boy's");             //getting the name of a boy and setting the var boyName = to it
    //girlName = getName("girl's");
   
    selectionSort(boyNames);                //sort vector of popular boys names
    
    //selectionSort(girlNames);
    //boyNameFound = search(boyName, boyNames);    
    //girlNameFound = search(girlName, girlNames);
    
    if(search(boyName, boyNames)){ cout << "boys true " <<endl;}
    else{cout << "boys false"; }
   // if(search(girlName, girlNames)){ cout << "girls true " <<endl;}
   // else{cout << "girls false";}
   
    
   
    
}

vector<string> getVector(const string& ph){
    vector<string> names;
    ifstream namesFile(ph.c_str());
    if (!namesFile){
        cout << "Error opening file \n";
    }
    string line;
    while(getline(namesFile,line)){
        names.push_back(line);
        
    }
    names.push_back("end");             //to help when searching for names
    return names;
        
}
    
    
    
string getName(const string& ph){
    string name;
    if(ph=="boy's"){    //when boys is selected
        cout << "Enter a boys name or N to skip: ";
        cin >> name;
        
    }
    else{               //when girls is selected
        cout << "Enter a girls name or N to skip: ";
        cin >> name;
    }
    return name;
}




bool search(const string& ph, const vector<string> &nameList){
    bool nameInList;
    cout << "The boys name we are searching for is " << ph <<endl;              //printing out the name we are looking for. this is for debugging
    
    cout << "TEST BINARY SEARCH: 0=false 1=true: " << binary_search (nameList.begin(), nameList.end(), ph) << endl;
    if(binary_search (nameList.begin(), nameList.end(), ph)){
        nameInList = true;
    }
    
    for(int y = 0; y < nameList.size(); y++)
    {
        cout << ph << " == " << nameList[y] << endl; //printing out for debugging
        if (ph == nameList[y])
            nameInList = true;

    }
    
    
    
    return nameInList;
}
    
    
void selectionSort(vector<string> &arr){                                        //selection sort works good
    int startScan, minIndex;
    string minValue;
    for (startScan = 0; startScan < (arr.size() - 1); startScan++){
        minIndex = startScan;     
        minValue = arr[startScan];
        for(int index = startScan + 1; index < arr.size(); index++){
            if (arr[index] < minValue){            
                minValue = arr[index];            
                minIndex = index;         
            }
        }
        arr[minIndex] = arr[startScan];      
        arr[startScan] = minValue;
    }
}

ТЕКСТОВЫЙ ФАЙЛ: BoysNames.txt

Jacob
Michael
Joshua
Matthew
Daniel
Christopher
Andrew
Ethan
Joseph
William
Anthony
David
Alexander
Nicholas
Ryan
Tyler
James
John
Jonathan
Noah
Brandon
Christian
Dylan
Samuel
Benjamin
Zachary
Nathan
Logan
Justin
Gabriel
Jose
Austin
Kevin
Elijah
Caleb
Robert
Thomas
Jordan
Cameron
Jack
Hunter
Jackson
Angel
Isaiah
Evan
Isaac
Mason
Luke
Jason
Gavin
Jayden
Aaron
Connor
Aiden
Aidan
Kyle
Juan
Charles
Luis
Adam
Lucas
Brian
Eric
Adrian
Nathaniel
Sean
Alex
Carlos
Bryan
Ian
Owen
Jesus
Landon
Julian
Chase
Cole
Diego
Jeremiah
Steven
Sebastian
Xavier
Timothy
Carter
Wyatt
Brayden
Blake
Hayden
Devin
Cody
Richard
Seth
Dominic
Jaden
Antonio
Miguel
Liam
Patrick
Carson
Jesse
Tristan
Alejandro
Henry
Victor
Trevor
Bryce
Jake
Riley
Colin
JaredJeremyMarkCadenGarrettParkerMarcusVincentKalebKadenBradyColtonKennethJoelOscarJosiahJorgeCooperAshtonTannerEduardoPaulEdwardIvanPrestonMaxwellAlanLeviStephenGrantNicolasOmarDakotaAlexisGeorgeCollinEliSpencerGageMaxCristianRicardoDerekMicahBrodyFranciscoNolanAydenDaltonShanePeterDamianJeffreyBrendan
TravisFernandoPeytonConnerAndresJavierGiovanniShawnBradenJonahCesarBradleyEmmanuelManuelEdgarErikMarioEdwinJohnathanDevonErickWesleyOliverTrentonHectorMalachiJalenRaymondGregoryAbrahamEliasLeonardoSergioDonovanColbyMarcoBrysonMartin

1 Ответ

2 голосов
/ 10 июля 2020

Помните, что binary search работает только с отсортированным списком. Он начинается с двух переменных l и r, которые представляют левую и правую границы, между которыми выполняется поиск name.

На каждом этапе создается переменная m = (l + r)/2 и сравнивает имя по этому индексу с искомым. Если имя то, что вы ищете, все готово. В противном случае, если имя больше , установите r на m и продолжайте; и установите l на m в случае, если он меньше.

Вот мой код:

int binarySearch(const vector <string> &names, string name){
    int l = 0, r = names.size();
    while(l != r){
        int m = (l+r)/2;
    
        if(names[m] == name){return m;}
        else if(names[m] > name){r = m;}
        else{
            l = m;
        }
    }

    return -1; // name does not exist in the list
}

Альтернативный способ реализовать двоичный поиск - реализовать его с помощью прыжки . Этот подход сохраняет одну переменную, curr, которая представляет индекс, сравниваемый в данный момент.

int curr = 0;
for(int i = names.size()/2; i >= 1; i /= 2){ // jump size
    while(curr+i < names.size() && names[curr+i] <= name){
        curr += i;
    }
}

if(names[curr] == name){
    // name was found at index curr
}

Оба этих подхода основаны на одной идее, и время их выполнения практически идентично. Использование любого из этих подходов должно работать для вашей программы.

В вашей программе также есть функция selectionSort(), которая, как я предполагаю, должна сортировать std::vector перед выполнением алгоритма двоичного поиска. Обратите внимание, что C ++ предоставляет функцию сортировки общего назначения, std::sort(), которая во многих случаях выполняется намного быстрее, чем сортировка по выбору. Чтобы использовать std::sort(), вы должны набрать #include <algorithm> где-нибудь в своей программе.

...