发现不工作,而我试图创建一个包含在c + +中的独特元素的向量
问题描述:
当我试图创建一个包含独特元素的向量时,发现不工作。发现不工作,而我试图创建一个包含在c + +中的独特元素的向量
该字符串是第一个标记化,然后它需要颠倒。但是反向字符串中的元素必须是唯一的。
#include <cstring>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
vector<char *> myvec;
string input;
getline(cin,input);
char *token = std::strtok((char *)input.c_str()," ");
while (token != NULL)
{
if(find(myvec.begin(), myvec.end(), token) != myvec.end())
cout<< "\n Skipping duplicate";
else
myvec.push_back(token);
token = std::strtok(NULL, " ");
}
cout<<endl;
while (!myvec.empty())
{
cout<<myvec.back();
myvec.pop_back();
cout<<" ";
}
cout<<endl;
}
Input: A bird came down the walk down END
Output: END down walk the down came bird A
Down should be removed from output as it is duplicate word.
答
的问题是,你是存储指针为char,而不是字符串:
vector<char *> myvec;
代替
vector<string> myvec;
所以,当你写你的输入:
A bird came down the walk down END
^ ^
这两个“倒”是不同的词,并且它们被存储在不同的存储位置中,并且因为它们的地址是不同的。
类似的代码工作,但使用字符串,如下:
string input;
getline(cin, input);
stringstream str;
str << input;
vector<string> v;
while (str >> input){
if (find(v.begin(), v.end(), input) == v.end())
v.push_back(input);
}
cout << '\n';
for(auto p = v.rbegin(); p != v.rend(); ++p)
cout << *p << ' ';
cout << '\n';
答
由于vector<char*>
是指针的向量和token
是一个指针,以及,你是比较指针。两个不同的指针指向不同的值,然后它们不相等。
插入这在你的代码,你会看到其中的差别:
std::cout << "Memory address: " << token << " value: " << *token << std::endl;
要比较的值,而不是指针。如评论中所述,您可以尝试使用vector<char>
,然后使用*token
,或直接使用vector<string>
(这样您也可以避免input.c_str()
)。
PS:如果你想在矢量仍然使用char*
,你可以实现一个简单的功能是这样的:
bool check_character(vector<char*> vec, char* token)
{
for (int i = 0; i < vec.size(); i++)
{
if (*(vec.at(i)) == *token)
return true;
}
return false;
}
(PS代码未测试)
答
有几个问题与你的代码。首先,当您执行(char*) input.c_str()
时,您会丢弃const
,这会导致未定义的行为。
否则您的std::find()
正在寻找重复的指针它没有比较它们指向的字符串的内容。为此,您需要一个字符串比较函数,如std::strcmp
。 std::find_if函数允许你提供你自己的复杂比较函数(在下面的代码中我使用了一个lambda函数)。
int main()
{
std::vector<char*> myvec;
std::string input = "A bird came down the walk down END";
// removed for exposition
// std::getline(cin, input);
// don't cast away const, use the address of the first element
// THIS ONLY WORKS AFTER C++11
// (because no guarantee of null terminator before that)
char* token = std::strtok(&input[0], " ");
while(token != NULL)
{
// use find_if() to compare zero-terminated strings using std::strcmp
if(find_if(myvec.begin(), myvec.end(),
[token](char* t){ return std::strcmp(t, token) == 0; }) != myvec.end())
std::cout << "\n Skipping duplicate";
else
myvec.push_back(token);
token = std::strtok(NULL, " ");
}
std::cout << '\n';
while(!myvec.empty())
{
std::cout << myvec.back();
myvec.pop_back();
std::cout << " ";
}
std::cout << '\n';
}
未定义的行为,因为.c_str的'的返回值()''是const' – alain
你跳过重复** **指针不能复制的文本。 – Galik
@Alain:令牌化没有问题。但问题与查找。 – user3069523