为啥我的搜索功能没有按预期工作,我该如何解决?

Posted

技术标签:

【中文标题】为啥我的搜索功能没有按预期工作,我该如何解决?【英文标题】:Why is my search function not working as expected and how do I fix it?为什么我的搜索功能没有按预期工作,我该如何解决? 【发布时间】:2019-07-09 00:32:16 【问题描述】:

我正在尝试制作一个比较搜索功能,可以根据字符将两个字符串一起比较。例如:

输入:“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) 的最后一个比较。答案应该是假的,但它一直返回真。

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

    ||=== 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;

    

【问题讨论】:

马上,name[k-1] 在循环的第一次迭代中出现k == 0 时表现出未定义的行为。 【参考方案1】:

可能主要问题是您尝试访问name[k-1]lastname[k-1],而k=0 则导致UB。

在继续工作之前,请开始学习STL algorithms。考虑到这一点,仅使用 find_ifstd::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

【讨论】:

问题是我使用了 name[k] 并且仍然得到相同的结果,所以我尝试使用 - 1 进行测试。我想我会 100% 学习 STL 算法。 另外,这不适用于我的代码。首先,我的向量是结构而不是字符串的向量,而且它不断给我奇怪的错误,我不知道如何修复。它一直将我指向模板的一些随机 c++ 文件 是的,你必须调整你的代码。你没有发布playerdata 的样子,所以我只使用了std::string,因为这就是你想要搜索的类型。 @Aeryes 仅仅因为您不了解错误消息,并不意味着它们是随机的,它们绝不是随机的。买一本好的 C++ 书,在做出这样的陈述之前先学习这门语言。 LMAO 我的意思不是随机的。【参考方案2】:
    首先,您的解决方法是正确的,但需要一些 改进。 我假设您不想使用正则表达式或模板 c++ 函数来解决它 哪个更好 您可能对 break 语句有误解,它会影响 只有循环它写在break 我已经解释了评论中的缺失点和需要改进的地方 线条 由于您没有指定所有细节,我不得不假设它们。

`

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;

【讨论】:

以上是关于为啥我的搜索功能没有按预期工作,我该如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

我的挤压功能没有按预期工作,我该怎么做才能修复这个功能?

MYSQL LAST_INSERT_ID 未按预期工作。我该如何解决?

为啥这个 CSS 过渡没有按预期工作? [复制]

为啥我的替换没有按预期工作[重复]

为啥我的查询没有按预期工作?

为啥我的 javascript 代码没有按预期工作