Zajímavé úlohy pro programátory v C a C++ #4

Od Petr Zemek, 2009-01-25

Zkouškové skončilo a já tak mohu v klidu přinést další zajímavou úlohu. Tentokrát budeme programovat pouze v C++ a cílem bude vytvořit program, který bude provádět zadanou činnost a použít při tom co nejmenší počet příkazů.

Zadání

Doplňte do následujícího kódu příkazy tak, aby daný program po přeložení a spuštění četl slova (složená z položek typu char, uvažujte pouze ASCII znaky) oddělená bílými znaky ze standardního vstupu až do konce vstupu a všechna je vytisknul seřazená od "nejmenšího" po "největší" (operátorem porovnání dvou stringů je , čili lexikografické uspořádání), každé slovo na jednom řádku. Cílem je, aby výsledný program (zdrojový kód, přesněji tělo funkce main()) obsahoval co nejmenší počet příkazů, takže pokud už někdo přijde s řešením, můžete klidně zkusit jeho program zkrátit o jeden příkaz atd. :).

// Zde doplňte hlavičkové soubory
 
// Zde doplňte případné deklarace/direktivy using pro zčitelnění kódu
 
int main() {
    // Zde doplňte tělo programu
}

Ukázkový výstup

$ ./program <<< "beta alfa gamma delta"
alfa
beta
delta
gamma

Omezení

Nesmíte používat ternární operátor a operátory čárka, &&, ||, and, or. Kromě hlavičkových souborů (pouze ze standardní C++ knihovny/STL) a případných deklarací/direktiv using pro zčitelnění kódu nedoplňujte žádný kód mimo tělo funkce main(). Řešení musí být implementačně nezávislé (tj nepoužívejte konstrukty s nespecifikovaným či nedefinovaným chováním) a přeložitelné podle standardu C++98.

Řešení

Zadanou úlohu lze vyřešit programem, jehož tělo funkce main() obsahuje 2 příkazy.

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <set>
 
using namespace std;
 
int main() {
    multiset<string> words((istream_iterator<string>(cin)), istream_iterator<string>());
    copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
}

Je použit kontejner multiset, protože na vstupu se může vyskytovat několikrát stejné slovo a také proto, že automaticky řadí vstupní data (defaulně pomocí binárního predikátu less>, což nám vyhovuje). Je využit konstruktor, který čte data z rozsahu 2 iterátorů. No, a druhý příkaz je standardní způsob výpisu obsahu kontejneru na výstup.

Poznámka pro ty, kteří se podivují nad zdánlivě nadbytečnými závorkami v prvním příkazu. Zkuste si je odstranit - program se pak nepřeloží, protože první příkaz nebude vytvářet objekt, ale deklarovat funkci... C++ je holt roztodivný jazyk :). Zájemce poprosím, aby si přečetli pátý komentář ("You are the victim of..".) z tohoto threadu, který popisuje, v čem je přesně problém.

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
12 + 8 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.

Petr Zemek

15 years 9 months zpět

Nikoho nenapada zadne reseni tohoto ukolu? To se mi nechce verit :).

Libor (neověřeno)

15 years 9 months zpět

#include <string>
#include <iostream>
#include <set>
 
typedef std::multiset<std::string> container;
 
int main() {
	container words;
	std::string current;
	while (std::cin >> current) {
		words.insert(current);
	}
 
	for (container::iterator it = words.begin(); it != words.end(); ++it) {
		std::cout << *it << std::endl;
	}
}

#include <string>
#include <iostream>
#include <iterator>
#include <set>
 
typedef std::multiset<std::string> container;
 
int main() {
        container words;
        std::string current;
        while (std::cin >> current) {
                words.insert(current);
        }
 
        copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout,"\n"));
}

Libor (neověřeno)

15 years 9 months zpět

#include <string>
#include <iostream>
#include <set>
#include <iterator>
 
typedef std::multiset<std::string> container;
 
int main() {
	container words;
	copy(std::istream_iterator<std::string>(std::cin),
			std::istream_iterator<std::string>(),
			std::inserter(words, words.begin()));
	copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout,"\n"));
}

Petr Zemek

15 years 9 months zpět

In reply to by Libor (neověřeno)

Sikovna uprava - pocet prikazu: 3.

Podari se to nekomu jeste prekonat? :)