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


#2219

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

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


#2220

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

#2221

Нет, это плохо. .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;

#2223

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


#2224

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


#2225

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


#2226

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


#2227

В данном случае вы не правы ни в 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 ищет от конца до начала, то есть в обратном направлении. Вот на таком надо акцентировать внимание.

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


#2228

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

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

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

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

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

#2229

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


#2230

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


#2231

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

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

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


#2232

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


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

#2234

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

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

или же

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

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

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

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


#2235

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


#2236

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

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

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


#2237

Потому что:

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

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


#2238

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

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

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

Ссылки:

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


#2239

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