【问题标题】: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 时表现出未定义的行为。

标签: c++11


【解决方案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】:
  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;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 2013-04-28
    • 2019-08-28
    相关资源
    最近更新 更多