Module 3 ¡ string: Text That Knows Its Own Length
Problems: string
In this lesson
- Read words with
cin >>and whole lines withgetline, including a line that follows a number. - Use
find,substr,+=andto_stringto take text apart and build an answer, checking every search againststring::npos. - Choose
long longor a string of digits for every number, and build a long answer in time.
Ten problems, graded against hidden tests. Each one practises an idea from lessons 01 to 06 of this module. Problems 1, 2 and 5 are free. The other seven open with Learn Pro or with the track.
Bob reads the sample, writes a loop and submits. Zara first tries one word, an empty match, a line that starts with spaces and the longest input. In a set about text, Zara's habit earns the marks.
Every starter reads its text in one of three shapes
Each starter turns on fast input and output with ios::sync_with_stdio(false); and cin.tie(nullptr);, from Module 1. Then it reads the input in one of three shapes. The largest tests are about 1 MB of text, so reading speed matters.
Some problems give words: cin >> word reads one run of characters without a space, and skips any spaces and line breaks before it. Some give lines: getline(cin, line) reads a whole line, spaces included, and drops the line break. And some give a count first, then lines. That third shape has a trap of its own, two sections down.
The judge never looks inside your strings. It runs your whole program on a hidden input and compares what it prints, line by line. Spaces at the end of a line are ignored, but spaces inside a line are not. Words such as yes, no and none are printed exactly as written. End every line with '\n'.
ASCII only, so size() counts characters
Lesson 01 showed that a string is a row of bytes. A Bangla letter takes 3 bytes in UTF-8, so size() of a Bangla word is not its number of letters. Every input in this set is ASCII: the characters from 32, the space, to 126, the tilde ~, plus line breaks. Each of those is one byte.
So here s.size() is the number of characters, and s[i] is the character at position i, counting from 0. Every statement says this again, so that no answer depends on how text is encoded. Letters sit in two unbroken runs, 'A' to 'Z' and 'a' to 'z', and the digits run from '0' to '9'.
A line after cin >> n needs one getline first
cin >> n reads the number and stops right after its last digit. The line break that ended that line is still waiting in the input. The next getline reads up to that line break, so it returns an empty line.
That is why three starters below read the count, then call getline(cin, line); once with the comment "finish the line that held n". Keep that line. Without it, the first line you check is the empty one, and the last real line is never read. Mistake 1 below shows the output.
find says npos, never -1
s.find(t) returns the index where t first starts in s. When there is no match, it returns string::npos, the largest value a size_t can hold. So the test is always pos == string::npos, never pos == -1 or pos < 0.
Keep the result in a size_t, the type find returns. s.find(t, from) starts the search at index from, which is how a loop finds every match. substr(pos, len) takes len characters from pos, and substr(pos) takes everything from pos to the end. So find and substr together cut a string at any character.
When a number outgrows long long
A long long holds up to 9223372036854775807, a little over 9 x 1018. thousands-separator stays inside that: its numbers reach 1018, and even -1018 fits. to_string(x) turns such a number into text, and stoi and stoll turn text back into a number.
big-add is different. Its numbers have up to 100000 digits, and no built-in type holds even 20. Such a number stays a string, and you add it the way you do on paper, one column at a time. The picture shows the sample, 958 plus 67.
A column adds a digit from each number and the carry. Its last digit is written down, and its tens become the next carry. The two edges, a number that runs out first and a carry left at the end, are the problem's to solve.
Build the answer with +=, not with ans = ans + piece
Every problem allows 1 second per test, for the whole program, reading included. In run-length, the answer for 500000 runs of one letter is 1000000 characters long. How you grow it decides whether you pass.
ans += piece adds the piece at the end of ans, where it already lives. Lesson 05 shows why that costs amortised O(1) per character. ans = ans + piece first builds a brand new string: a copy of all of ans, then the piece. Inside a loop, that copies the whole answer once per run.
We measured both on the largest test, 500000 runs of length 1, and on its first 10000 to 200000 letters. Each program timed only the encoding loop with chrono::steady_clock. Each number is a run on Compiler Explorer, GCC 12.2, g++ -O2 -std=c++17, the Playground's flags. Every row ran at least three times in each of two sessions, and the table gives the range. Compiler Explorer stops a program after about 20 seconds.
| Way | Input | Time, two sessions |
|---|---|---|
ans = ans + piece | 10000 letters | 2.7 to 5.8 ms |
ans = ans + piece | 25000 letters | 36 to 50 ms |
ans = ans + piece | 50000 letters | 289 to 475 ms |
ans = ans + piece | 100000 letters | 1988 to 4325 ms |
ans = ans + piece | 200000 letters | 12642 to 14958 ms in four runs; stopped after about 20 s in two |
ans = ans + piece | 500000 letters, the largest test | stopped after about 20 s, all six runs |
ans += piece | 500000 letters, the largest test | 5.6 to 12.8 ms |
Both versions print the same correct answer. On the largest test, ans += piece needs 5.6 to 12.8 ms, and the other way runs out of time on Compiler Explorer every time. That test stays in run-length's hidden set, so ans = ans + piece cannot pass. The same holds for any answer that grows inside a loop.
The forms these ten problems need
cin >> word; one word: no spaces; false at the end of the input
getline(cin, line); a whole line, spaces kept, the line break dropped
cin >> n; getline(cin, line); finish the line that held n, then read lines
s.size() s[i] s.empty() length in bytes (ASCII: characters), char i, "is it empty?"
s.find(t) s.find(t, from) first index of t (from index from), or string::npos
s.substr(pos, len) len characters from pos; substr(pos) runs to the end
s += c; s += t; append at the end, where s already lives
to_string(x) stoi(t) stoll(t) number to text; text to int or long long
istringstream in(line); a line read like cin: in >> w gives its words
getline(in, part, ','); read up to the next comma, and drop the comma
isalnum((unsigned char)c) tolower((unsigned char)c) letters and digits; small letters
reverse(s.begin(), s.end()); the characters in the opposite order
- Every starter below already reads the input. Keep those lines, and write your code where the comment says.
istringstreamneeds<sstream>,isalnumandtolowerneed<cctype>, andreverseneeds<algorithm>. Add the include when a starter lacks it.- Test the edges before the sample: one word, one character, no match, a line of spaces, and the largest input.
Alice paints signs for shops. For each sign she needs the number of characters and the number of spaces.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
string line;
getline(cin, line); // finish the line that held n
for (int i = 0; i < n; i++) {
getline(cin, line);
int spaces = 0;
for (char c : line) {
if (c == ' ') {
spaces++;
}
}
// ASCII text: size() is the number of characters.
cout << line.size() << " chars, " << spaces << " spaces\n";
}
return 0;
}
13 chars, 2 spaces
13 chars, 3 spaces
3 chars, 0 spaces
That output is for the input 3, then the three signs OPEN 24 HOURS, Fresh bread with two spaces in front, and Tea.
getline keeps the two leading spaces of the second sign, so they count: 13 characters and 3 spaces. cin >> would have skipped them. Delete the first getline and the program reports an empty sign of 0 characters first, then never reaches Tea.
Zara logs her run times as minutes:seconds. Print each time in seconds, or bad when a time has no colon.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
for (int i = 0; i < n; i++) {
string t;
cin >> t;
// find returns a size_t: an index, or string::npos for no match.
size_t colon = t.find(':');
if (colon == string::npos) {
cout << "bad\n";
continue;
}
int minutes = stoi(t.substr(0, colon));
int seconds = stoi(t.substr(colon + 1));
cout << minutes * 60 + seconds << '\n';
}
return 0;
}
245
750
bad
That output is for the input 3, then 4:05, 12:30 and 90, one per line.
In 4:05 the colon is at index 1. substr(0, colon) takes the 1 character before it, and substr(colon + 1) takes 05, which stoi reads as 5. For 90 there is no colon, so find returns string::npos and the program says bad instead of cutting at a position that does not exist.
David puts his shop's pages online. Each page title becomes a web address part: small letters, words joined by -, extra spaces dropped.
#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
string line;
getline(cin, line); // finish the line that held n
for (int i = 0; i < n; i++) {
getline(cin, line);
istringstream in(line);
string word;
string slug;
while (in >> word) {
if (!slug.empty()) {
slug += '-';
}
for (char c : word) {
slug += (char)tolower((unsigned char)c);
}
}
cout << slug << '\n';
}
return 0;
}
fresh-bread-today
tea-and-cake
That output is for the input 2, then Fresh Bread Today and Tea and CAKE.
in >> word skips every run of spaces, so the extra ones never reach slug. A dash goes in only when slug already holds a word, so none comes first. tolower returns an int, so the cast back to char keeps += adding a letter, not a number.
Where this is used
- The Unix
sedcommand.sed 's/cat/dog/g'replaces every match from left to right and goes on after each one, never searching what it put in. That is the rule ofreplace-word, and GNU sed turns the sample into the same line. - Python's number formatting.
format(1234567, ",")returns1,234,567, the output ofthousands-separator.format(-1000, ",")keeps the sign in front:-1,000. - The BMP image format. Its RLE8 compression stores a run of pixels as two bytes: how many there are, then the colour they share. That is
run-lengthwith a byte for the count instead of decimal digits. - CPython's integers. Python adds integers of any size. CPython keeps a big integer as an array of 30-bit digits. It adds two of them column by column with a carry, as
big-adddoes in base 10.
Common mistakes
1. Reading lines straight after cin >> n.
int n = 0;
cin >> n;
string line;
for (int i = 0; i < n; i++) {
getline(cin, line);
No message at any command line. The first getline reads the rest of the line that held n, which is empty. On reverse-words's sample, one run on Compiler Explorer printed an empty line, then fox brown quick the and cases edge tests Zara. The empty line is for the empty rest of the first line, and hello was never reached. Finish the line first with one getline(cin, line);.
2. Counting the minus sign as a digit.
string s = to_string(x);
int len = (int)s.size();
for (int j = 0; j < len; j++) {
if (j > 0 && (len - j) % 3 == 0) {
out += ',';
}
out += s[j];
}
No message at any command line, and 1000 and -1000 both come out right. For -123, one run on Compiler Explorer printed -,123, and for -123456 it printed -,123,456. The - made the length one bigger, so a comma landed right after it. Take the sign off first, add the commas to the digits, then put the sign back.
3. stoll on a number of 100000 digits.
cout << stoll(a) + stoll(b) << '\n';
It compiles without a word and passes the sample, 958 and 67. For a first number of twenty 9s, one run on Compiler Explorer stopped with this, on stderr: terminate called after throwing an instance of 'std::out_of_range', then what(): stoll. stoll throws when the text is too big for a long long. Add the digits yourself, one column at a time.
4. Searching again inside the piece you just put in.
size_t pos = text.find(from);
while (pos != string::npos) {
text.replace(pos, from.size(), to);
count++;
pos = text.find(from, pos + 1);
}
No message at any command line, and the sample with cat and dog passes. For banana with a and aa, every aa put in holds a new a at pos + 1, so the text grows forever. One run on Compiler Explorer printed nothing and was killed after about 6 seconds. Search again from pos + to.size(), or build a new string and search only the old one.
Zara wants the longest word in Bob's trip notes, and its length. A word is any run of characters without a space, so a comma stuck to a word is part of it.
Input. Words separated by spaces or line breaks, until the input ends. No count comes first.
Output. One line: the longest word, a space, and its length. On a tie, the first of the longest words.
Constraints. 1 to 100000 words, each 1 to 100 ASCII characters; the input is at most 1000000 bytes.
Sample. Input Bob packs maps, snacks and a camera for the trip gives snacks 6.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string word;
while (cin >> word) {
// Keep the longest word seen so far.
// Replace it only when this word is strictly longer.
}
// Print the longest word, a space, and its length.
return 0;
}
Run in Compiler
Hint 1
The sample has two words of 6 characters. What must happen when a word is exactly as long as the best so far?
Hint 2
Keep the best word in a string that starts empty. Replace it only when the new word's size is strictly greater. After the loop, print the best word, a space and its size.
Solution
The best word starts empty, with size 0, and every word has at least one character, so the first word always replaces it. Only a strictly longer word replaces it later, so the first of equal words stays. cin >> word skips any mix of spaces and line breaks. The input is ASCII, so size() is the length.
Replacing on >= keeps the last of a tie and prints camera 6 for the sample. The hidden tests hold a single word of one character and a single word of 100. Others hold equal words over many lines, the longest word last with no line break, and 100000 one-character words.
Alice needs every address on her club's sign-up list split in two: the user name before the @ and the domain after it.
Input. n, then n email addresses, one per line.
Output. For each address, one line: the part before the @, a space, and the part after it.
Constraints. 1 <= n <= 20000; each address has at most 100 ASCII characters, no spaces, exactly one @, and at least one character on each side of it.
Sample. Input 3, maria@school.example, bob.rahman@mail.example.com and z@x.io gives maria school.example, bob.rahman mail.example.com and z x.io on three lines.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
for (int i = 0; i < n; i++) {
string email;
cin >> email;
// Find the '@'. Print the part before it, a space,
// and the part after it, on one line.
}
return 0;
}
Run in Compiler
Hint 1
In z@x.io the @ is at index 1. How many characters come before it?
Hint 2
Find the index of the @. The user name is the substring from 0 with exactly that many characters. The domain is the substring that starts one past the @ and runs to the end.
Solution
find('@') gives the index of the @, and that index is also the number of characters before it. substr(pos, len) with pos 0 takes exactly those, and substr(pos) one past the @ takes the rest. Every address holds one @, so string::npos never comes back here. Without that promise, check for it first, as Example 2 does.
Starting the domain at the @ itself prints maria @school.example. Taking one character too few cuts the last letter off every user name. The hidden tests put the @ second and second to last, and use punctuation such as +, _ and ~. One holds 10000 addresses of 100 characters, just over 1 MB.
Amara's text editor needs find-and-replace. Replace every occurrence of from in the text with to, scanning left to right, and count the replacements. Never search inside a piece you have just put in, and resolve overlaps leftmost first: aaa with aa and b gives ba and 1.
Input. Line 1: the text, which may contain spaces. Line 2: from. Line 3: to.
Output. The new text on line 1, and the number of replacements on line 2.
Constraints. The text has 1 to 100000 ASCII characters; from and to each have 1 to 10 characters and no space.
Sample. Input I like cats. My cat likes catnip., cat and dog gives I like dogs. My dog likes dognip. and 3 on two lines.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string text, from, to;
getline(cin, text);
getline(cin, from);
getline(cin, to);
// Replace every occurrence of from in text, left to right.
// Never search inside a piece you have just put in.
// Print the new text, then the number of replacements, on two lines.
return 0;
}
Run in Compiler
Hint 1
Work out banana with a and aa on paper. After a replacement, where must the next search start?
Hint 2
Build a new string and search only the original text. From the current position, find the next match. Append the text before it and the new piece, count it, and move the position past the whole match. When the search finds nothing, append the rest.
David's account totals are hard to read. Print each number with a comma every three digits, counted from the right. A minus sign stays in front, as in -1,000, and 0 prints as 0.
Input. n, then n integers, one per line.
Output. Each number on its own line, with its commas.
Constraints. 1 <= n <= 20000, and each integer is between -1018 and 1018.
Sample. Input 5, 0, 999, 1000, -1234567 and 1000000000000000000 gives 0, 999, 1,000, -1,234,567 and 1,000,000,000,000,000,000 on five lines.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
for (int i = 0; i < n; i++) {
long long x = 0;
cin >> x;
// Turn x into text with to_string. Print it with a comma
// between every group of three digits, counted from the right.
// A minus sign stays in front, with no comma after it.
}
return 0;
}
Run in Compiler
Hint 1
What does to_string give for -1234567, and is its first character a digit?
Hint 2
Set the minus sign aside and keep only the digits. Walk them from the left. Before each digit but the first, add a comma when the digits from it to the end number a multiple of 3. Put the sign back in front.
Maria wants to know which letters a text uses. Count the letters a to z, with a capital counted as its small letter. Digits, spaces and punctuation are not letters.
Input. A text of one or more lines, until the input ends.
Output. For each letter that appears, from a to z, one line: the letter, a space, its count. If no letter appears, the word none.
Constraints. The text is at most 1000000 bytes of ASCII.
Sample. Input Hello, World! and Zara 2026 gives nine lines: a 2, d 1, e 1, h 1, l 3, o 2, r 2, w 1 and z 1.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<int> count(26, 0);
string line;
while (getline(cin, line)) {
// For every letter of the line, turn a capital into a small
// letter, then add 1 to count[letter - 'a'].
}
// For each letter from a to z that appears, print the letter,
// a space and its count. Print "none" if no letter appears.
return 0;
}
Run in Compiler
Hint 1
'a' - 'a' is 0 and 'z' - 'a' is 25. How far apart are 'A' and 'a'?
Hint 2
For each character, turn a capital into its small letter, then add 1 to the counter of a small letter. Afterwards walk the 26 counters in order, print the ones above 0, and remember whether you printed any.
Solution
ASCII keeps 'A' to 'Z' and 'a' to 'z' each in an unbroken run, 32 apart. So adding 'a' - 'A' turns a capital small, and c - 'a' is the counter's index. Walking the counters from 0 to 25 prints a to z with no sort. A flag set on the first print decides none.
Printing 'a' + k without the cast to char prints 97, because the sum is an int. A range check that is one off counts @, [, ` or {, the characters right beside the letters. The hidden tests hold exactly those, text with no letter at all, empty lines, 999000 copies of a, and a last line with no line break.
Kenji exported the class marks as CSV lines of the form name,mark1,mark2,mark3. A name can hold single spaces. Print the name with the best total, and the total.
Input. n, then n lines name,mark1,mark2,mark3.
Output. The best name on line 1 and its total on line 2. On a tie, the first of them.
Constraints. 1 <= n <= 20000. A name has 1 to 40 characters: letters, with single spaces inside, no comma and no space at either end. Each mark is from 0 to 100.
Sample. Input 4, Maria Rose,90,85,77, Bob,100,60,95, Zara Bell,88,95,72 and Kenji,70,70,70 gives Bob and 255 on two lines.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
string line;
getline(cin, line); // finish the line that held n
for (int i = 0; i < n; i++) {
getline(cin, line);
// Split the line at its commas: a name, then three marks.
// Keep the name with the highest total; the first one wins a tie.
}
// Print the best name on one line and its total on the next.
return 0;
}
Run in Compiler
Hint 1
The name Maria Rose holds a space. Where would >> stop reading it?
Hint 2
Put the line into an istringstream and read up to each comma with the three-argument getline: once for the name, three times for the marks. Turn each mark into a number. Keep the best total and its name, and replace them only on a strictly greater total.
David's chat app sends messages backwards. Print each line's words from the last to the first, with single spaces. A line can have extra spaces between words, and spaces at its start or end.
Input. n, then n lines, each with 1 to 1000 words of letters and digits separated by one or more spaces.
Output. Each line's words in reverse order, separated by single spaces.
Constraints. The whole input is at most 1000000 bytes.
Sample. Input 3, the quick brown fox, Zara tests edge cases and hello gives fox brown quick the, cases edge tests Zara and hello on three lines.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
string line;
getline(cin, line); // finish the line that held n
for (int i = 0; i < n; i++) {
getline(cin, line);
// Read the words of the line, then print them from the last
// to the first, separated by single spaces.
}
return 0;
}
Run in Compiler
Hint 1
How does >> treat three spaces in a row, or spaces at the start of the input?
Hint 2
Read the line's words with an istringstream into a vector<string>. Then print the vector from its last index down to 0, with a space between two words.
Zara keeps only the letters and digits of a line, in small letters, and asks whether that reads the same both ways. An empty result counts as a palindrome.
Input. n, then n lines.
Output. For each line, yes or no.
Constraints. Each line has 1 to 100000 printable ASCII characters, and the whole input is at most 1000000 bytes.
Sample. Input 5, A man, a plan, a canal: Panama, race a car, ?!, No 'x' in Nixon and 12321 gives yes, no, yes, yes and yes on five lines.
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0;
cin >> n;
string line;
getline(cin, line); // finish the line that held n
for (int i = 0; i < n; i++) {
getline(cin, line);
// Keep only the letters and digits, as small letters.
// Print "yes" if what is left reads the same both ways, else "no".
}
return 0;
}
Run in Compiler
Hint 1
What is left of ?! once only letters and digits stay? Does that read the same both ways?
Hint 2
Build a cleaned string from the letters and digits, each turned small. Then walk two indexes in from both ends, comparing, until they meet.
Kenji encodes a string of small letters: every maximal run of one letter becomes the letter followed by the run's length. So aaabccdddd becomes a3b1c2d4.
Input. One string of small letters.
Output. The encoded string on one line.
Constraints. The string has 1 to 500000 letters. The largest test, 500000 runs of length 1, runs out of time if you rebuild the answer with ans = ans + ...; it was measured on GCC 12.
Sample. Input aaabccdddd gives a3b1c2d4.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
// For each run of equal letters, add the letter and the length
// of the run to the answer. Print the answer on one line.
return 0;
}
Run in Compiler
Hint 1
Where does a run end? And how long is the answer when all 500000 runs have length 1?
Hint 2
From the start of a run, move a second index on while the letter stays the same. Append the letter and the run's length, as text, to the end of the answer. Jump to where the run ended, and print the answer once at the end.
Amara's calculator must add two non-negative integers far too big for a long long. Read them as strings and print the sum.
Input. Two lines, each with one non-negative integer.
Output. The sum on one line.
Constraints. Each number has 1 to 100000 digits, with no leading zeros except the number 0 itself.
Sample. Input 958 and 67 gives 1025.
#include <iostream>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string a, b;
cin >> a >> b;
// Add the two numbers digit by digit, from the right,
// carrying 1 whenever a column reaches 10. Print the sum.
return 0;
}
Run in Compiler
Hint 1
Where does the paper method start, and what happens when a column reaches 10? Try 999 plus 1.
Hint 2
Walk an index back from the last digit of each number. A column adds the two digits, 0 for a number that has run out, and the carry. Append its last digit to the result and keep its tens as the carry. Go on while a digit or a carry is left, then reverse the result once.
Common doubts
Why does find return string::npos and not -1?
findreturns asize_t, which cannot be negative. So the library gives the one value no real index can reach, the largestsize_t, and names itstring::npos. Compare with that name and the code works on every machine.The judge ignores spaces at the end of a line. Can I leave a space after every word?
At the end of the line, yes, the judge ignores it. Two spaces inside a line, or one at its start, are a different line, and the answer is wrong. Printing a space between two words, never before the first, is the habit that is always right.
Why does every input stay ASCII? Real text has Bangla in it.
With ASCII, one character is one byte, so
size(),s[i]andtolowerall mean what they seem to. A Bangla letter is 3 bytes in UTF-8, so the same code would count bytes, as lesson 01 showed. Counting real letters needs a library made for it, and that is beyond this set.Is ans = ans + piece always wrong?
No. Joining a few pieces once, as in
name = first + " " + last, is clear and cheap. The cost appears when the answer grows inside a loop, because every round copies everything built so far. In a loop, use+=.
Key takeaways
- Read words with
cin >>and lines withgetline; aftercin >> n, onegetlinefinishes that line. - Every input here is ASCII, so
size()counts characters ands[i]is one character. findreturns an index orstring::npos; keep it in asize_tand compare it withstring::npos.- Numbers up to 1018 fit a
long long; longer ones stay strings and are added one column at a time. - Build a growing answer with
+=:ans = ans + piecein a loop missed the second on the largest test every time. - Go deeper: CP and Interview Pack, string patterns and the bug gallery (Pro).
Next comes the cheat sheet, the whole of string on one page, and then the module test.
End of lesson 7
Get every problem accepted, and the lesson is done.
0 of 3 free problems accepted
Next: Cheat Sheet: string on One Page