为什么我的搜索功能无法按预期运行,该如何解决?

时间:2019-07-09 00:32:16

标签: c++11

我正在尝试创建一个比较搜索功能,该功能可以根据字符将两个字符串进行比较。例如:

输入:“ ca” 姓氏字段下的结构矢量内容(排序矢量)(索引/值):0 /“汽车”,1 /“道路” 结果:“在索引0找到名称-汽车”

我希望用户能够使用任意数量的字符。然后,程序应将提供的搜索条件与向量的内容进行比较,并返回所有匹配项的索引。

到目前为止,我还没有实现任何成功的尝试,这是到目前为止的代码。另外,我对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:

编辑:正如您从我的控制台输出中看到的那样,当代码不应该这样做时,它会返回真正的比较。一个示例是is(e == n)的最后一个比较。答案应该是错误的,但始终会返回true。

使用注释中建议的代码后,我仍然无法使我的代码按预期工作并出现以下错误:

    ||=== 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 个答案:

答案 0 :(得分:2)

可能的主要问题是,您尝试访问lastname[k-1]时访问k=0find_if,这会导致UB。

在继续工作之前,请开始学习STL algorithms。考虑到这一点,仅使用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; } 即可完成您的任务:

{{1}}

}

LIVE DEMO

答案 1 :(得分:0)

  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;

}