Почему моя функция поиска не работает должным образом и как я могу это исправить? - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь создать функцию поиска сравнения, которая может сравнивать две строки вместе на основе символов.Например:

Ввод: «ca» Структурировать векторное содержание под полями фамилии (отсортированный вектор) (индекс / значение): 0 / «автомобили», 1 / «дороги» Результат: «Имя найдено в индексе 0- cars "

Я хочу, чтобы пользователи могли использовать любое количество символов.Затем программа должна сравнить предоставленные критерии поиска с содержимым вектора и вернуть индекс любых совпадений.

До сих пор я безуспешно пытался реализовать этот алгоритм, вот мой код.Также я довольно новичок в C ++.

// Function for searching through an array for a string value.
int searchArray(std::vector<playerdata> (&people), std::string name) {

    int loc = -1;
    int counter = 0;
    int index = 0;

    //when loc is no longer -1, that means the person has been found

    for (int i = 0; i < people.size(); i++)

        for(int k = 0; k < name.length(); k++) {

            std::cout << name[k-1] << std::endl;
            std::cout << people[i].lastname[k-1] << std::endl;
            std::cout << counter << std::endl;
            std::cout << "" << std::endl;

            if(name[k-1] == people[i].lastname[k-1]) {

                counter++;

            }

            if(counter == name.length()) {

                loc = i;
                break;

            }
        }

        //if (people[i].lastname.compare(name) == 0)

            //loc = i;

    return loc;

}

Вот что я получаю в своей консоли, я использую cout для отладки:

What is player 1 information (F/L/DOB (DD/MM/YYY)), Seperate using a space):
hello sunshine
What is player 2 information (F/L/DOB (DD/MM/YYY)), Seperate using a space):
good bye
Pick from the available options:
1 - Input Data:
2 - Display Original Data:
3 - Sort Data:
4 - Display Sorted Data:
5 - Search By Last Name:
6 - Exit The Program;

3
Array Sorted!!!
Pick from the available options:
1 - Input Data:
2 - Display Original Data:
3 - Sort Data:
4 - Display Sorted Data:
5 - Search By Last Name:
6 - Exit The Program;

4
Player 1: good bye
Player 2: hello sunshine

Pick from the available options:
1 - Input Data:
2 - Display Original Data:
3 - Sort Data:
4 - Display Sorted Data:
5 - Search By Last Name:
6 - Exit The Program;

5
Enter the name to search:
bye
b
b
0

y
y
1

e
e
2

b
s
3

y
u
4

e
n
4

Player Found:  good bye
Enter the name to search:
by
y
b
0

y
s
1

Player Found:  good bye
Enter the name to search:
b
The player was not found, try again.
Enter the name to search:
sun
u
b
0

n
y
1

u
s
1

Player Found:  hello sunshine
Enter the name to search:
sunshine
u
b
0

n
y
1

s
e
1

h

1

i
h
1

n
i
1

e
n
1

u
s
1

n
u
2

s
n
2

h
s
2

i
h
2

n
i
2

e
n
2

The player was not found, try again.
Enter the name to search:

РЕДАКТИРОВАТЬ: Как вы можете видеть из моегоВывод на консоль кода возвращает истинные сравнения, когда этого не следует делать.Примером последнего сравнения является (e == n).Ответ должен быть ложным, но он продолжает возвращать истину.

После использования кода, предложенного в комментариях, я все еще не могу заставить свой код работать должным образом и получаю следующие ошибки:

    ||=== Build file: "no target" in "no project" (compiler: unknown) ===|
E:\Coding\Cplus_work\assignmentseven.cpp||In function 'int main()':|
E:\Coding\Cplus_work\assignmentseven.cpp|68|warning: NULL used in arithmetic [-Wpointer-arith]|
E:\Coding\Cplus_work\assignmentseven.cpp|158|warning: NULL used in arithmetic [-Wpointer-arith]|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\bits\predefined_ops.h||In instantiation of 'bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<playerdata*, std::vector<playerdata> >; _Predicate = searchArray(std::vector<playerdata>&, std::__cxx11::string&)::<lambda(std::__cxx11::string&)>]':|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\bits\stl_algo.h|120|required from '_RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<playerdata*, std::vector<playerdata> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<searchArray(std::vector<playerdata>&, std::__cxx11::string&)::<lambda(std::__cxx11::string&)> >]'|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\bits\stl_algo.h|161|required from '_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator<playerdata*, std::vector<playerdata> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<searchArray(std::vector<playerdata>&, std::__cxx11::string&)::<lambda(std::__cxx11::string&)> >]'|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\bits\stl_algo.h|3930|required from '_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = __gnu_cxx::__normal_iterator<playerdata*, std::vector<playerdata> >; _Predicate = searchArray(std::vector<playerdata>&, std::__cxx11::string&)::<lambda(std::__cxx11::string&)>]'|
E:\Coding\Cplus_work\assignmentseven.cpp|35|required from here|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\bits\predefined_ops.h|283|error: no match for call to '(searchArray(std::vector<playerdata>&, std::__cxx11::string&)::<lambda(std::__cxx11::string&)>) (playerdata&)'|
E:\Coding\Cplus_work\assignmentseven.cpp|33|note: candidate: 'searchArray(std::vector<playerdata>&, std::__cxx11::string&)::<lambda(std::__cxx11::string&)>'|
E:\Coding\Cplus_work\assignmentseven.cpp|33|note:   no known conversion for argument 1 from 'playerdata' to 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string<char>&'}|
E:\Coding\Cplus_work\assignmentseven.cpp||In function 'bool sortArray(const playerdata&, const playerdata&)':|
E:\Coding\Cplus_work\assignmentseven.cpp|28|warning: control reaches end of non-void function [-Wreturn-type]|
||=== Build failed: 1 error(s), 8 warning(s) (0 minute(s), 0 second(s)) ===|

