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

Учитывая тот факт, что слово “учитьСЯ” подразумевает пояснение самому себе, то технически нет никаких других учителей :upside_down_face:

А если string[4] устарело, то как методически верно проверить сигнатуру файла PDF - прочитать первые четыре байта как текст “%PDF” ?

Устарело с точки зрения использования коротких строк где ни поподя. Есть ситуации, в которых без коротких строк не обойтись. Конкретно по Вашему вопросу: на мой взгляд тут вполне нормально использовать короткую строку и читать в нее “по старинке” оператором Read.

А еще можно, например, вот так:

begin
  var f: file;
  Reset(f, 'Tri.pdf');
  var s: string := '';
  loop 4 do
    s += f.ReadChar;
  f.Close;
  if s = '%PDF' then
    Println('Распознана сигнатура PDF-файла')
end.
1 лайк

Нет, это плохо. .ReadChar работает, используя очень сложный алгоритм декодирования. Лучше прочитать 4 байта в сырую и проверить на правильные значения.

А чтоб не добавлять волшебные числа в код - можно использовать word('P') и т.п. Преобразование char в word - это на самом деле не преобразование, а копирование памяти. И JIT компилятор наверняка оптимизирует такое приведение литерала.

А это вообще жуть, сложение строк это медленная операция, и они тут вообще не нужны.
Если уже делать типо как универсально:

(в отдельной функции)

foreach var ch in '%PDF' do
  if f.ReadByte <> word(ch) then
    exit;
Result := true;

Но если заменить это на 4 проверки - в данном случае код не становиться сложнее:

if f.ReadByte <> word('%') then exit;
if f.ReadByte <> word('P') then exit;
if f.ReadByte <> word('D') then exit;
if f.ReadByte <> word('F') then exit;
Result := true;
3 лайка

Вы, как всегда, в своем амплуа. Пофиг размер кода, пофиг ясность алгоритма, зато можно выгадать пару миллисекунд. Даже разбирать Ваш код не стану - фактически это почти ассемблер.

1 лайк

В данной задаче, с учётом краткости кода, не думаю, что скорость критична.

На фоне времени открытия файла операционной системой говорить об эффективности кода чтения четырех байт смысла не вижу.

Тем более абстрактными файлами паскаля, у которых дофига внутренней реализации

В данном случае вы не правы ни в 1 из пунктов. Если написать мой вариант целиком:

function CheckPDFHeader(f: file): boolean;
begin
  foreach var ch in '%PDF' do
    if f.ReadByte <> word(ch) then
      exit;
  Result := true;
end;

begin
  var f: file;
  Reset(f, '1.pdf'); // вообще лучше OpenBinary, тогда всё в 1 строчку
  Writeln(CheckPDFHeader(f));
end.

Этот алгоритм ни сколько не сложнее, и по размеру такой же.


Следующее - тут вопрос не нескольких миллисекунд. В .Net ради того чтоб работало в каждом компе каждой культуры - серьёзно пожертвовали простотой внутренних алгоритмов.

У integer.Parse, вон, несколько сотен строк реализации. Поэтому IntToStr, в отличии от большинства остальных велосипедов из PABCSystem - просто летает.

И чтение символов и строк использующее определённые кодировки - не на много лучше.


Ну вообще, тут всё не так ужасно.

У них нет ничего и близкого по затратам к чтению символов. Но всё же правильнее использовать BinaryReader:

  1. Он поддерживает все стандартные типы. То есть все виды целых чисел (всех размеров и знаковости) и т.п.

  2. file, в целом, устарел. В основном это касается его процедурного синтаксиса, но не только.


И последнее, что касается общего случая:
@RAlex, вы не научите никого ничему хорошему, показывая красивый, но не более того, код. Таким кодом можно эффективно вербовать некрофилов, но не обучать.

Даже если работа такова, что повсеместно надо думать сначала о времени написания кода, и только после этого о качестве - чтоб писать красивые и короткие костыли, тоже надо хорошо разбираться в том что есть, чего нет и в том, как всё устроено.

Как, к примеру, тот факт что .LastIndexOf ищет от конца до начала, то есть в обратном направлении. Вот на таком надо акцентировать внимание.

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

3 лайка

Я не стану Вам возражать, поскольку уже привык, что Вы тут периодически штатно поливаете фекалиями и Microsoft, и .NET, и PascalABС.NЕТ… Вас послушать - ну все везде настолько кривое, у разработчиков руки растут не оттуда, все написано длинно, нерационально и т.п. Это как на Руси скоморохи были на ярмарках, народ смешили, так и Вас читать временами бывает забавно. Но не более.

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

