Другой от Дельфи, который я думаю, немного более строг, чем другой отправленный пример Дельфи. Это может легко превратиться в играющее в гольф соответствие, но я попытался сделать мой читаемым.
Edit0: Мне было любопытно на предмет рабочих характеристик, таким образом, я действительно немного тестировал. На моей машине я выполнил эту функцию против 60 символьных строк 50 миллионов раз, и потребовалось 5 секунд.
function TForm1.IsPalindrome(txt: string): boolean;
var
i, halfway, len : integer;
begin
Result := True;
len := Length(txt);
{
special cases:
an empty string is *never* a palindrome
a 1-character string is *always* a palindrome
}
case len of
0 : Result := False;
1 : Result := True;
else begin
halfway := Round((len/2) - (1/2)); //if odd, round down to get 1/2way pt
//scan half of our string, make sure it is mirrored on the other half
for i := 1 to halfway do begin
if txt[i] <> txt[len-(i-1)] then begin
Result := False;
Break;
end; //if we found a non-mirrored character
end; //for 1st half of string
end; //else not a special case
end; //case
end;
И вот то же самое в C#, за исключением того, что я оставил его с несколькими точками выхода, которые я не люблю.
private bool IsPalindrome(string txt) {
int len = txt.Length;
/*
Special cases:
An empty string is *never* a palindrome
A 1-character string is *always* a palindrome
*/
switch (len) {
case 0: return false;
case 1: return true;
} //switch
int halfway = (len / 2);
//scan half of our string, make sure it is mirrored on the other half
for (int i = 0; i < halfway; ++i) {
if (txt.Substring(i,1) != txt.Substring(len - i - 1,1)) {
return false;
} //if
} //for
return true;
}
Это действительно довольно элегантно.
Сначала мы определяем функцию sieve
, которая принимает список элементов:
sieve (p:xs) =
В теле sieve
, мы берем заголовок списка (потому что мы передаем бесконечный список [2 ..]
, а 2 определяется как простое число) и добавляем его (лениво!) К результату применение sieve
к остальной части списка:
p : sieve (filter (\ x -> x 'mod' p /= 0) xs)
Итак, давайте посмотрим на код, который выполняет работу с остальной частью списка:
sieve (filter (\ x -> x 'mod' p /= 0) xs)
Мы применяем sieve
к отфильтрованный список. Давайте разберемся, что делает фильтрующая часть:
filter (\ x -> x 'mod' p /= 0) xs
filter
принимает функцию и список, к которому мы применяем эту функцию, и сохраняет элементы, которые соответствуют критериям, заданным функцией. В этом случае фильтр
выполняет анонимную функцию:
\ x -> x 'mod' p /= 0
Эта анонимная функция принимает один аргумент, x
. Он проверяет модуль из x
против p
(заголовок списка, каждый раз, когда вызывается сито
):
x 'mod' p
Если модуль не равен 0:
x 'mod' p /= 0
Тогда элемент x
сохраняется в списке. Если он равен 0, он отфильтровывается. В этом есть смысл: если x
делится на p
, то x
делится более чем на 1 и само себя, и поэтому не является простым.
x 'mod' p /= 0
Затем элемент x
сохраняется в списке. Если он равен 0, он отфильтровывается. В этом есть смысл: если x
делится на p
, то x
делится более чем на 1 и само себя, и поэтому не является простым.
x 'mod' p /= 0
Затем элемент x
сохраняется в списке. Если он равен 0, он отфильтровывается. В этом есть смысл: если x
делится на p
, то x
делится более чем на 1 и саму себя, и, следовательно, не является простым.
Он реализует Решето Эратосфена
По сути, начните с простого (2) и отфильтруйте все остальные целые числа, кратные двум. Следующее число в этом отфильтрованном списке также должно быть простым, поэтому отфильтровать все его кратные из оставшихся и т. Д.
В нем говорится, что «решето некоторого списка является первым элементом списка (который мы назовем p) и решето остальной части списка, отфильтрованное таким образом, что через "разрешены только элементы, не делящиеся на p". Затем он начинает работу, возвращая решето всех целых чисел от 2 до бесконечности (которое представляет собой 2, за которым следует решето всех целых чисел, не делящихся на 2, и т. Д.).
Я рекомендую The Little Schemer , прежде чем атаковать Haskell.
Вопреки тому, что здесь утверждали другие, эта функция не реализует истинное решето Эратосфена . Тем не менее, он возвращает начальную последовательность простых чисел аналогичным образом, так что можно думать об этом как о сите Эратосфена.
Я почти закончил объяснение кода, когда mipadi опубликовал его ответ; Я мог бы удалить его, но, поскольку я потратил на это некоторое время и наши ответы не полностью идентичны, я оставлю его здесь.
Прежде всего, обратите внимание, что в опубликованном вами коде есть некоторые синтаксические ошибки. Правильный код:
let sieve (p:xs) = p : sieve (filter (\x -> x `mod` p /= 0) xs) in sieve [2..]
let x in y
определяет x
и позволяет использовать его определение в y
. Результатом этого выражения является результат y
.
сито
, которая принимает список в качестве своего первого аргумента. (p: xs)
- это шаблон , который соответствует p
с головой указанного списка и xs
с хвостом (все, кроме головы). p: xs
- это список, первым элементом которого является стр
. xs
- это список, содержащий оставшиеся элементы. Таким образом, sieve
возвращает первый элемент списка, который он получает. Не смотрите на оставшуюся часть списка:
sieve (filter (\ x -> x `mod` p / = 0 ) хз)
сито
вызывается рекурсивно. Таким образом, выражение filter
вернет список. filter
принимает функцию фильтра и список. Он возвращает только те элементы в списке, для которых функция фильтрации возвращает истину. В этом случае xs
- это фильтруемый список, а
(\ x -> x `mod` p / = 0)
- это функция фильтрации.
x
и возвращает истину, если и только если он не кратен p
. Теперь, когда решето
, мы передаем ему [2 ..]
, список всех натуральных чисел, начиная с 2. Таким образом,