Помощь новичкам

Про массивы - это я уже понял, сделав замеры. Вроде бы можно обойтись

var b:=a.Where(t->Has3(t));

потому что массив не нужен, но преобразование .ToArray ускоряет решение почти вдвое.

Абсолютно “убили” реализация .ToString, а также процедуры Str() и функции IntToStr() - лишь обращение к ним для преобразования целого в строку на порядок (!) медленнее, чем весь цикл

 while n<>0 do begin
    if n mod 10=3 then begin Result:=True; Exit end;
    n:=n div 10; 
    end;

Но эти тормоза, видимо, уже заложены в .NET. Т.е. если в процедуре только написать var s:=n.ToString; то получим код, который почти вдесятеро дольше, выполняется, чем приведенный цикл.

Здравствуйте.

  1. Как язык. А какие NET-проекты кроме консольного и оконного имеете в виду?
  2. Да, надо убрать RemObjects Oxygene - он малораспространён. В своё время embarcadero присоединила к себе Prism, потом отсоединила - что то пошло не так. Delphi заняла свою нишу, учебной в этой нише уже нет.
  3. Связали с .NET потому что компиляторы под .NET писать просто и библиотек много.

Ну здесь побочный эффект In3 вызывается только если a[i] > max, поэтому в разы быстрее. ToArray на погоду не влияет

Ну так здесь дело в сборщиках мусора, а в самом алгоритме. Что еще раз доказывает, что надо думать о задаче, а не о ручном управлении памяти, где мы выграем 2% времени.

function Has3(n:Integer):boolean;
begin
  while n<>0 do begin
    if n mod 10=3 then begin Result:=True; Exit end;
    n:=n div 10; 
    end;
  Result:=False
end;

function &Where<T>(self: array of T; pred: (T,T)->(boolean, T)): array of T; extensionmethod;
begin
  var initial := default(T);
  var lst := new List<T>;
  for var i := 0 to self.Length - 1 do
  begin
    var item := self[i];
    var res := pred(item, initial);
    initial := res.Item2;
    if res.Item1 then
      lst.Add(item);
  end;
  Result := lst.ToArray();
end;

begin
  var a:=Arr(520,46904,58684,2215,83967,66560,96722,41600,16921,
        99150,1151,86738,63634,71238,13216,32406,49880,1558,75516,
        73929,7482,58804,47776,65890,47698,18548,26752,98776,82750,
        87389,23938,55437,86701,10204,93551,24241,16244,44138,25003,
        22798,83587,70257,65030,83983,81229,67478,78077,42619,73533,
        41772,49635,31721,77620,34630,63560,41716,99129,92794,54518,
        65419,39808,97947,58850,29532,75212,45715,37,53430,77687,
        88976,16163,5742,76556,52718,90343,37226,93774,63793,84661,
        80220,40472,84134,25243,40979,37755,92218,77818,52072,46645,
        51836,25112,23450,89621,59584,82991,85640,11407,35498,8771,35515);
  var k:=1000000;
  Milliseconds;
  loop k do begin
    var b:=a.Where((t,max)->((t > max) and Has3(t))?(true,t):(false,max));
    if b.Length>0 then begin
      //writeln('a[',kk+1,']=',max);
      end
    else
      writeln('Элементы, содержащие цифру 3 отсутствуют');
    end;
   writeln(Milliseconds);
  var t:=MillisecondsDelta;  
  Writeln(t/k);
end.

:slight_smile:

Программа “злого преподавателя” или как там его выполняется за 0.002 миллисекунд на итерация цикла, а ваша 0.007. Кстати когда я заменил в программе RAlex’a массив на список - получил тот же результат в 0.007. [quote=“ibond, post:248, topic:263”] ToArray на погоду не влияет [/quote] .ToArray преобразовывает алгоритм заложенный в sequence в массив, ускоряя всё в 2 раза, потому что в программе сначала проверяется if b.Length>0 then(кстати тут пожалуй надо было поставить if b.Any then), для вычисления кол-во элементов вычисляется вся последовательность, а потом она ещё раз вычисляется в b.Max. Ну а основная проблема программы RAlex’a в том что создаётся отдельный массив, в программе преподавателя его не было и если сделать без него то программа опять же работает с выходом ~0.002.

И ещё хотелось бы добавить про 2%. Вот вам пример правила “минимум глобальных переменных” и красивый код который оно даёт, с не мешающимися в остальном классе именами:

procedure p1(i: integer);
begin
  var i2 := i + 1;
  var i3 := i2 + 1;
  var i4 := i3 + 1;
