在C++中使用find函数时出现问题
Trouble using find function in C++
当我使用std::find时,我正试图找出代码中的差异。
对于我的测试代码。我制作了一个名为Test 的矢量
std::vector<const char*> Test;
为了测试find函数,我使用push_back函数在test矢量中填充了伪数据
Test.push_back("F_S");
Test.push_back("FC");
Test.push_back("ID");
Test.push_back("CD");
Test.push_back("CT");
Test.push_back("DS");
Test.push_back("CR");
Test.push_back("5K_2");
Test.push_back("10K_5");
Test.push_back("10K_1");
Test.push_back("10K_2");
Test.push_back("10K_3");
Test.push_back("10K_4");
Test.push_back("10K_5");
我想用find函数做的是通过测试,看看是否有任何重复的数据。第一次遇到数据时,我会将其保存到一个名为Unique_data的向量中。
std::vector<const char*> Unique_Data;
因此,对于上面的14个数据点,由于10K_5重复,将只保存13个。
我使用的代码看起来像这个
for(int i = 0; i < Test.size(); i++)
{
if( Unique_Data.empty())
{
Unique_Data.push_back(Test[i]);
}
else if (std::find(Unique_Data.begin(), Unique_Data.end(), Test[i]) != Unique_Data.end())
{
// Move on to next index
}
else
{
Unique_Data.push_back(Test[i]);
}
}
我遇到的问题是当我使用伪数据时。我得到了Unique_Data的正确答案。
但是,如果我将实际数据保存到保存在链表中的测试向量中。我知道它们都是独一无二的。
代码看起来像这个
p_curr = List.p_root;
while(p_curr != NULL)
{
// id starts from 0
if(atoi(p_curr->id) == 14) break;
Test.push_back(p_curr->Descriptor);
p_curr = p_curr->p_next;
}
我用同样的14个数据进行了测试。它们都是const-char*类型。但是,当我使用链表数据时。find函数认为所有数据都是唯一的。
有人能告诉我这是怎么回事吗?
使用C风格的字符串有点棘手,它们只是一个指针,指针是通过标识进行比较的。两个C字符串具有相同的字符序列,但不同的地址会比较不同。
const char first[] = "Hi";
const char second[] = "Hi";
assert(first == second); // will fail!
这个问题有两种解决办法。简单的方法是在容器中使用std::string
,因为std::string
将提供值比较。另一种选择是将比较函子作为最后一个参数传递给std::find
。但这仍然会留下管理存储在向量中的const char*
-s的寿命的问题。
这是一个指针问题。您不是在数组中存储字符串,而是在字符串中存储数据的内存地址。
这种奇怪的行为可能是因为在您的示例中,您有无法更改的文本字符串,因此编译器正在优化存储,当两个字符串相同时,它会为所有具有相同文本的字符串存储相同的地址。
在实际数据示例中,有一组字符串保存相同的数据,但这些字符串中的每一个都位于不同的内存地址,因此find函数表示所有字符串都有不同的地址。
总之,find函数查看的是字符串的内存地址,而不是字符串中的数据(文本)。如果使用std::string,那么这个问题就会消失。
我强烈建议使用字符串,因为性能会非常好,而且它们可以消除大量问题。
正如David Rodriguez在回答中提到的,您只比较指针,而不是字符串本身的内容。如果存储std::string
而不是char const *
,您的解决方案将按原样工作。对于后者,您需要使用std::find_if
和调用strcmp
的谓词来确定字符串是否相同。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
int main()
{
std::vector<const char*> Test;
Test.push_back("F_S");
Test.push_back("FC");
Test.push_back("ID");
Test.push_back("CD");
Test.push_back("CT");
Test.push_back("DS");
Test.push_back("CR");
Test.push_back("5K_2");
Test.push_back("10K_5");
Test.push_back("10K_1");
Test.push_back("10K_2");
Test.push_back("10K_3");
Test.push_back("10K_4");
Test.push_back("10K_5");
std::vector<const char*> Unique_Data;
for(auto const& s1 : Test) {
if(std::find_i(Unique_Data.cbegin(), Unique_Data.cend(),
[&](const char *s2) { return std::strcmp(s1, s2) == 0; })
== Unique_Data.cend()) {
Unique_Data.push_back(s1);
}
}
for(auto const& s : Unique_Data) {
std::cout << s << 'n';
}
}
下面是的一个实例
- Visual Studio中的函数声明和函数定义问题
- C++quit()函数中可能存在作用域问题
- 类似于strcat()的函数出现问题
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 类C++中的函数问题(LNK2019和LNK1120错误)
- c++binary_search函数排序数组(流行名称搜索)出现问题
- 关于简单C++函数(is_palindrome)的逻辑的问题
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 如何在C++向量中奇数元素前面加上值-1,我在使用insert函数时遇到了问题
- constexpr构造函数需要常量成员函数时出现问题
- 添加存储在向量中的大整数的函数出现问题
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 关于 c++ 函数中指针赋值的简单问题
- 如何在标头中声明(或定义)函数的问题
- 有关 c++ 构造函数的问题
- 模板类转换问题 - 无法推断调用的函数
- 从 C++ 中的函数返回数组地址问题
- 关于复制构造函数的一个棘手问题
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- Arduino:在 loop() 和自定义函数中运行相同的代码时出现问题