【问题标题】:Is there a way of inserting a string into a char set? C++有没有办法将字符串插入字符集中? C++
【发布时间】:2020-04-16 09:44:51
【问题描述】:

我有一个字符串“{a, b, c, d}”,我想取出该字符串中的字母并将它们放入包含这些字母的集合中,然后输出它的大小。我已经尝试过编写代码,但它会给我一个错误。

#include <bits/stdc++.h>
using namespace std;

string text;
set <char> yeet;

int main()
{
    cin >> text;

    yeet.insert(text);

    cout << yeet.size();
}

输入:

{a, b, c, d}

输出:

4

【问题讨论】:

  • 你想插入字符串的每个字符吗?还是字符串作为字符?后者是不可能的。
  • 只是对未来问题的提示:您的代码仅错过了符合 minimal reproducible example 的条件。最好将它们添加到代码中,而不是依赖其他人来做。为了使它成为一个好问题,您应该说预期的输出是什么。我不得不猜测你想要4,但正如另一条评论所说,你想要什么存在一些不确定性。此外,硬编码输入而不是使用std::cin 可以更轻松地运行代码
  • 为什么不使用"abcd" 作为输入?使用"{a, b, c, d}" 会使它变得更加复杂。由于这是用户输入,所以不明显为什么要添加括号和,,我的意思是您可以要求用户使用最适合处理的格式
  • 查看更新的答案

标签: c++ string char set


【解决方案1】:

std::set::insert 有一个重载,它需要两个迭代器来插入一系列元素并删除字符串中不需要的字符,您可以使用erase-remove-idiom(参见例如here)。我本可以使用remove_if 一次性删除所有内容,但是对于较小的字符串,最好保持简单。

#include <string>
#include <set>
#include <iostream>
#include <algorithm>

int main()
{
    std::string text{"{a, b, c, d}"};

    text.erase(std::remove(text.begin(), text.end(), '{'), text.end()); 
    text.erase(std::remove(text.begin(), text.end(), '}'), text.end()); 
    text.erase(std::remove(text.begin(), text.end(), ','), text.end()); 
    text.erase(std::remove(text.begin(), text.end(), ' '), text.end()); 
    std::set<char> yeet;            

    yeet.insert(text.begin(),text.end());

    std::cout << yeet.size();
}

输出:

4

请注意,如果您想从 string 中的所有字符构造 set,则可以改用构造函数:

std::set<char> yeet(text.begin(),text.end());

最后但并非最不重要的一些建议:

【讨论】:

  • @Smartie 我知道这就是您的要求。再想一想.. 字符串 "{a, b, c, d}" 的内容是字面意思吗?看看为什么最好在代码中包含输入:P。请澄清,然后我可以更新问题。虽然如果字符串真的是"{a, b, c, d}",那么它需要一些解析,并且您必须准确了解格式,它是否总是字符后跟, 和一个空格?
  • 是的,我是新手,所以我需要一些时间来了解如何操作,是的,字符后面总是跟一个 , 和一个空格。
  • 在意识到同样的事情之后也编辑了我的答案:)
  • 我试图让用户输入字符串,但不知何故,即使我写了完全相同的字符串,它也不行吗?
  • 这意味着不是给出相同数量的集合,而是给出大小为 1,我用字符串检查,结果它从 {a, b, c, d } 到用户输入字符串时的 a。 @idclev463035818
【解决方案2】:

可以遍历字符串,将每个字符插入到集合中:

#include <iostream>
#include <set>
int main() 
{ 
  std::string text;
  std::cin>> text;
  std::set<char> yeet;
  for(char c:text)
    yeet.insert(c);
  std::cout<< yeet.size();    
}

但是,不必编写循环插入到集合容器中。一个更简单的方法是使用std::set::insert() 和两个迭代器位置,如@idclev463035818 所述,或者在声明时使用构造函数直接构造集合。

考虑使用循环方法作为替代方法。

此外,如果您想从字符串的特定部分获取元素,您可以更改迭代器的位置。 (循环也可以,但前者包含更短的代码)

请记住,集合包含不同的元素,因此只有唯一的元素会被插入并相应地占总大小。


编辑:

基于除字母之外的字符的字符串,您的要求是仅采用字母(在您的示例中为 a、b、c 和 d),您可以使用 issalpha()。

更通用的方法是只包含您想要的字符(甚至是字母或任何一般字符),然后可以创建一个函数(布尔类型)来区分这些字符并向std::remove_if提供相同的信息(包括&lt;algorithm&gt;),通过std::erase从你的字符串中删除这些元素(同样,在erase-remove-idiom之后):

bool IsValid(char c) { return(c == '{' || c == '}' || c == ',' || c == ' '); }

工作示例:

#include <iostream>
#include <set>
#include <algorithm>

bool IsValid(char c) { return(c == '{' || c == '}' || c == ',' || c == ' '); }

int main()
{
   std::string text = {"{a, b, c, d}"};
   text.erase(std::remove_if(text.begin(), text.end(), IsValid), text.end());  
   std::set<char> yeet(text.begin(),text.end());
   std::cout << yeet.size();    
}

输出:4

【讨论】:

  • 对于一个集合,在复杂性或分配方面没有区别,但您不需要自己编写循环(对于其他容器,例如向量,它确实会有所不同)
  • 不,你不必参考我的答案(用户名可以顺便改变一下,所以它可能会过时)。有不同的有效答案并没有什么坏处。正如我所说,对于一套来说,这只是一个品味问题,你有我的投票权
  • @idclev463035818 是的,谢谢 :) 我更喜欢你的回答而不是我的回答,因此我改变了。 (它更短,因为我们可以在声明它的时候直接构造它)
猜你喜欢
  • 1970-01-01
  • 2020-03-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多