Точныйкод, который я использовал:

// Function for searching through an array for a string value.
int searchArray(std::vector<playerdata> (&people), std::string (&name))
{
    auto it = std::find_if(people.begin(), people.end(), [&name](std::string& person){
        return person.find(name) != std::string::npos;
    });

    if(it != people.end()) {

        return std::distance(people.begin(), it);

    } else {

        return -1;

    }
}

Ответы [ 2 ]

2 голосов
/ 09 июля 2019

Вероятно, основная проблема в том, что вы пытаетесь получить доступ к name[k-1] и lastname[k-1], когда k=0, что приводит к UB.

Прежде чем продолжить работу, начните изучать алгоритмы STL . Имея это в виду, ваша задача становится тривиальной, используя только find_if и std::string::find:

#include <algorithm>
#include <iostream>
#include <vector>
#include <string>

struct playerdata
{
    std::string lastname;

    playerdata(std::string lastname) :
        lastname(std::move(lastname))
    {
    }
};

int searchArray(std::vector<playerdata>& people, const std::string& name) 
{
    auto it = std::find_if(people.cbegin(), people.cend(), [&name](const playerdata& player){
        return player.lastname.find(name) != std::string::npos;
    });

    if(it != people.end())
        return std::distance(people.cbegin(), it);
    else 
        return -1;
}

}

LIVE DEMO

0 голосов
/ 10 июля 2019
  1. Прежде всего, ваш подход к решению верен, но нуждается в некотором улучшении.
  2. Я предположил, что вы не хотите решать его с помощью регулярного выражения или функции шаблона c ++, что было бы лучше
  3. Возможно, вы неправильно понимаете инструкцию break, которая влияет только на цикл, в котором она написана break
  4. Я объяснил недостающие моменты и необходимые улучшения в комментарии
    линии
  5. Поскольку вы не указали все детали, я должен был их принять.

`

SearchArray(std::vector<playerdata>& people, const std::string& keyWord) 
{

  int loc = -1;

  // Use a better variable name to explain its purpose instead of `i`
  // so you and other people like us can understand its meaning much faster
  for (int vectorIndex = 0; vectorIndex < people.size(); vectorIndex++)
  {
    // if length of the name is bigger than a lastname it can`t be a match so just continue
    if (keyWord.length() > people[vectorIndex].lastname.length())
    {
        continue;
    }

    int counter = 0;
    int charIndexKeyWord = 0;
    // Use a better variable name to explain its purpose instead of `k`
    for (int charIndexIarget = 0; charIndexIarget < people[vectorIndex].lastname.length(); charIndexIarget++)
    {           
        // Your for loop starts from 0 but you're trying to use [k-1] in your code
        // you shouldn't do that, because in the first iteration of the loop it will indicate -1 [k-1]
        // but it starts with 0, 

        //std::cout << keyWord[charIndexKeyWord] << std::endl;
        //std::cout << people[vectorIndex].lastname[charIndexIarget] << std::endl;
        //std::cout << counter << std::endl;
        //std::cout << "" << std::endl;

        // This is part of your code which needs improvment
        if (keyWord[charIndexKeyWord] == people[vectorIndex].lastname[charIndexIarget]) 
        {
            counter++; 
            charIndexKeyWord++;
        }
        else
        {
            // If you keep your code as it is, it will may also consider matches like susnhine `sun` because
            // so you need to make some improvements to get rid of it.
            // if you have already founded a match but next word is not a match then you need to start looking from  the beginning
            if (counter != 0)
            {
                counter = 0;
                charIndexKeyWord = 0;                   
            }               
        }

        if (counter == keyWord.length())
        {

            loc = vectorIndex;
        }
    }

    if (loc != -1)
    {
        break;
    }

}

return loc;

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...