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


#146

Я думал, Вы не можете не знать. Видимо, просто забыли

Что до интерпретатора - это значит полный анализ каждой функции, диагностика ошибок, ведение таблицы переменных, выполнение “на лету” библиотечных функций… маленький дипломчик?


#147

А, ну да, только не знаю, что это алгоритм Дейкстры. Я Дейкстру знаю по тому что он goto в основном запрещал.

Нет, это алгоритм слишком простой. Я бы писал полноценный top-down парсер


#148

Не совсем. Технологии сейчас далеко продвинулись. Там работы - на день максимум.


#149

А кратчайший путь на графе?


#150

А ну да, ещё и это. Кратчайший путь и goto


#151

Возможно. Если знать эти технологии и владеть каким-то инструментальным языком, для них подходящим.


#152

Дам кому-нибуть в качестве допзадания на курсе по компиляторам


#153

Видимо, пора записываться на курс по компиляторам. Не приходилось этими делами лет так под 30 заниматься, у меня все представления остались на уровне книги Д.Гриса. Когда-то писал на PL/1 кросс-компилятор с придуманного самим же для работников радиозавода технологического языка в модифицированный бейсик для микроконтроллера.


#154

Встретилась вот такая задачка.

Дана вещественная матрица размера n x m, все элементы которой различны. В каждой строке выбирается элемент с наименьшим значением, затем среди этих чисел выбирается наибольшее. Указать индексы элемента с найденным значением.

Решил, чтобы не мучиться со вводом, инициализировать матрицу случайными числами. Но загвоздка в том, что матрица вещественная, а MatrRandomReal (что ожидаемо), заполняет её значениями с “бешеной” дробной частью. Поэтому приходится получать подобные данные из целых чисел путем деления на 10, 100, 1000 и т.п. И вот тут не удалось обойтись без оператора цикла (а хотелось!).

// PascalABC.NET 3.2, сборка 1482 от 12.06.2017
// Внимание! Если программа не работает, обновите версию!

begin
  var n:=ReadInteger('Количество строк в матрице:');
  var m:=ReadInteger('Количество столбцов в матрице:');
  var a:=new real[n,m]; // создали матрицу
  var s:=SeqRandom(m,1000,9999).Select(x->x/100); // шаблон случайной строки
  for var i:=0 to n-1 do a.SetRow(i,s.ToArray); // заполнили матрицу
  Writeln('*** Исходная матрица [',n,',',m,'] ***');
  a.Println(6,2); Writeln(6*a.ColCount*'-');
  // собственно, поиск нужного элемента
  var r:=a.Rows.Select((x,i)->(x.Select((y,j)->(y,j))
    .MinBy(y->y[0]),i)).MaxBy(x->x[0][0]);
  Writeln('Искомый элемент A[',r[1]+1,',',r[0][1]+1,']=',r[0][0])
end.

Вывод получается примерно такой (задание подразумевало индексы от единицы)::

Количество строк в матрице: 4
Количество столбцов в матрице: 7
*** Исходная матрица [4,7] ***
 95.22 17.16 14.35 66.27 20.10 91.88 67.96
 20.80 32.71 45.44 35.80 20.17 58.59 24.22
 93.03 93.99 18.30 75.80 65.47 97.14 56.24
 16.95 73.12 48.54 75.72 91.90 67.95 95.71
------------------------------------------
Искомый элемент A[2,5]=20.17

Конечно, я бы мог обойтись без цикла, если бы нашло поддержку мое предложение (идея подчерпнута из Фортрана и Питона) сделать формирование двумерного массива из одномерной последовательности, но увы.

Может быть, кто-то найдет более изящное решение для этой задачи, где не будет цикла и, возможно, будет более выразительным нахождение требуемых индексов?


#155
begin
  var a := MatrGen(3,4,(i,j)->Random(1000)/100);
  a.Println(6);
end.

#156

Добрый день!

