Skip to content

Instantly share code, notes, and snippets.

@alzobnin
Last active January 28, 2021 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alzobnin/fc4ff58206af3efa244387e732c74870 to your computer and use it in GitHub Desktop.
Save alzobnin/fc4ff58206af3efa244387e732c74870 to your computer and use it in GitHub Desktop.

Разбор задачи "Утилита paste"

Условие

Вам необходимо реализовать упрощенный аналог консольной утилиты paste. В Linux эта утилита принимает на вход несколько файлов и выписывает очередные строки этих файлов, склеенные через знак табуляции. В этой задаче отдельных входных файлов не будет: вместо этого данные будут просто последовательно подаваться на вход программы.

В первой строке указано неотрицательное целое m — количество "файлов". Далее идёт m блоков данных. В начале каждого блока сначала указано неотрицательное целое число n_i — количество строк очередного "файла". Затем идут сами строки, состоящие из латинских букв, цифр и знаков пунктуации, но не содержащие пробельных разделителей (то есть, вы можете их читать просто через std::cin >> word). Гарантируется, что строки непусты. Количество файлов, количество строк в каждом файле и количество символов в каждой строке не превосходит 100.

Выведите сначала первые строки всех файлов (склеив их через табуляцию), затем вторые строки и т. д. В конце каждой строки должен быть напечатан символ перевода строки. Если в каком-то из файлов строки закончатся раньше, не выводите в соответствующем поле ничего (но символ табуляции перед таким полем, если оно не первое, всё равно должен быть).

Решение

Для тех, кто не знает, что такое символ табуляции: читайте статью в Википедии. Важно понимать, что табуляция не тождественна нескольким пробелам.

В задаче важно печатать табуляцию только между полями. Частая ошибка - печать табуляции в конце каждой строки. Визуально это неотличимо от примера вывода, но если выделить текст (или посмотреть на его байты в каком-нибудь редакторе), то табуляцию можно увидеть.

Считаем сначала все строки файлов в вектор векторов строк. Затем аккуратно пройдёмся по элементам этого вектора и склеим строки:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

int main() {
    size_t files_count;
    std::cin >> files_count;
    std::vector<std::vector<std::string>> files(files_count);

    size_t max_lines_count = 0;
    for (size_t i = 0; i != files.size(); ++i) {
        size_t lines_count;
        std::cin >> lines_count;
        max_lines_count = std::max(max_lines_count, lines_count);
        files[i].resize(lines_count);
        for (size_t j = 0; j != lines_count; ++j) {
            std::cin >> files[i][j];
        }
    }

    for (size_t j = 0; j != lines_count; ++j) {
        for (size_t i = 0; i != files.size(); ++i) {
            if (i > 0) {
                std::cout << '\t';
            }
            if (j < files[i].size()) {
                std::cout << files[i][j];
            }
        }
        std::cout << '\n';
    }
}

Здесь мы используем индекс i для номера файла, а индекс j - для номера строки в файле. Фактически нам надо "транспонировать" двумерный вектор, поэтому при выводе порядок циклов меняется местами.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment