Разминка для мозгов: реверс строки
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Задача Написать код функции, которая выводит на экран строку-аргумент в обратном порядке. Шаблон программы прилагается. Запрещается использовать внешние библиотеки, кроме функций/объектов, необходимых для вывода на экран. Запрещается изменять шаблон программы: ваш код должен быть только там, где указано комментарием. Функция должна корректно отрабатывать случай пустой строки и случай нулевого указателя.
Постарайтесь написать наиболее эффективный код.
Публикуйте пожалуйста только свой вариант функции
reverse
.Вывод программы должен выглядеть так:
*) Для удобства отладки под Visual Studio в шаблон программы вставлены операторы условной компиляции: добавляется pause перед закрытием окна программы.
Как вариант
Могу предложить вот такой код:
P.S.: Череп, если нет оптимальных решений, то ты, пожалуйста, не выкладывай код, дай нам ещё немного подумать
Юрий, у тебя код строго подвязан к длине строки в 10 или 0 символов. Строка может быть произвольной длины. Реверс строки фиксированной длины — это даже не интересно )) Кроме того, у тебя вывод пустой строки явно лишний.
porshe, хорошо. Чуть-чуть теряешь время на доступе к элементу массива через индекс. И, чисто стилистическое замечание: не рекомендуется использовать односимвольные переменные, особенно, если их легко спутать с другим символом. Особенно этим грешит буква
l
, которая похожа и на цифру 1, и на буквуI
. Но это так, к слову.selevit, код рабочий. Можно немного ускорить за счёт более оптимального вычисления длины строки.
PS 1. На счёт «оптимального решения»: такового не существует ;) И существовать не может. А НЕоптимальное — может. Вот такой парадокс. Дело в том, что оптимальное решение может быть оптимальным или по объёму машинного кода, или по скорости выполнения (хорошо, конечно, когда и код компактный и выполняется быстро, но такое бывает крайне редко). И объём кода, и скорость выполнения при приближении к точке оптимума начинают зависеть от компилятора, операционки, архитектур компьютера и процессора. Поэтому ни я, ни кто-либо другой, абсолютный оптимум определить не сможет.
PS 2. И вообще, целью этого небольшого соревнования является разминка мозгов, поиск нестандартного (но работающего!) решения, попытка оптимизации очевидного решения. Отнеситесь к этому как к разгадыванию головоломки... и как к обмену опытом. Анализируйте и критикуйте чужой код.
Череп, а ещё будет? мне очень интересно. :) Или дай, пожалуйста ссылку на подобные задания.
Вот так, кстати работает оригинальный
strlen()
из glibc. Кошмар :)Я тоже поддерживаю porshe и хотел бы развития подобного рода «провокаций» :) Мне кажется такого рода общение подогревает интерес к изучению языка. Череп давай!!!
нуууу...или как-то так
лично у мну код работает
SuperUSer, да ваш код работает, но тут лишняя строчка
По условию там ничего не должно выводиться, а у вас выведется
""
, а это переведёт курсор на новую строку.Я бы переделал ваш код так:
porshe, код
не переведёт курсор на новую строку: здесь нет вывода символа новой строки
"\n"
илиendl
. Но действительно этот кусок явно лишний.superUSer, гораздо хуже, что код выводит лишний символ: концевой
'\0'
. Должно быть так:Ещё несколько вариантов функции реверса строки.
Вариант 1.
Очень похож на вариант, предложенный selevit. Но длина строки вычисляется эффективнее. Последний цикл (собственно вывод), на уровне машинного кода, практически идентичен.
Вариант 2.
Примерно на ту же тему, что и предыдущий вариант, но без вычисления длины строки.
Вариант 3.
Этот вариант [видимо] не столь эффективен и имеет существенное ограничение на длину строки (понятно почему?). Но показателен, как демонстрация совершенно другого подхода к решению задачи.
Кстати, этот вариант, как алгоритм, имеет может быть и наиболее эффективным, но для другого языка. В этом варианте кода не изменяется ни одна переменная и нет ни одного присваивания.
По поводу оригинального strlen() из glibc.
На сколько я понял, здесь сначала выводят указатель на границу длинного целого (
unsigned long int
), а потом ищут длинное целое, в котором имеется нулевой байт. Когда такое длинное целое найдено, уже по нему находят адрес занулённого байта и по разности адресов начала строки и занулённого байта вычисляют длину строки. Побайтовое чтение происходит только на первом этапе, при выходе на границу длинного целого, и на последнем этапе, при анализе длинного целого с занулённым байтом.Ориентировано скорее на достаточно длинные строки.
Смысл — минимизировать операции обращения к памяти. Считывание из памяти идёт не побайтно, а сразу по 4 или по 8 байтов (в зависимости от архитектуры). Далее, скорее всего, для анализа будут использованы регистры процессора, что очень быстро.
Ссылок на подобные задания не дам, поскольку не знаю таковых. Ищите, наверное есть такие ресурсы. Гугл вам в помощь.
Есть ресурсы, посвящённые олимпиадному программированию. Как правило, на этих ресурсах есть архив задач и система автоматизированной проверки выполненных заданий. Но там основной упор делается всё-таки на логическое решение задачи, а не на технику кодинга. Впрочем тоже интересно.
Ссылки можно посмотреть здесь.
Могу порекомендовать набор задач для начинающих на сайте Timus Online Judge. На русском. Я попробовал — всё прекрасно работает.
Cranium, I seen that you have athorized and changed your nickname. I couldn't understand at once what a new person at the blog with new nick. What a wind of change? :)
Юрий, система авторизации сайта code-live.ru к сожалению не поддерживает ники на кириллице. Пришлось переводить свой ник на латынь. Череп -> Cranium.
Так ты теперь под каким ником будешь на форуме?
Если логиниться будет влом, то под русским ))
Статьи или большие посты — точно под латинским — тут оказывается редактировать сообщения можно.