1

I've got a string that is "{a, b, c, d}" and I want to take the letters in that string and put them into a set that contains these letters and then output it's size. I've tried doing the code but it would give me an error.

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

string text;
set <char> yeet;

int main()
{
    cin >> text;

    yeet.insert(text);

    cout << yeet.size();
}

Input:

{a, b, c, d}

Output:

4
Smartie
  • 85
  • 8
  • Do you want to insert each char of the string? Or the string as a char? The latter is not possible. – Dimfred Apr 16 '20 at 09:48
  • just a tip for future questions: your code only misses the includes to qualify as [mcve]. It is better if you add them already in your code instead of relying on others to do that. Also to make it a good question you should have said what is the expected output. I had to guess that you want `4`, but as the other comment says, there is some uncertainty on what you want. Also hardcoding the input instead of using `std::cin` makes it easier to run the code – 463035818_is_not_an_ai Apr 16 '20 at 09:52
  • why dont you use `"abcd"` as input? using `"{a, b, c, d}"` makes it much more complicated. As this is user input, it isnt obvious why you want to add brackets and `,`, I mean you can ask the user to use the format that is best to process – 463035818_is_not_an_ai Apr 16 '20 at 10:36

2 Answers2

3

std::set::insert has an overload that takes two iterators to a range of elements to be inserted and to remove the unwanted characters in the string you can use the erase-remove-idiom (see eg here). I could have used remove_if to remove all in one go, but for a string of small size, better keep it simple.

#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();
}

Output:

4

Note that if you want to construct a set from all characters in a string you can use the constructor instead:

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

Last but not least some recommendations:

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • @Smartie I understand that that is what you asked for. On a second thought.. is the contents of the string `"{a, b, c, d}"` literally? see why it is better to include the input in the code :P. Please clarify then I can update the question. Though if the string really is `"{a, b, c, d}"` then it needs some parsing and you have to be precise about the format, is it always character followed by `,` and a single space? – 463035818_is_not_an_ai Apr 16 '20 at 10:28
  • Yeah I'm new to this so I need some time knowing how to do stuff, yes, the character is always followed by a ```,``` and a single space. – Smartie Apr 16 '20 at 10:34
  • Edited my answer as well, after realizing the same :) –  Apr 16 '20 at 11:24
  • I've tried to make the string get entered by the user but somehow, even if I write the same exact string, it would somehow not work? – Smartie Apr 19 '20 at 06:45
  • It would mean that instead of giving the same number of set, it would give out the size as 1, I checked with the string, turns out it gets changed from {a, b, c, d} to a when the string is inputted from the user. @idclev463035818 – Smartie Apr 19 '20 at 09:30
  • @Smartie to read a line you have to use `getline`, `std::cin` only read till the first whitespace – 463035818_is_not_an_ai Apr 19 '20 at 09:31
1

You can traverse through the string and insert each character into the set:

#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();    
}

However, its not necessary to write a loop to insert into a set container. A much simpler approach would be to use std::set::insert() with two iterator positions as @idclev463035818 mentioned, or directly constructing the set at the time of declaration using a constructor.

Consider the loop approach as an alternative.

Additionally, you can change iterator positions if you want to get elements from specific parts of the string. (loop works too, but the former includes shorter code)

Remember that a set holds distinct elements, so only the unique ones would be inserted and correspondingly account for total size.


Edit:

Based on the string having characters apart from the alphabets, with your requirement being to take only the alphabets, (a, b, c and d in your example) you can use issalpha().

A more generic approach, to include only the character you desire (even alphabets or any character in general) can be followed by creating a function (of boolean type) which distinguishes those characters and provides the same information to std::remove_if (include <algorithm>), to erase those elements (again, following the erase-remove-idiom) via a std::erase from your string:

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

Working example:

#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();    
}

Output: 4

  • for a set there is no difference in terms of complexity or allocations, but you do not need to write the loop yourself (and for other containers eg a vector, it does make a difference) – 463035818_is_not_an_ai Apr 16 '20 at 09:54
  • nah you dont have to refer to my answer (usernames can change btw, so it can get outdated). It doesnt hurt to have different valid answers. As I said, for a set it is only a matter of taste, you have my vote – 463035818_is_not_an_ai Apr 16 '20 at 10:10
  • @idclev463035818 Aye, thank you :) I would prefer your answer over mine, hence I changed. (its shorter and for the reason we can directly construct the set at the time of declaring it) –  Apr 16 '20 at 10:13