Задача
В строке найти первое слово, которое встречается два раза подряд. Слова разделяются одним или несколькими пробелами. Напечатать его.
Пояснение к решению
Идея простая:
- последовательно разбиваем строку на отдельные слова с помощью функций стандартной библиотеки
- смотрим, не встретилось ли некоторое слово два раза подряд
Решение
Основной вариант:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <sstream> using namespace std; int main() { string str, a, b, tmp; getline(cin, str); stringstream ss(str); ss >> a; while (ss >> tmp) { if (a == tmp) { cout << a << endl; return 0; } a = tmp; } cout << "Нет повторов" << endl; return 0; } |
Перевод на Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.util.*; import java.lang.*; import java.io.*; class Ideone { public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); String s, t; boolean check = true; s = in.next(); while (in.hasNext()) { t = in.next(); if (s.equals(t)) { System.out.println(s); check = false; } s = t; } if (check) System.out.println("Нет повторов"); } } |
Старый неаккуратный и медленный вариант:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <vector> #include <string> #include <iostream> #include <sstream> using namespace std; int main() { string str, buf; getline(cin, str); vector<string> words; stringstream ss(str); while (ss >> buf) words.push_back(buf); if (words.size() > 1) for (auto it = words.begin(); it != words.end() - 1; it++) if (*it == *(it + 1)) cout << *it; } |
А если строка очень длинная?
Мы можем обойтись без разбиения на слова и хранения их всех — отслеживая пробелы и сравнивая подстроки, заключённые между ними.
Но мне приведённый вариант показался более эстетичным. К тому же он более универсальный — позволяет получить намного больше информации о строке, хотя, наверное, медленный на больших строках.
Действительно даже в строке вида «А А …» ваше решение будет продолжать парсить остальные миллиарды терабайт 🙂
Но оно не только медленное, но и требует удвоенной памяти. Его стоит оставить, но ниже добавить решение, оставляющее строку на месте.
Принято. Есть несколько вопросов:
— Как Вы думаете, как происходит присваивание a=tmp? Происходит излишнее здесь копирование содержимого одной строки в другую или простое переназначение указателей?
— Для чего предназначено бессмысленное (на мой взгляд) оценочное суждение «Идея простая»?