Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ reading input for programming contests

Tags:

c++

What is the easiest way code parsing string input like the following:

WORD WORD2
WORD3 WORD4

WORD5
WORD6

That is, an unknown number of pairs of words followed by a blank line followed by an unknown number of words one-per line. I want to put the first group of these words into a map, and the second list of words into a vector.

Using getline has problems discovering when the first group of paired words terminates.

like image 750
Neil G Avatar asked Aug 29 '26 09:08

Neil G


1 Answers

A simple matter of using getline and some containers:

#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <map>

std::map<std::string, std::string> m;
std::vector<std::string>           v;

for (std::string line; std::getline(std::cin, line); )
{
    if (line.empty()) { break; }

    std::string x, y;
    std::istringstream iss(line);

    if (!(iss >> x >> y >> std::ws)) { /* fatal error */ }

    m[x] = y;
}   

for (std::string line; std::getline(std::cin, line); )
{
    v.push_back(std::move(line));
}

std::cout << "We read " << m.size() << " pairs and " << v.size() << " words.\n";

If you want to make sure that the first part of the file consists precisely of pairs of words with a single region of whitespace in between, you can strengthen the condition to this:

if (!(iss >> x >> y >> std::ws) || iss.get() != EOF) { /* fatal error */ }

Similarly, you can add a check that the second part of the file contains no whitespace if you like. Finally, you could use insert() for the map to check that there are no duplicate keys; in C++11, you should be able to say m.emplace(std::move(x), std::move(y));. And an unordered_map is probably a lot more efficient with strings.

like image 52
Kerrek SB Avatar answered Aug 31 '26 22:08

Kerrek SB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!