Просмотр сообщений

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


Темы - ilovb

Страницы: 1 [2] 3 4 ... 8
16
Общий раздел / [Oberon 07/13] Семантика FOR
« : Ноябрь 26, 2013, 02:25:17 pm »
Склоняюсь к мысли, что семантика цикла FOR должна быть примерно как в Ada/Lua, т.е.:
1. Переменную цикла запрещено объявлять в секции VAR (соответственно запрещено перекрытие имен)
2. Тип всегда INTEGER;
3. Область действия переменной - тело цикла.
4. Переменная доступна только для чтения.

Кто что думает на этот счет?

17
Общий раздел / Поиск в матрице n*n
« : Ноябрь 22, 2013, 03:07:30 pm »
Тема перекликается с http://oberspace.dyndns.org/index.php/topic,591.0.html
Яркий пример на тему "ниасилил while (и линейный поиск)"

Выдержка из http://kpolyakov.blogspot.ru/2012/10/break-break.html

Цитировать
Пример 5. Разработать функцию, которая определяет, если ли в квадратной матрице элемент, равный заданному значению.

Будем предполагать, что введен тип данных
type Matrix = array[1..N,1..N] of integer;
Тогда функцию можно написать так:
function Find(const A: Matrix; X: integer): boolean;
var i, j: integer;
begin
  Result := True;
  for i:=1 to N do
    for j:=1 to N do
      if A[i,j] = X then exit;
  Result := False
end;
Здесь оператор exit фактически выполняет роль break для вложенного цикла. С формальной точки зрения у функции два выхода. В общем, «я своим ученикам никогда такое не зачту» — уже слышу я от учителей информатики.

А давайте подумаем, какие альтернативы? Можно вот так:
function Find(const A: Matrix; X: integer): Boolean;
var i, j: integer;
label finish;
begin
  Result := True;
  for i:=1 to N do
    for j:=1 to N do
      if A[i,j] = X then goto finish;
  Result := False;
finish:
end;
Но тут вообще «криминал» — метка и goto! Хотя по сути ничего не изменилось, тот же выход из вложенного цикла.

Конечно, здесь можно использовать исключение:
function Find(const A: Matrix; X: integer): Boolean;
var i, j: integer;
begin
  Result := False;
  try
    for i:=1 to N do
      for j:=1 to N do
        if A[i,j] = X then
          raise Exception.Create('');
  except
    Result := True
  end
end;
Но ведь это далеко не «исключительная ситуация», поэтому по смыслу исключения здесь всё-таки не особо уместны. Кроме того, нужно учитывать, что при обработке исключений выполняется большое число машинных команд, что снижает эффективность программы.

Любителей «чистого» структурного программирования наверняка устроит такой вариант решения:
function Find(A: Matrix; X: integer): Boolean;
var i, j: integer;
begin
  Result := False;
  for i:=1 to N do
    for j:=1 to N do
      if A[i,j] = X then Result := True
end;
Но, к сожалению, по эффективности он не может составить конкуренцию предыдущим, так как в любом случае рассматриваются все N2 элементов массива, даже если элемент A[1,1] равен X.


18
Общий раздел / Форыч зло
« : Ноябрь 21, 2013, 03:15:52 pm »
Я эволюционировал.
Предпосылки:
http://oberspace.dyndns.org/index.php/topic,225.msg6308.html#msg6308
http://oberspace.dyndns.org/index.php/topic,584.msg19744.html#msg19744

Сегодня два часа воевал с одним циклом.
Планирование производства.(распределение операций по исполнителям и по времени)
3 вложенных Форыча, ~300 строк, в каждом форыче несколько continue.

Мозг сломал, но так и не придумал как мне вклиниться в эту говнологику.

В итоге, сдавшись, стал размышлять о причинах этого безобразия. И пришел к выводу, что виновата комбинация лени и херового дизайна языка.

Все эти continue (кроме одного) возникли скорее всего не сразу.
Код эволюционировал со временем и условия втыкались автором "по месту", ибо это гораздо легче, чем реструктуризация цикла.
Причина, по которой цикл изначально писался через форыч+continue, тоже банальна.
Дизайн языка и коллекций провоцирует на использование таких циклов. Т.к. форыч интуитивно кажется проще и легче чем while, плюс коллекции спроектированы так, чтобы их удобно было обходить именно форычем.
В результате имеем форыч+continue там, где явно должен быть while.

Если есть возможность написать цикл через форыч, то этой возможностью обязательно воспользуются (с)

Вывод: Форыч зло.
 

19
...но их можно придумать самому по мере надобности.
Сообщение Сергея взбудоражило любопытство...
Кто может похвастать собственной структурой данных? (если не жалко)
Делитесь опытом, товарищи.  :)

