Предполагается, что при выполнении задания вы должны идти вперед и назад по рельсам, но вы просто идете в одном направлении, а затем возвращаетесь к началу, используя i % numRails
.
Нет необходимости использовать словарь для рельсов. Просто используйте список, проиндексированный по номеру рельса.
def Encrypt(numRails, plainText):
rails = [""] * numRails
rail = 0
direction = 1
for c in plainText:
rails[rail] += c
rail += direction
# check if we need to change directions
if direction == 1 and rail >= numRails:
direction = -1
rail = numRails - 2
elif direction == -1 and rail < 0:
direction = 1
rail = 1
cipherText = "".join(rails)
print (cipherText)
return cipherText
Это дает тот же результат, что и страница Википедии .
Using boost::bind with std::for_each solves this problem in a clean way. Or you can use BOOST_FOREACH.
Example of std::for_each:
std::for_each(v.begin(), v.end(), boost::bind(&C::f, _1, param));
Example of BOOST_FOREACH:
std::list<int> list_int( /*...*/ );
BOOST_FOREACH( int i, list_int )
{
// do something with i
}
Используйте его как любой другой языковой инструмент. Когда это облегчит вашу жизнь, используйте его. Когда это становится громоздким, делай что-то еще. Это не так, как если бы требования изменились. Действительно сложно реорганизовать цикл так или иначе.
Хотя и может пойти противоположным путем. Предположим, вы начинаете с операции, которая занимает всего пару строк. Вы не хотите беспокоиться о создании функции, которая будет вызываться только один раз, просто чтобы сжать цикл, поэтому вы пишете что-то вроде:
for ()
{
// do
// some
// stuff
}
Тогда, когда операция, которую вам нужно выполнить, становится более сложной, вы понимаете, что ее выполнение в отдельная функция имеет смысл, поэтому вы в конечном итоге получаете
for ()
do_alot_more_stuff();
, а затем модифицируете ее так, чтобы она была похожа на ваш оригинальный метод, имеет смысл сжимать ее дальше:
std::for_each(begin, end, do_alot_more_stuff);
В конце концов, насколько сложно действительно изменить for_each на for петля или наоборот? Не мучайте себя мелкими деталями!
Подобно вашей проблеме, я часто замечаю, что шаблон / идиома "функтор" в C ++ на самом деле довольно громоздкий. Вот почему я с нетерпением жду лямбда-функций в C ++ 0X. Некоторое из этого возможно теперь с boost :: lambda.
У меня была такая же проблема со многими вещами в Алгоритме. У него есть неприятная тенденция заканчивать тем, что он становится более кодом, который просто использует старомодный цикл for.
Я не могу на самом деле оправдать уход и создание какого-то специального класса функторов (который является умеренно продвинутой темой в C ++, который многие из моих сопровождающих не до конца понимают) с надлежащим конструктором и деструктором и, возможно, некоторыми аксессорами, просто чтобы избежать одной строки для цикла.
Возможно, вы сначала использовали for_each вместо transform ...
Я никогда не использую std :: for_each (или очень редко).
Я бы посоветовал пока использовать Boost.Foreach и классические конструкции «для». А когда выйдет C ++ 0x, вы можете рассмотреть возможность использования новой конструкции «for», более удобочитаемой для итерации по контейнерам.
Также подумайте о параллелизме, с функцией вы можете определить, что изменится, и указать, может ли диапазон элементов вместо этого быть выполняется параллельно, а не по одному от начала до конца.
Или вы можете подождать C ++ 0x и использовать для (elem & e, container) {e.something ();}
Совершенно так же, как BOOST_FOREACH ()
,