Мать слегла. Врачи определили полеомиелит, потерю памяти,
тахикардию с перемежающейся экстрасистолией, хронический гастрит,
чесотку и энцефалопатический сидром.

– Сходи к бабушке, дочка, – прошептала мать. – Отнеси ей пирожков.
Пусть порадуется. Недолго уж ей осталось...

Бабушка жила одна в глухом лесу, где до ухода на пенсию по инвалидности
работала уборщицей в Театре оперы и балета. Как-то, заменяя внезапно
умершую балерину, она упала в оркестровую яму, сломала ноги, руки, шею,
позвоночник и выбила зубы...
                                                      А.Иванов. "Красная Пашечка".
1 лайк

Не думаю, @RAlex хотя бы научит красиво оформлять код, что не самый бесполезный навык, поскольку кроме умения оптимально писать код хорошо бы уметь его красиво «подавать», чтобы другие его могли быстро понять.

Ну мелкософт и точканет ладно. Но я ни разу не видел чтобы Сергей поливал PascalABC.NET. Я искренне убеждён в том, что даже если такое было, то только в целях сделать PascalABC.NET лучше.

1 лайк

Я прошу воздержаться от препирательств друг с другом, а то после вербования некрофилов я не знаю, куда фантазия наших участников форума занесёт.

Считаю это некорректным по отношению к оппоненту.

Пока не буду ничего модерировать. Надеюсь, предупреждения достаточно

5 лайков

Некрофилы это, если что, любители сдохших паскалей)) Вообще, вроде, это не первый раз я их тут так назвал…

- Да позволено мне будет узнать, что ты, о бриллиант моей души,  подразумеваешь
под этим неизвестным мне словом "балда"?  -  с  любопытством осведомился Хоттабыч.
Волька покраснел, как морковка.
- Понимаешь ли... как тебе сказать... э-э-э...  Ну,  в  общем,  "балда" -
это что-то вроде мудреца.
                                        Л.Лагин. "Старик Хоттабыч".
2 лайка

Мнения разные, и я считаю, что критерии скорее не “новее-старее”, а “быстрее написать-легче понять” - и далее по приоритетам.

  1. Подскажите, как проще инициализировать структуру вида
var список:array['A'..'Z']of list<string>;

или же

for var c:='A'to'Z'do список:=new list<string>;

нормально вписывается в парадигму ? Пока что не придумал быстрый алфавитный указатель.

  1. В каждой отдельной строке текстового файла находится цифровая комбинация (может начинаться с нулей). Нужно сравнить этот файл со вторым и вывести в третий файл только совпадения.

Как бы просто: ввести первый файл в HashSet и читать второй файл, фильтруя совпадения. Но есть ли в данном случае не только рекомендательные, но и реальные преимущества у SortedSet или других структур ?

Вместо статичного массива можно использовать словарь (Dictionary), потому что в отличии от статичных массивов - это нормальный класс, которому не надо делать синоним чтоб его можно было передавать в методы.
Но инициализировать всё равно только через for. Более короткой записи в данном случае нет.

В общем я понимаю концепцию хэшей и возможные моменты, но есть нюанс с namespace или почему при объявлении

var dict:=new Dictionary<string, word>(system.StringComparer.InvariantCultureIgnoreCase);

в компараторе нужно указать модуль system ?

Потому что:

  1. System не модуль, а пространство имён.
  2. Dictionary описан в PABCSystem, то есть модуле который подрубается ко всему. А описан он так:
  /// Представляет ассоциативный массив (набор пар Ключ-Значение), реализованный на базе хеш-таблицы
  Dictionary<Key, Value> = System.Collections.Generic.Dictionary<Key, Value>;

Если прописать uses System - дальше писать System. не надо будет

Потому, что в Вашей программе пространство имён (!) System не подключено. Возможность же писать Dictionary без явной ссылки на System обуславливается тем, что за Вас в системном модуле, подключаемом неявно ко всему, прописан alias для Dictionary<,>:

  /// Представляет ассоциативный массив (набор пар Ключ-Значение), реализованный на базе хеш-таблицы
  Dictionary<Key, Value> = System.Collections.Generic.Dictionary<Key, Value>;

, но для компаратора IEqualityComparer<> подобного alias'a не сделано.

Ссылки:

Полезные материалы по .NET, технологиям программирования, алгоритмам и паттернам проектирования

Помогите. Не получается преобразовать в char. var C: char тоже не помог. procedure Form1.button1_Click(sender: Object; e: EventArgs); begin var c:=textbox1.Text; label1.Text := ord©; end;