Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Олимпиадная задача с повышенной сложностью

#cpp


Салют всем чайникам и гуру, девелоперам и фрилансерам, прогерам и кодерам! Но речь
не о классификации и иерархии нашего брата. Речь о олимпиадной задачи, которую я уже
неделю не могу решить. Я точно знаю: решение что-то простое и гениальное - но вот под
каким камнем оно спряталось? Так что, суровые хэшкод-юзеры, прошу у вас помощь в решение
этой задачи!
Задача:
Язык программирования: С++.
В программе должна быть 1 единственная функция вывода информации, которая может только
писать, т.е. не может удалять текст, а только вставлять новый. При этом она работает
следующий образом
Исполняемый код:
func( "1" );


Вывод:
(1)
[1]


Исполняемый код:
func( "1" );
func( "2" );


Вывод
(1)
(2)
[2]
[1]


Испоняемый код:
func( "1" );
func( "2" );
func( "qwer" );


Вывод
(1)
(2)
(qwer)
[qwer]
[2]
[1]


Я уверен, что задача решается легко, но у меня нет других вариантов, кроме как все
же буферизовать хвост, изменять его, и заменять старый хвост на новый. Но тогда приходится
использовать удаление символов.
P.S. задача не совсем олимпиадная, эта задачка была давно в какой-то мощной статье
по альтернативному программирование где рассматривалось несколько примеров, но вот
код реализации такой задачи не помню. И статью ту тоже не могу найти. У самого без
удаление символов написать не получается.    


Ответы

Ответ 1



Испоняемый код: func( "1" ); func( "2" ); func( "qwer" ); Вывод (1) (2) (qwer) [qwer] [2] [1] то есть нужно напечатать в обычном и обратном порядке ???? как я понял можно только вызывать одну и ту же функцию... (если да то решение ниже) делаем класс func и в нём храним std::vector делаем конструктор func(string) с записью дубля в вектор и выводом на экран в деструкторе выводим вектор в обратном порядке UPD:: ну ещё будет "красиво" перегрузить "operator()" дабы не портить конструкторы

Ответ 2



Ещё один вариант, без глобального списка, но с макросами: #include class StringPrinter { const char* content; public: StringPrinter(const char* s) : content(s) { std::cout << '(' << content << ')' << std::endl; } ~StringPrinter() { std::cout << '[' << content << ']' << std::endl; } }; #define func(S) StringPrinter PASTE1(stringPrinterInstance, __LINE__) (S) #define PASTE1(T1, T2) PASTE2(T1, T2) #define PASTE2(T1, T2) T1 ## T2 int main() { func("1"); func("2"); func("3"); func("whatever"); }

Ответ 3



Внесу свои 5 копеек на Си. Правда не уверен, что формально этот код отвечает условиям задачи (это я насчет одной функции в программе). По сути же, изображено тоже самое, что ранее показано с классом и его деструктором в С++. Из main() вызывается только одна функция и никаких "левых" параметров ей не передается. #include #include #include struct list { struct list *next; char *text; }; static struct list *list = 0; static void rfunc() { struct list *p = list; while (p) { printf ("[%s]\n",p->text); p = p->next; } } func (char *s) { printf ("(%s)\n",s); if (!list) atexit(rfunc); struct list *p = malloc(sizeof(*p)); p->next = list; p->text = s ? strdup(s) : NULL; list = p; } int main (int ac, char *av[]) { while (ac--) func(av[ac]); } Ничто не упрятано, так сказать, все секреты наружу.

Ответ 4



Очевидно же. Создаем в функции статический объект, который накапливает строки. По завершении работы программы объект разрушается, и в его деструкторе можно вывести строки в нужном порядке: #include #include #include class Collector { public: void push(const std::string& s) { data_.push_back(s); } ~Collector() { for (const auto& s: data_) { std::cout << "(" << s << ")" << std::endl; } std::reverse(data_.begin(), data_.end()); for (const auto& s: data_) { std::cout << "[" << s << "]" << std::endl; } } private: std::vector data_; }; void func(const std::string& s) { static Collector collector; collector.push(s); } int main() { func("1"); func("2"); func("qwer"); } http://ideone.com/njet2N

Комментариев нет:

Отправить комментарий