Home > Back-end >  Is there any way to use std::cout when calling a function within a class?
Is there any way to use std::cout when calling a function within a class?

Time:11-15

#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>

class Solution {
public:
    std::vector<std::vector<std::string>> groupAna(std::vector<std::string> strs) {
        std::unordered_map<std::string, std::vector<std::string>> ana;
        for (int i {0}; i < strs.size();   i)
        {
            std::string key = getKey(strs[i]);
            ana[key].push_back(strs[i]);
        }
        
        std::vector<std::vector<std::string>> results;
        for (auto it = ana.begin(); it != ana.end();   it)
        {
            results.push_back(it->second);
        }
        
//        for (int i {0}; i < results.size();   i)
//        {
//            for (int j {0}; j < results[i].size();   j)
//            {
//                std::cout << results[i][j] << " ";
//            }
//        }
        return results;
    }
    
private:
    std::string getKey(std::string str) {
        std::vector<int> count(26);
        for (int i {0}; i < str.length();   i)
        {
              count[str[i] - 'a'];
        }
        
        std::string key {""};
        for (int j {0}; j < 26;   j)
        {
            key.append(std::to_string(count[j]   'a'));
        }
        
        return key;
    }
};

int main() {
    std::vector<std::string> strs ({"eat","tea","tan","ate","nat","bat"});
    Solution obj;
    std::cout << obj.groupAna(strs);
    
    return 0;
}

I receive this error:

Invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'std::vector<std::vector<std::string>>' (aka 'vector<vector<basic_string<char, char_traits<char>, allocator<char>>>>'))

This solution is for Group Anagrams on Leetcode. I'm just using XCode to practice writing out all the code needed, instead of using what Leetcode gives.

My issue comes when calling and trying to print the groupAna() function in class Solution. I believe the error is telling me what I want to print isn't something you can print, but I have no idea if that's entirely correct.

I'm ultimately trying to print each string inside its respective vector. What's commented out was a workaround that gives me what I want, but it doesn't show each word in a vector, so how can I tell if it's in the vector it's suppose to be in, other than it being in the correct order?

Output is bat tan nat eat tea ate

CodePudding user response:

The member function groupAna returns a std::vector<std::vector<std::string>> but there are no operator<< overloads for std::vectors. You could output to a std::ostringstream instead and then return a std::string:

#include <sstream>

class Solution {
public:
    // now returns a std::string instead:
    std::string groupAna(const std::vector<std::string>& strs) {
        std::unordered_map<std::string, std::vector<std::string>> ana;
        for (size_t i{0}; i < strs.size();   i) {
            std::string key = getKey(strs[i]);
            ana[key].push_back(strs[i]);
        }

        std::vector<std::vector<std::string>> results;
        for (auto it = ana.begin(); it != ana.end();   it) {
            results.push_back(it->second);
        }

        std::ostringstream os; // used to build the output string
        for (size_t i{0}; i < results.size();   i) {
            for (size_t j{0}; j < results[i].size();   j) {
                os << results[i][j] << ' ';
            }
        }
        /* or using a range based for-loop:
        for(const auto& inner : results) {
            for(const std::string& str : inner) {
                os << str << ' ';
            }
        }
        */
        return os.str(); // return the resulting string
    }
// ...
};

CodePudding user response:

Leetcode will ask you to implement a given function, and they will try your code with a battery of unit tests, feeding each test with an input and expecting an output. That is, you don't need to print the vector of vectors of strings within the groupAnagrams function, but just generate that matrix correctly.

Anyway, should you want to test your code, and print the output from groupAnagrams, you could use the fmt library. The <fmt/ranges.h> header lets you print standard containers. In the case of vectors, it will print them enclosed in square brackets. For your example, notice that you will have inner vectors.

[Demo]

#include <fmt/ranges.h>

int main() {
    std::vector<std::string> strs({"eat", "tea", "tan", "ate", "nat", "bat"});
    Solution obj;
    fmt::print("{}", obj.groupAna(strs));
}

// Outputs: [["bat"], ["tan", "nat"], ["eat", "tea", "ate"]]

Or, if you want to flatten that structure, apart from the two solutions proposed by Ted Lyngmo (streams and two nested range-based for loops), you could use C 23 ranges.

[Demo]

#include <fmt/core.h>
#include <ranges>

int main() {
    std::vector<std::string> strs({"eat", "tea", "tan", "ate", "nat", "bat"});
    Solution obj;
    auto&& groups{ obj.groupAna(strs) };
    for (auto&& str : (groups | std::views::join)) {
        fmt::print("{} ", str);
    }
}

// Outputs: bat tan nat eat tea ate
  • Related