Создание обратного вывода с использованием вектора, STL - PullRequest
0 голосов
/ 21 апреля 2020

Я читаю данные из текстового файла с именем test.txt. Содержимое файла:

C ++ беспокоит меня каждый день

, и я хочу получить результат, подобный

  1. ++ C si gnibrutsid yreve yad (перевернутые слова)

  2. это я C ++ день каждое беспокойство (отсортировано по длине)

Как я могу это сделать ? Вот что я попробовал:

#include <fstream>
#include <iostream>
#include <vector>
using namesapce std;

string file { "test.txt" }

int main()

{
  ifstream in(file);

  vector<char> v{istreambuc_iterator<char>(in), istreambuf_iterator < char()};

  /* my horrible coding
  int n{ 0 };
      for (auto i = v.cbegin(); i < v.cend(); ++i)
      {
              int tmp=0;
              if (*i == ' ')
              {
                      v[n] = tmp;
                      v[n] = *i;
                      tmp = *i;
              }n++;

      }
  --------------------*/
  for (auto c : v) cout << c;
}

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Читайте каждое слово индивидуально, а затем выполняйте любую необходимую обработку:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>

void printReversedWords(std::vector<std::string> const& vec) noexcept {
        for (auto const& str : vec) {
                std::copy(str.crbegin(), str.crend(),
                        std::ostream_iterator<char>(std::cout));
                std::cout << ' ';
        }
        std::cout << '\n';
}

// remove noexcept if you care catching bad_alloc
void printSortedVec(std::vector<std::string> const& vec) noexcept {
        auto const vec_view = [&vec] {
                std::vector<std::string const*> vec_view;
                vec_view.reserve(vec.size());

                std::transform(vec.cbegin(), vec.cend(), std::back_inserter(vec_view),
                        [](auto const& str) { return &str; });

                std::sort(vec_view.begin(), vec_view.end(),
                        [](auto const* const pstr1, auto const* const pstr2) {
                                return pstr1->size() < pstr2->size();
                        });
                return vec_view;
        }(); // IILE


        for (auto const* const pstr : vec_view) std::cout << *pstr << ' ';

        std::cout << '\n';
}

int main() {
        auto constexpr fileName = "./test.txt";
        std::ifstream in(fileName);

        if (!in) {
                std::cerr << "Failed to open the file";
                return -1;
        }

        std::vector<std::string> const vec{ std::istream_iterator<std::string>(in), {} };
        printReversedWords(vec);
        printSortedVec(vec);
}
0 голосов
/ 21 апреля 2020

Вы можете использовать встроенные в C ++ алгоритмы.

Сначала посмотрите пример кода, который может дать вам, и идею о том, как его можно реализовать:

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

const std::string fileName{ "test.txt" };

int main() {

    // Open the file and check, if it could be opened.
    if (std::ifstream inStream(fileName); inStream) {

        // Read all words from the file into our vector
        std::vector words(std::istream_iterator<std::string>(inStream), {});

        std::cout << "\nReversed words:\n\n";
        // Show reversed words
        std::transform(words.begin(), words.end(),  std::ostream_iterator<std::string>(std::cout, " "), 
            [](const std::string& s) { return std::string(s.rbegin(), s.rend()); });

        // Sort
        std::sort(words.begin(), words.end());

        // Show sorted list of words
        std::cout << "\n\n\nSorted list of words:\n\n";
        std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, " "));
        std::cout << "\n\n";
    }
    else {
        std::cerr << "\n*** Error: Could not open file: " << fileName << "\n\n";
    }
    return 0;
}

Сначала мы откроем файл и проверьте, если открытие прошло успешно. Это мы делаем с , если с оператором init . Таким образом, мы предотвращаем загрязнение внешнего пространства имен. Потоковая переменная просто используется в if -статменте. И используя часть инициализации if, мы откроем файл. Часть условия if -статента - это просто переменная потока. И это будет работать, потому что оператор bool потока ios :: перегружен и вернется, если поток файла в порядке или нет.

OK, теперь файл открыть, и мы хотим прочитать все слова. Итак, мы определяем std::vector с именем «слова». Нет необходимости определять параметр шаблона для std::vector. С C ++ 17 CTAD (Вывод аргумента шаблона класса), потому что он будет выведен автоматически.

Мы используем конструктор диапазона std :: vector (здесь число 5) . Итератор begin - это std :: istream_iterator . Он будет вызывать оператор извлечения >>, пока не будет использован весь ввод. Пожалуйста, обратите внимание. Нам не нужно явно упоминать итератор end, поскольку {} будет использоваться в качестве инициализатора по умолчанию. Смотрите здесь: конструктор номер 1 .

Итак, определяя переменную и используя ее конструктор диапазона, мы будем читать все слова из файла.

Для обращения вспять словами, мы также будем использовать конструктор диапазона std::sting. И в качестве итераторов begin и end мы используем реверсированные версии. Итак, очень просто.

И чтобы показать перевернутые строки, мы будем использовать std::transform, go над всеми словами, поместив его в std::ostream_operator. Это вызовет оператор вставки << для всех слов. А функция преобразования - это лямбда, которая возвращает обратную строку. </p>

Сортировка тривиальна, а копирование отсортированных слов в std::cout довольно просто.

Все это приводит к элегантности и современности. Код C ++, всего несколько строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...