end;

begin
  
  var LT := System.DateTime.Now;
  
  loop 100000000 do
    p1(1);
  
  writeln(System.DateTime.Now - LT);

end.

И её оналог с глобальными переменными:

var
  i2,i3,i4:integer;

procedure p1(i: integer);
begin
  i2 := i + 1;
  i3 := i2 + 1;
  i4 := i3 + 1;
end;

begin
  
  var LT := System.DateTime.Now;
  
  loop 100000000 do
    p1(1);
  
  writeln(System.DateTime.Now - LT);
  
end.

И вот уже разница в 2 раза! Не поймите меня не правильно, когда надо написать что то на скорую руку - такие “трюки” очень даже полезны, но надо знать когда это уместно.

Сейчас же вопрос был в том чтоб оптимизировать программу, а не сделать красивое нагромождение.

Глобальные переменные - зло.

Запустите в режиме Release по Shift-F9, отключив в Опциях компиляции все галочки - результат будет противоположным: в 4 раза быстрее работают локальные переменные

Ну, собственно, Sun_Serega прав. Основное преимущество в алгоритме бешеного преподавателя даёт неполное вычисление логического выражения. Второе преимущество - явный вызов функции, а не через указатель. Вот я всё это поменял - и хвалёное преимущество первой программы растворилось:

    var pp: integer->boolean := In3;
    for i:integer:=1 to N do
      if (pp(a[i])) and (a[i]>max) then begin
        max:=a[i]; p:=i; Y:=True;
      end;

Можно ли в RegexReplace сослаться в подстроке замены на результат поиска в соответствии с заданным для поиска регулярным выражением?

Есть задача: после каждого непробельного символа в строке вставить звездочку. Символы легко выделяютcя по \w, но как на них сослаться в подстроке замены?

Я попробовал работать с гитхабом чтоб была возможность делать бекапы, но заметил что русский текст в комментариях сохраняет как Åäåíèöà. Это у меня что то не так настроено, паскаль не так сохраняет или в принципе у паскаля и гитхаба не совместимые кодировки?

с помощью кодирования на паскаль абс.нет можно ли создать анимированное видео в длинною 30-50 секунд? если да, то как в него добавить звук?

Тут вопрос не в паскале. Ищите библиотеки в интернете для создания .mp4 или какой формат видео хотите сделать, подключайте. Подключить можно любую библиотеку работающую на C++ и функционал у неё будет тот же.

Здравствуйте, подскажите пожалуйста как подключать .net библиотеки в паскале абсNet, и где их можно скачать. Заранее спасибо.

{$reference 'system.dll'}
{$reference 'system.io.dll'}
{$reference 'system.drawing.dll'}
{$reference 'system.windows.forms.dll'}

uses
system,
system.io,
system.drawing,
system.windows.forms;

ну и аналогично) Скачивать не нужно, при установке среды, .NET Framework устанавливается принудительно, да и основные библиотеки есть в винде :slight_smile: Приятного пользования) P.S. Если хотите формы делать, то совет: подключите ещё “PresentationCore.dll”

Подключение стандартной библиотеки System.Drawing: {$reference System.Drawing.dll};

Подключение метода из WinApi:

function MessageBox(h:integer;m,c:string;t:integer):integer;
external 'User32.dll' name 'MessageBox';

begin
  MessageBox(0,'Привет!','Сообщение',0);
end.

(Пример из папки Samples, идущей в наборе с паскалем)

Чтоб скачивать - надо знать что вы хотите скачать, перейти на страницу продукта и от туда скачать.

Про большинство библиотек так же написано на msdn, вот к примеру про MessageBox. На этой странице есть вся необходимая информация чтоб с 0 ещё раз написать тот пример. Библиотеку User32.dll скачивать не нужно потому что без неё ваш компьютер не работал бы.

Не подскажите библиотеки для парсинга математических выражений?

Вроде есть какой то класс в System для этого, но он очень ограниченный… Попробуйте поискать в интернете готовые парсеры и перевести их код на паскаль. Или напишите свой, это программа на строчек 50-300(зависит от умений).

А как использовать EXCEL? Жалуется, что нет Interop.Excel.dll

В каком смысле использовать эксель? Загружать файлы созданные в экселе? Использовать какие то функции экселя в паскале?

Скорее всего в таком примерно (код C#)

using Excel = Microsoft.Office.Interop.Excel;
namespace AppWordExcel
... 
  private Excel.Application excelapp;
  excelapp = new Excel.Application(); 
  excelapp.Visible=true;
...