По нетехничесим причинам не могу обновить PascalABC.NET. Скажите, пожалуйста, можно ли поставить на комп новую версию, не удаляя старую, т.е. чтобы можно было пользоваться обеими?


#157

Смотря на сколько разнятся версии. В принципе, Вам ничто не мешает переименовать текущую папку, куда установлен PascalABC.NET и сделать новую установку.

Но только следует иметь в виду, что в некоторых случаях программа, написанная на одной сборке, может не пойти без исправления уже на следующем обновлении. Редко, но все же…


#158

Можно


#159

Вообще говоря нельзя, так как PABCRtl.dll один на всю систему. Отключайте запуск с ускорением, чтобы не было конфликтов.


#160

Может быть, нельзя одновременно работать с несколькими версиями? Ведь PABCRtl.dll не устанавливает какой-то процесс, постоянно находящийся в памяти?


#161

Если отключать запуск с ускорением из оболочки, то можно без конфликтов


#162

Известно, что PascalABC.NET реализует ссылочную объектную модель. Как следствие, если X - объект, принадлежащий некоторому классу, то в результате присваивания var Y:=X произойдет копирование ссылки на X в объявленную переменную Y с автовыводом её класса, но при этом X и Y будут ссылаться на один и тот же объект. Это хорошо, потому что просто и наглядно позволяет написать P:=<выражение> и ни о чем не заботиться. Но одновременно это бывает и плохо. Например, если как было указано выше X и Y - это ссылки на один объект, то изменение, сделанное в Х, будет отражаться и в Y, а также, наоборот. Чтобы избежать такой связки, приходится явно выполнять копирование объекта. Так, для массивов имеется функция Copy и мы пишем a:=Copy(b);

А теперь, собственно, проблема. Пусть создается некий класс P

type P=class
   x:array of real;
   y:real;

   constructor(px:array of real; py:real);
   begin
      x:=Copy(px);
      y:=py
   end;

   constructor (n:integer);
   begin
      x:=new real[n];
      y:=0.0
   end;
end;

Я хочу в этом классе иметь возможность делать присваивание вида Q:=P так, чтобы происходило не копирование ссылки, а создавался новый объект, принимающий значения из старого. Конечно, можно написать примерно такой код

begin
  var a:=new P(Arr(1.0,2.0,3.0),-1.0);
  var b:=new P(a.x,a.y);
end.

Но это даже при недостаточно несложной структуре класса Р выглядит достаточно неэлегантно. Попытка перегрузить операцию присваивания у меня не получилась - видимо в справочной системе не хватает какого-то сакрального знания, либо оно запрятано)) Т.е. сам код перегрузки я написал, но после этого начались проблемы с конструктором, который также начал пытаться использовать эту перегрузку.

type P=class
  x:array of real;
  y:real;

  constructor(px:array of real; py:real);
  begin
    x:=Copy(px);
    y:=py
    end;

  constructor (n:integer);
  begin
    x:=new real[n];
    y:=0.0
    end;
   
  class procedure operator :=(var pp:P; value:P);
  begin
    pp.x:=Copy(value.x);
    pp.y:=Value.y;
    end; 
end;

begin
  var a:=new P(Arr(1.0,2.0,3.0),-1.0);
  var b:=new P(a.x,a.y);
end.

Компилятор ругается на строку var a:=new P(Arr(1.0,2.0,3.0),-1.0); - пишет “Несколько подпрограмм могут быть вызваны”.

Хотелось бы увидеть решение, если оно возможно.


#163

Нет, семантику присваивания менять нельзя. То есть, ссылочное всегда останется ссылочным. Оператор := как в C++ тоже перегружать нельзя. Сакрального знания нет.


#164

напиши функцию clone, делов то?

function clone:= new P(self.x,self.y);


#165

Я не задавал вопроса, как это обойти. Меня интересовало конкретно, можно перегрузить операцию присваивания, или нет. Непонятно было, что можно перегрузить +=, но нельзя :=