为啥我的搜索功能没有按预期工作,我该如何解决?
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_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
【讨论】:
问题是我使用了 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;
【讨论】:
以上是关于为啥我的搜索功能没有按预期工作,我该如何解决?的主要内容,如果未能解决你的问题,请参考以下文章