20
Общий раздел / Чудо природы
« : Ноябрь 20, 2013, 08:07:55 pm »
Не перестаю удивляться фантазии матушки природы:
Цитировать
Thaumoctopus mimicus умеет копировать внешний вид и поведение более чем 15 групп морских организмов: морских змей, скатов, камбал, медуз, актиний, креветок, крабов, офиур и некоторых других[3][4]. Установлено, что осьминоги способны определять, какое животное необходимо изобразить, в зависимости от того, какого хищника они заметили
http://ru.wikipedia.org/wiki/Thaumoctopus_mimicus

ps Интересно, как это объясняет эволюционная теория?

21
Забавная штука:
http://grompe.org.ru/static/prog_comp_matrix_ru.html

А какой уровень у вас?

ps Мой получается в промежутке 1.5 - 2  :D

22
Предлагаю в этой ветке делиться полезной информацией по всяким алгоритмам и структурам данных.

Вот сносное учебное пособие Новосибирского Государственного Технического Университета:
http://edu.nstu.ru/courses/saod/content.htm

Performance Analysis of BSTs in System Software

23
Общий раздел / Без дженериков можно жить
« : Ноябрь 16, 2013, 04:51:47 pm »
Интерфейс абстрактного типа данных:
DEFINITION AdtRBTrees;

   TYPE
      Node = POINTER TO ABSTRACT RECORD
         (n: Node) Compare- (IN data: Data): INTEGER, NEW, ABSTRACT;
         (n: Node) CopyFrom- (other: Node), NEW, ABSTRACT;
         (n: Node) GetData- (VAR data: Data), NEW, ABSTRACT;
         (n: Node) SetData- (IN data: Data), NEW, ABSTRACT
      END;

      Rider = POINTER TO EXTENSIBLE RECORD
         tree-: Tree;
         linked-: BOOLEAN;
         (rd: Rider) Connect (tree: Tree), NEW;
         (rd: Rider) Find (IN data: Data): BOOLEAN, NEW;
         (rd: Rider) Next (VAR data: Data): BOOLEAN, NEW;
         (rd: Rider) Prev (VAR data: Data): BOOLEAN, NEW;
         (rd: Rider) Reset, NEW
      END;

      Tree = POINTER TO ABSTRACT RECORD
         (tree: Tree) Delete (IN data: Data), NEW;
         (tree: Tree) Insert (IN data: Data), NEW;
         (t: Tree) NewNode- (): Node, NEW, ABSTRACT
      END;

      Data = EXTENSIBLE RECORD  END;

END AdtRBTrees.
Цена вопроса:
MODULE AdtTest;
   
   IMPORT
      RBTrees := AdtRBTrees, Log;
   
   TYPE
     
      Tree* = POINTER TO RECORD (RBTrees.Tree) END;
     
      Rider* = POINTER TO RECORD (RBTrees.Rider) END;
     
      Node* = POINTER TO RECORD (RBTrees.Node)
         data*: Data;
      END;
     
      Data* = RECORD (RBTrees.Data)
         key*: INTEGER;
      END;
   
   PROCEDURE (tree: Tree) NewNode- (): Node;
      VAR node: Node;
   BEGIN
      NEW(node);
      RETURN node;
   END NewNode;
   
   PROCEDURE (node: Node) CopyFrom- (other: RBTrees.Node);
   BEGIN
      WITH other: Node DO
         node.data := other.data;
      END;
   END CopyFrom;
   
   PROCEDURE (node: Node) SetData- (IN data: RBTrees.Data);
   BEGIN
      WITH data: Data DO
         node.data := data;
      END;
   END SetData;
   
   PROCEDURE (node: Node) GetData- (VAR data: RBTrees.Data);
   BEGIN
      WITH data: Data DO
         data := node.data;
      END;
   END GetData;
   
   PROCEDURE (node: Node) Compare- (IN data: RBTrees.Data): INTEGER;
      VAR
         res: INTEGER;
   BEGIN
      WITH data: Data DO
         IF node.data.key > data.key THEN
            res := 1;
         ELSIF node.data.key < data.key THEN
            res := -1;
         ELSE
            res := 0;
         END;
      END;
      RETURN res;
   END Compare;
     
   PROCEDURE Do*;
      VAR
         t: Tree;
         d: Data;
         rd: Rider;
         i: INTEGER;
   BEGIN
     
      NEW(t); NEW(rd); rd.Connect(t);
     
      FOR i := 10 TO 1 BY -1 DO   
         d.key := i;
         t.Insert(d);
      END;
     
      WHILE rd.Next(d) DO
         Log.Int(d.key);
      END;
     
      WHILE rd.Prev(d) DO
         Log.Int(d.key);
      END;
     
   END Do;

