Это Вы вначале попробуйте пройти от 1.0 до 2.0 с шагом 0.1. Я уверен - результат Вас неприятно удивит
Это - скрытая ошибка
Не удивит: я давно (лет так 45 примерно) знаком с фокусами неточного представления чисел в ЭВМ. Поскольку начинал работать с техникой, где даже ассемблера еще не было - только восьмеричные коды. Если у меня шаг нецелый, то пусть в меня сколько угодно кидают камни, но я поступаю так:
begin
var (x,h):=(1.0,0.1);
while x<=2+h/2 do begin
Print(x);
x+=h
end
end.
Но реплика об очень непристойном слове для случая целочисленных параметров цикла все равно остается…
Ну ладно, есть же
begin
foreach var x in Range(1,10,2) do
Print(x)
end.
И вообще для генерации последовательностей есть
begin
var (a,h) := (1.0,0.1);
foreach var x in SeqGen(10,a,x->x+h) do
Print(x)
end.
Я выкрутился, конечно, но все же…
var s:=Range(0,r)+Range(p,n-1);
foreach var k in s do
foreach var j in s do
a[k,j]:=a[k,j]-b[j]*c[k];
Ну подождите, почему же выкрутились? По-моему, очень элегантно: в памяти последовательности не хранятся. И - тут нет шага, есть скачок
Выкрутился - потому что моделировал алголовские циклы (см. выше), а прямой замены нет, за что Н.Вирту “спасибо”. С другой стороны, нельзя в очередной раз не сказать настоящее спасибо разработчикам за прекрасные возможности, заложенные в эту версию языка.
В регулярных выражениях PCRE есть квантификатор {n,} (>=n повторений) и {,n} (<=n) С удивлением обнаружил, что PABC.NET не поддерживает второй
begin
var s := '123';
println(RegEx.isMatch('123', '\d{3,}')); //true
println(RegEx.isMatch('123', '\d{,3}')); //false
end.
Спасибо, давно искал))
А Вы проверили - библиотеки .NET его вообще поддерживают? Microsoft дает полное описание того, что поддерживается и в каком формате.
@admin Ошибки с примером в справке по индексированному слову where (поиск минимального эл-та в массиве):
- использована несуществующая переменная
max
; - перепутан знак сравнения в операторе
if
, т.е. в текущем виде ф-ция будет искать максимальный элемент.
Кстати, кто-нибудь может мне объяснить, почему условие в виде if Result.CompareTo(a[i]) > 0
всегда возвращает true
(и, соответственно, результатом функции будет просто последний элемент массива, а не ожидаемый минимальный), а если записать его в инверсии: if a[i].CompareTo(Result) < 0
, то все работает как положено?
function MinElem<T>(a: array of T): T;
where T: IComparable<T>;
begin
Result := a[0];
for var i := 1 to a.Length - 1 do
if Result.CompareTo(a[i]) > 0 then
Result := a[i];
end;
@admin В PABCSystem, строки 9152 и 9165 – опечатка в описании функций LastIndexMax:
- /// Возвращает индекс последнего минимального элемента
- /// Возвращает индекс последнего минимального элемента начиная с позиции start
+
во многих случаях пропущены запятые перед словом если в описаниях
@admin На мой взгляд функции LastIndexMin
и LastIndexMax
в вариантах с дополнительным параметром start
вообще сейчас реализованы некорректно – они производят поиск в первой половине массива, т.е. от начала и до позиции start
, а не с позиции start
и до конца, как ожидается из их описания. Ну, или тогда замените имя start
на finishAt
, например.
Ну почему же.
function LastIndexMin<T>(Self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[start];
Result := start;
for var i:=start-1 downto 0 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
min := Self[i];
end;
end;
От позиции start до начала. То есть, мы стартуем с конца. По-моему, всё верно
Ну не знаю, Станислав Станиславович, может Вы, конечно, выросли на Ближнем Востоке ;), но для большинства людей естественный и ожидаемый порядок обработки последовательных данных – по нарастающей слева-направо / сверху-вниз, то есть в данном случае от нулевого элемента массива (или любого другого произвольного = start) и до последнего. Проход в обратном порядке – это всего лишь внутренняя особенность реализации конкретной функции, которая обычному пользователю не видна.
Давайте рассуждать так: с точки зрения пользователя есть одна функция LastIndexMax
c необязательным параметром start
на тот случай, если он захочет начать обработку не с 0-го элемента, а с любого другого. Если он опустит этот параметр (т.е. логически для него начнет с нуля), обработается весь массив. Но если он явно напишет a.LastIndexMax(0)
– также начать с нуля, то будет обработан только нулевой элемент и результат всегда будет = 0. Когнитивный диссонанс обеспечен!
Я указываю только на очевидное, на мой взгляд, противоречие между описанием/заголовком ф-ции (и соотв. ожидаемым результатом) и фактическим результатом. Разумеется, имеет право на существование и текущая реализация, если в ней больше практическго смысла, но в таком случае описание нужно скорректировать, например, так:
/// Возвращает индекс последнего максимального элемента, начиная с позиции 0 вплоть до позиции stopAt
function LastIndexMax<T>(Self: array of T; stopAt: integer): integer; extensionmethod;
Интересно, что думают на этот счет другие коллеги?
Вот код из .NET:
begin
var l := Lst(5,5,2,2,5,4,5,6,5,7,5,7);
Print(l.LastIndexOf(5,3));
end.
Он находит последнюю пятерку начиная с индекса 3.
Та же идея.
Максимум что я могу для Вас сделать - это назвать имя параметра не start, а index
Как я и говорил, такой подход вполне допустим, если он соответствует описанию функции. В данном случае – полностью соответствует. Обратите внимание на разницу:
/// Осуществляет поиск указанного объекта и возвращает отсчитываемый от нуля индекс последнего вхождения в диапазоне элементов списка System.Collections.Generic.List'1,
начиная с первого элемента и до позиции с заданным индексом.
'/// Возвращаемое значение: Отсчитываемый от нуля индекс последнего вхождения элемента
function LastIndexOf(item: T; index: integer): integer;
/// Возвращает индекс последнего минимального элемента начиная с позиции start
function LastIndexMax<T>(Self: array of T; start: integer): integer; ...
Пускай даже параметр будет называться нейтрально – index, лишь бы не start в данном случае, хотя stopAt здесь был бы интуитивно понятнее, ИМХО.
З.Ы. Кстати, вторая строчка из Comment-Doc (Возвращаемое значение:
) у меня не отображается в подсказке Intellisense, так и должно быть?
Еще одна опечатка в PABCSystem.pas, строка 9055:
/// Возвращает максинимальный элемент
function Max<T>...
Это удачная мысль. Наверно я в прошлой жизни был восточным человеком, потому что для меня все функции, “делающие Last” всегда понимаются перебирающими элементы от конца к началу.