发现不工作,而我试图创建一个包含在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. 
+1

未定义的行为,因为.c_str的'的返回值()''是const' – alain

+0

你跳过重复** **指针不能复制的文本。 – Galik

+0

@Alain:令牌化没有问题。但问题与查找。 – user3069523

的问题是,你是存储指针为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::strcmpstd::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'; 
}