BEGIN   

END AdtTest.Do

Прошу обратить внимание, что модуль поддается банальному копипасту и последующей модификации:
Data* = RECORD (RBTrees.Data)
   key*: INTEGER;
END;
и
PROCEDURE (node: Node) Compare- (IN data: RBTrees.Data): INTEGER;
   VAR
      res: INTEGER;
BEGIN
   WITH data: Data DO
      IF node.data.key > data.key THEN
         res := 1;
      ELSIF node.data.key < data.key THEN
         res := -1;
      ELSE
         res := 0;
      END;
   END;
   RETURN res;
END Compare;

Реализацию AdtRBTrees пока не показываю, так как оно еще в процессе обдумывания/модификации/отладки/тестирования

24
Такие есть в природе?

Интересует обычное структурное программирование. Т.е. разбиение на процедуры.
Хочу дать чего-нибудь падавану, но вспомнить ничего такого не могу.

Уже даже была мысль самому написать краткое руководство.

25
Общий раздел / Какой код лучше?
« : Ноябрь 15, 2013, 06:29:37 pm »
PROCEDURE RotateLeft (tree: Tree; node: Node);
   VAR
      temp: Node;
BEGIN

   temp := node.right;
   node.right := temp.left;
   
   IF temp.left # NIL THEN
      temp.left.parent := node;
   END;
   
   temp.parent := node.parent;
   
   IF node.parent = NIL THEN
      tree.root := temp;
   ELSIF node = node.parent.left THEN
      node.parent.left := temp;
   ELSE
      node.parent.right := temp;
   END;
   
   temp.left := node;
   node.parent := temp;
   
END RotateLeft;

PROCEDURE RotateLeft (tree: Tree; a: Node);
   VAR
      b, c, p: Node;
     
BEGIN
   
   p := a.parent;
   c := a.right;
   b := c.left;
   
   (* before:
      p
      a
          c
        b
     
   *)
   
   c.parent := p;
   a.parent := c;
   
   IF p = NIL THEN (* a = tree.root *)
      tree.root := c;
   ELSE
      IF p.right = a THEN
         p.right := c;
      ELSE
         p.left := c;
      END;
   END;
   
   c.left  := a;
   a.right := b;
   
   IF b # NIL THEN
      b.parent := a;
   END;
         
   (* after:
          p
          c
      a
        b
     
   *)
   
END RotateLeft;

26
Возникла потребность уточнить тип поля в расширении записи:
MODULE test;
IMPORT JS;
TYPE
  r1 = RECORD
    a: INTEGER
  END;
  r2 = RECORD(r1)
    b: INTEGER
  END;
  r3 = RECORD
    r: r1
  END;
  r4 = RECORD(r3)
    r: r2 (* АХТУНГ! *)
  END;
BEGIN
END test.

Такое возможно вообще сделать?

ps Я правильно понимаю, что это невозможно из-за фиксированного смещения полей внутри записи? (т.е. расширенная запись тупо не влезет в отведенное предком место)

27
Возможно глупый вопрос. При вставке, если данный ключ уже имеется в дереве, то как правильно обрабатывать эту ситуацию?
1. Вставлять
2. Ничего не делать
3. Сгенерить исключение

Смотрел две реализации. В одной вставляют, в другой ничего не делают. Какое поведение правильное?

28
Общий раздел / Борьба с вложенными IF
« : Ноябрь 08, 2013, 05:47:28 pm »
PROCEDURE CloseWindow (w: Windows.Window);
        VAR res: INTEGER; msg: Sequencers.CloseMsg;
    BEGIN
        IF w # NIL THEN
            IF ~w.sub THEN
                msg.sticky := FALSE; w.seq.Notify(msg);
                IF ~msg.sticky THEN
                    IF w.seq.Dirty() & ~(Windows.neverDirty IN w.flags) THEN
                        HostDialog.CloseDialog(w, quit, res);
                        IF res = HostDialog.save THEN
                            SaveWindow(w, FALSE);    (* if saving is canceled, document remains dirty *)
                            IF w.seq.Dirty() THEN quit := FALSE
                            ELSE Windows.dir.Close(w)
                            END
                        ELSIF res = HostDialog.cancel THEN quit := FALSE
                        ELSE Windows.dir.Close(w)
                        END
                    ELSE Windows.dir.Close(w)
                    END
                ELSE quit := FALSE
                END
            ELSE Windows.dir.Close(w)
            END;
            IF ~quit THEN Kernel.Cleanup END
        END
    END CloseWindow;

Как это переписать чтобы повысилась читабельность?

29
Общий раздел / ART идет на смену Dalvik
« : Ноябрь 08, 2013, 03:28:07 pm »

Страницы: 1 [2] 3 4 ... 8