1

I need to convert letters into a dictionary of characters. Here's an example:

letter

l: 1
e: 2
t: 2
r: 1

I did some research and found this helpful answer, but that was using getline() and separating words by spaces. Since I am trying to split by character I don't think I can use getline() since '' isn't a valid split character. I could convert to a char* array but I wasn't sure where that would get me.

This is fairly easy in other languages so I thought it wouldn't be too bad in C++. I was hoping there would be something like a my_map[key]++ or something. In Go I would write this as

// Word map of string: int values
var wordMap = make(map[string]int)

// For each letter, add to that key
for i := 0; i < len(word); i++ {
    wordMap[string(word[i])]++
}

// In the end you have a map of each letter.

How could I apply this in C++?

Developer
  • 11
  • 1
  • 1
    Depends on how you want to approach it; a character is also just a number (ASCII-ish chars, anyway). – Dave Newton Nov 25 '21 at 18:22
  • Similar questions: [How do I frequency count characters?](https://stackoverflow.com/questions/67730078/c-how-do-i-frequency-count-characters); [Count character occurrences in a string](https://stackoverflow.com/questions/3867890/count-character-occurrences-in-a-string-in-c); [Counting the frequency of characters in a file](https://stackoverflow.com/questions/13553140/counting-the-frequency-of-characters-in-a-file-c); – Stef Nov 25 '21 at 18:23
  • Similar questions: [program to check the frequencies of the letters](https://stackoverflow.com/questions/38547564/c-program-to-check-the-frequencies-of-the-letters); [calculate frequency of each letter in a string](https://stackoverflow.com/questions/28383292/calculate-frequency-of-each-letter-in-a-string); – Stef Nov 25 '21 at 18:23
  • @DaveNewton I need to sort a dictionary and see if each word in the English dictionary contains the letters of my word. So if my word was `sale`, then the word `wales` would be a match. I figure the best way to do it is create a map of letters for each English dictionary word and see if they have at least the same amount of the same letters. – Developer Nov 25 '21 at 18:24
  • The answer you linked counts occurrences of *words*. You are interested in counting occurrences of *characters*. You can use an `std::unordered_map`. No need to map whole strings to ints. Or you could even use a `std::vector` and index the vector directly by the ascii codes. – Stef Nov 25 '21 at 18:25
  • That's a very different kind of problem and against a large corpus becomes more algorithmic. I mighty instead consider something like a bitmap, so a 32-bit int per dictionary word, and a logical operation. I'm sure there's many solutions, though, of better and worse efficiency. – Dave Newton Nov 25 '21 at 18:52

3 Answers3

1

How could I apply this in C++?

It could look rather similar to your Go code.

// Word map of char: int values
// (strings would be overkill, since you know they are a single character)
auto wordMap = std::map<char,int>{};

// For each letter, add to that key
for ( char c : word )
    wordMap[c]++;
}
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
1

Here is the unicode version of Drew Dormann's answer:

#include <locale>
#include <codecvt>

std::string word = "some unicode: こんにちは世界";

std::map<char32_t, uint> wordMap;
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;

for (auto c : converter.from_bytes(word)) {
    wordMap[c]++;
}

for (const auto [c, v] : wordMap) {
    std::cout << converter.to_bytes(c) << " : " << v << std::endl;
}
floomby
  • 191
  • 1
  • 9
-1

I wrote an article about this which can be checked out here. Below i have given 2 versions of the program. Version 1 keeps track of the character count in alphabetical order. But sometimes(in case) you want the character count in insertion order for which you can use Version 2.

Version 1: Get character count in ͟a͟l͟p͟h͟a͟b͟e͟t͟i͟c͟a͟l͟ ͟o͟r͟d͟e͟r͟

#include <iostream> //needed for std::cout, std::cin
#include <map>      //needed for std::map
#include <iomanip>  //needed for formating the output (std::setw)

int main() 
{
    std::string inputString; //user input will be read into this string variable
    std::cout << "Enter a string: " << std::endl;
    std::getline(std::cin, inputString);
    //this map maps the char to their respective count
    std::map < char, int > charCount;
    //iterate through the inputString
    for (char & c: inputString) 
    {
        charCount[c]++;//increment the count for character c
    }
    std::cout << "Total unique characters are: " << charCount.size() << std::endl;
    std::cout << "------------------------------------" << std::endl;
    std::cout << "Character" << std::setw(10) << "Count" << std::endl;
    std::cout << "------------------------------------" << std::endl;
    for (std::pair < char, int > pairElement: charCount) 
    {
        std::cout << std::setw(4) << pairElement.first << std::setw(13) << pairElement.second << std::endl;
    }
    return 0;
}

Version 2: Get character count in i͟n͟s͟e͟r͟t͟i͟o͟n͟ ͟o͟r͟d͟e͟r͟

#include <iostream> 
#include <map>      
#include <iomanip>  

int main() 
{
    std::string inputString; 
    std::cout << "Enter a string: " << std::endl;
    std::getline(std::cin, inputString);
    
    std::map < char, int > charCount;
    
    for (char & c: inputString) 
    {
        charCount[c]++;
    }
    std::cout << "Total unique characters are: " << charCount.size() << std::endl;
    std::cout << "------------------------------------" << std::endl;
    std::cout << "Character" << std::setw(10) << "Count" << std::endl;
    std::cout << "------------------------------------" << std::endl;
    std::size_t i = 0;
    //just go through the inputString instead of map
    for(char &c: inputString)
    {
        std::size_t index = inputString.find(c);
        if(index != inputString.npos && (index == i)){
         std::cout << std::setw(4) << c << std::setw(13) << charCount.at(c)<<std::endl;
         
        }
        ++i;
    }
    return 0;
}
Jason
  • 36,170
  • 5
  • 26
  • 60