Реализуем Стек, Очередь и Приоритетную очередь в 1С

Публикация № 1079893

Разработка - Практика программирования

абстрактная структура данных стек очередь приоритет приоритетная приоритетом

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

 

Стек

Стек - это абстрактный тип данных, представляющий собой список элементов, организованных по принципу ЛИФО ("последним пришел - первым вышел").

Основные операции со стеком это:

  • Push – вставка элемента наверх стека;

  • Top – получение верхнего элемента без удаления;

  • Pop – получение верхнего элемента и его удаление;

  • isEmpty – возвращает true, если стек пуст.

Для реализации стека будем использовать тип данных Массив. Реализуем вышеописанные операции:

#Область Стек

Функция Стек_Новый()
	Возврат Новый Массив;
КонецФункции

// Push
Процедура Стек_Положить(Стек, Значение)
	Стек.Добавить(Значение);
КонецПроцедуры

// Top
Функция Стек_ВзятьБезУдаления(Стек)
	Возврат Стек[Стек.ВГраница()];
КонецФункции

// Pop
Функция Стек_Взять(Стек)
	ИндексПоследнегоЭлемента = Стек.ВГраница();
	Значение = Стек[ИндексПоследнегоЭлемента];
	Стек.Удалить(ИндексПоследнегоЭлемента);
	Возврат Значение;
КонецФункции

// isEmpty
Функция Стек_Пустой(Стек)
	Возврат Стек.Количество() = 0;
КонецФункции

#КонецОбласти

Эти операции работают как в тонком так и в других клиентах.

 
 Пример того, как использовать стек

Вроде все просто и быстро работает.

 

Очередь

Очередь - это абстрактный тип данных, представляющий собой список элементов, организованных по принципу ФИФО ("первый пришел - первый вышел").

Основные операции с очередью это:

  • Добавить элемент в конец очереди;

  • Получить элемент из начала очереди (без удаления из очереди);

  • Получить элемент из начала очереди (с удалением из очереди);

  • Проверка пустая ли очередь.

Так же как и для стека будем использовать тип данных Массив. Реализуем вышеописанные операции.

#Область Очередь

Функция Очередь_Новый()
	Возврат Новый Массив;
КонецФункции

Процедура Очередь_Добавить(Очередь, Значение)
	Очередь.Добавить(Значение);
КонецПроцедуры

Функция Очередь_ПолучитьБезУдаления(Очередь)
	Возврат Очередь[0];
КонецФункции

Функция Очередь_Получить(Очередь)
	Значение = Очередь[0];
	Очередь.Удалить(0);
	Возврат Значение;
КонецФункции

Функция Очередь_Пустой(Очередь)
	Возврат Очередь.Количество() = 0;
КонецФункции

#КонецОбласти
 
 Пример использования очереди

Здесь тоже все просто, но что по скорости? Поскольку отличие в только в способе получения элемента данных, то сравним скорость работы функции Очередь_Получить(Очередь) с Стек_Взять(Стек). Замеры производительности показали:

 

Строка кода 10 000 элементов 50 000 элементов 100 000 элементов
Время чистое % Время чистое % Время чистое %
Стек (Стек_Взять(Стек)) 0,170986 43,97 0,877694 21,25 1,703886 14,30
ИндексПоследнегоЭлемента = Стек.ВГраница(); 0,064098 16,48 0,330289 8,00 0,639357 5,37
Значение = Стек[ИндексПоследнегоЭлемента]; 0,047934 12,33 0,244083 5,91 0,475707 3,99
Стек.Удалить(ИндексПоследнегоЭлемента); 0,058954 15,16 0,303322 7,34 0,588822 4,94
             
Очередь (Очередь_Получить(Очередь)) 0,217842 56,03 3,253449 78,75 10,2105 85,70
Значение = Очередь[0]; 0,058589 15,07 0,333911 8,08 0,535987 4,50
Очередь.Удалить(0); 0,159253 40,96 2,919538 70,67 9,674513 81,20
             
Итого 0,388828 100,00 4,131143 100,00 11,914386 100,00

 

Динамика ожидаемая. Поскольку при получении элемента очереди из массива удаляется нулевой элемент, то и работает это дольше из-за того, что массив каждый раз "сдвигает" индексы. Но оказалось, что в 1С метод массива ВГраница() "не дешевый".

Если размер очереди не превышает 10 000 элементов, то разница в скорости между очередью и стеком не заметна, т.е. такая реализация Очереди работает также быстро как и Стек. В остальном же, чем больше элементов в очереди, тем медленнее будет работать операция получения. А что делать, если у нас могут быть очереди огромных размеров? Способ известен, избавляемся от удаления нулевого элемента в массиве и у нас получается следующее:

 

#Область Очередь

Функция Очередь_Новый()
	Возврат Новый Структура("Данные, Голова, Хвост", Новый Массив, 0, 0)
КонецФункции

Процедура Очередь_Добавить(Очередь, Значение)
	Очередь.Данные.Добавить(Значение);
	Очередь.Хвост = Очередь.Хвост + 1;
КонецПроцедуры

Функция Очередь_ПолучитьБезУдаления(Очередь)
	Возврат Очередь.Данные[Очередь.Голова];
КонецФункции

Функция Очередь_Получить(Очередь)
	Значение = Очередь.Данные[Очередь.Голова];
	Очередь.Голова = Очередь.Голова + 1;
	Возврат Значение;
КонецФункции

Функция Очередь_Пустой(Очередь)
	Возврат Очередь.Голова = Очередь.Хвост;
КонецФункции

#КонецОбласти

Сравним скорость работы со стектом

 

Строка кода 10 000 элементов 50 000 элементов 100 000 элементов
Время чистое % Время чистое % Время чистое %
Стек 0,330505 43,37 1,633625 44,14 3,288941 43,81
Возврат Новый Массив; 0,000014 0,00 0,000014 0,00 0,000015 0,00
Стек.Добавить(Значение); 0,069462 9,11 0,340238 9,19 0,680083 9,06
ИндексПоследнегоЭлемента = Стек.ВГраница(); 0,063925 8,39 0,321949 8,70 0,649467 8,65
Значение = Стек[ИндексПоследнегоЭлемента]; 0,047449 6,23 0,239641 6,47 0,477748 6,36
Стек.Удалить(ИндексПоследнегоЭлемента); 0,05953 7,81 0,29952 8,09 0,597924 7,96
Возврат Стек.Количество() = 0; 0,090125 11,83 0,432263 11,68 0,883704 11,77
             
Очередь 0,431625 56,63 2,067537 55,86 4,219035 56,19
Возврат Новый Структура("Данные, Голова, Хвост", Новый Массив, 0, 0) 0,000054 0,01 0,000046 0,00 0,000049 0,00
Очередь.Данные.Добавить(Значение); 0,09672 12,69 0,442808 11,96 0,943409 12,57
Очередь.Хвост = Очередь.Хвост + 1; 0,096046 12,60 0,4312 11,65 0,857976 11,43
Значение = Очередь.Данные[Очередь.Голова]; 0,075233 9,87 0,37646 10,17 0,752637 10,02
Очередь.Голова = Очередь.Голова + 1; 0,083533 10,96 0,418471 11,31 0,835261 11,12
Возврат Очередь.Голова = Очередь.Хвост; 0,080039 10,50 0,398552 10,77 0,829703 11,05
             
Итого 0,76213 100,00 3,701162 100,00 7,507976 100,00

 

Конечно, очередь все равно работает чуть медленнее стека, но разница не так заметна и она уже не растет при размере более 10 000. Но у нас растет размер массива.

 

Приоритетная очередь

Приоритетная очередь — это абстрактная структура данных, где у каждого элемента есть приоритет. Элемент с более высоким приоритетом находится перед элементом с более низким приоритетом. Если у элементов одинаковые приоритеты, они располагаются в зависимости от своей позиции в очереди.

Очередь с приоритетом использует такие же операции что и обычная очередь:

  • Добавить элемент в конец очереди;

  • Получить элемент из начала очереди (без удаления из очереди);

  • Получить элемент из начала очереди (с удалением из очереди);

  • Проверка пустая ли очередь.

Какой же тип выбрать для этой структуры данных? Теперь наряду с элементом, необходимо хранить приоритет. Простым способом будет выбрать тип, у которого есть методы сортировки. Очевидно, что массив не подойдет. Что мы имеем:

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

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

Реализуем приоритетную очередь используя тип ТаблицаЗначений:

#Область ПриоритетнаяОчередь_ТаблицаЗначений

Функция ПриоритетнаяОчередь_Новый()
	Очередь = Новый Структура;
	Очередь.Вставить("Отсортировано",	Истина);
	Очередь.Вставить("Данные",		Новый ТаблицаЗначений);
	Очередь.Данные.Колонки.Добавить("Значение");
	Очередь.Данные.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число"));
	Очередь.Данные.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число"));
	Очередь.Вставить("Позиция", 0);
	Возврат Очередь;
КонецФункции

Процедура ПриоритетнаяОчередь_Добавить(Очередь, Значение, Приоритет)
	Очередь.Отсортировано = Ложь;
	НоваяСтрока = Очередь.Данные.Добавить();
	НоваяСтрока.Значение = Значение;
	НоваяСтрока.Приоритет = Приоритет;
	НоваяСтрока.Позиция = Очередь.Позиция + 1;
	Очередь.Позиция = НоваяСтрока.Позиция;
КонецПроцедуры

Функция ПриоритетнаяОчередь_ПолучитьБезУдаления(Очередь)
	Данные = Очередь.Данные;
	Если Не Очередь.Отсортировано Тогда
		Очередь.Отсортировано = Истина;
		Данные.Сортировать("Приоритет, Позиция");
	КонецЕсли;
	Возврат Данные[0].Значение;
КонецФункции

Функция ПриоритетнаяОчередь_Получить(Очередь)
	Данные = Очередь.Данные;
	Если Не Очередь.Отсортировано Тогда
		Очередь.Отсортировано = Истина;
		Данные.Сортировать("Приоритет, Позиция");
	КонецЕсли;
	Значение = Данные[0].Значение;
	Данные.Удалить(0);
	Возврат Значение;
КонецФункции

Функция ПриоритетнаяОчередь_Пустой(Очередь)
	Возврат Очередь.Данные.Количество() = 0;
КонецФункции

#КонецОбласти
 
Пример использования приоритетной очереди

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

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

 

Реализуем приоритетную очередь используя тип СписокЗначений:

В Списке значений для хранения Приоритета будем использовать Представление. И вот здесь наталкиваемся на ограничение - Представление имеет тип Строка, а Приоритет у нас Число. Таким образом Приоритет из Числа преобразуется в Строку и метод СортироватьПоПредставлению() неправильно будет работать для нашей цели (например строки 1, 2, 10, 20, 100, 200 будут упорядочены сделующим образом 1, 10, 100, 2, 20, 200). Чтобы добиться "правильной" сортировки нам необходимо число привести в соответствующий строковый вид, например, числа 1, 2, 10, 20, 100, 200 приводим к строкам 001, 002, 010, 020, 100, 200. Для этого нам необхомо с определиться с длиной (разрядностью) и "дорисовать" лидирующие нули. Длина влияет на скорость сортировки, поэтому будем реализовывать так, чтобы можно было заранее указать разрядность. Вспоминаем еще один момент со "сдвигами" индексов, список значений эту "проблему" имеет, поэтому сортируем по убыванию, а получаем элемент сверху. В результате получаем следующее:

#Область ПриоритетнаяОчередь_СписокЗначений

&НаКлиенте
Функция ПриоритетнаяОчередь_Новый(РазрядностьПриоритета = 16, РазрядностьПозиции = 16)
	Очередь = Новый Структура;
	Очередь.Вставить("Отсортировано", Истина);
	Очередь.Вставить("Данные", Новый СписокЗначений);
	Очередь.Вставить("ФорматнаяСтрокаПриоритета", "ЧЦ=" + РазрядностьПриоритета + "; ЧН=; ЧВН=; ЧГ=0");
	Очередь.Вставить("ФорматнаяСтрокаПозиции", "ЧЦ=" + РазрядностьПозиции + "; ЧН=; ЧВН=; ЧГ=0");
	Очередь.Вставить("Позиция", 0);
	Возврат Очередь;
КонецФункции

&НаКлиенте
Процедура ПриоритетнаяОчередь_Добавить(Очередь, Значение, Приоритет)
	Очередь.Отсортировано = Ложь;
	Очередь.Позиция = Очередь.Позиция + 1;
	ПриоритетСтрока =  Формат(Приоритет, Очередь.ФорматнаяСтрокаПриоритета) + Формат(Очередь.Позиция, Очередь.ФорматнаяСтрокаПозиции);
	Очередь.Данные.Добавить(Значение, ПриоритетСтрока);
КонецПроцедуры

&НаКлиенте
Функция ПриоритетнаяОчередь_ПолучитьБезУдаления(Очередь)
	Данные = Очередь.Данные;
	Если Не Очередь.Отсортировано Тогда
		Очередь.Отсортировано = Истина;
		Данные.СортироватьПоПредставлению(НаправлениеСортировки.Убыв);
	КонецЕсли;
	ИндексПоследнегоЭлемента = Данные.Количество() - 1;
	Возврат Данные[ИндексПоследнегоЭлемента].Значение;
КонецФункции

&НаКлиенте
Функция ПриоритетнаяОчередь_Получить(Очередь)
	Данные = Очередь.Данные;
	Если Не Очередь.Отсортировано Тогда
		Очередь.Отсортировано = Истина;
		Данные.СортироватьПоПредставлению(НаправлениеСортировки.Убыв);
	КонецЕсли;
	ИндексПоследнегоЭлемента = Данные.Количество() - 1;
	Значение = Данные[ИндексПоследнегоЭлемента].Значение;
	Данные.Удалить(ИндексПоследнегоЭлемента);
	Возврат Значение;
КонецФункции

&НаКлиенте
Функция ПриоритетнаяОчередь_Пустой(Очередь)
	Возврат Очередь.Данные.Количество() = 0;
КонецФункции

#КонецОбласти

Если удобней передавать максимальное число, а не разрядность то фукнция ПриоритетнаяОчередь_Новый() будет выглядеть так:

&НаКлиенте
Функция ПриоритетнаяОчередь_Новый(МаксимальноеЧислоПриоритета = Неопределено, МаксимальноеЧислоПозиции = Неопределено)
	
	РазрядностьПриоритета = ?(МаксимальноеЧислоПриоритета = Неопределено, 16, СтрДлина(Формат(МаксимальноеЧислоПриоритета, "ЧГ=0")));
	РазрядностьПозиции = ?(МаксимальноеЧислоПозиции = Неопределено, 16, СтрДлина(Формат(МаксимальноеЧислоПозиции, "ЧГ=0")));
	
	Очередь = Новый Структура;
	Очередь.Вставить("Отсортировано", Истина);
	Очередь.Вставить("Данные", Новый СписокЗначений);
	Очередь.Вставить("ФорматнаяСтрокаПриоритета", "ЧЦ=" + РазрядностьПриоритета + "; ЧН=; ЧВН=; ЧГ=0");
	Очередь.Вставить("ФорматнаяСтрокаПозиции", "ЧЦ=" + РазрядностьПозиции + "; ЧН=; ЧВН=; ЧГ=0");
	Очередь.Вставить("Позиция", 0);
	
	Возврат Очередь;
	
КонецФункции

Сравним обе реализиции приоритетной очереди по скорости:

 

Строка кода 10 000 элементов 50 000 элементов 100 000 элементов
Время чистое % Время чистое % Время чистое %
Приоритетная очередь (таблица значений) 1,1063 35,81 6,100376 37,26 12,214519 37,28
Очередь = Новый Структура; 0,000014 0,00 0,000013 0,00 0,000014 0,00
Очередь.Вставить("Отсортировано",   Истина); 0,000023 0,00 0,000022 0,00 0,000022 0,00
Очередь.Вставить("Данные",          Новый ТаблицаЗначений); 0,000025 0,00 0,000023 0,00 0,000024 0,00
Очередь.Данные.Колонки.Добавить("Значение"); 0,000049 0,00 0,000071 0,00 0,000046 0,00
Очередь.Данные.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число")); 0,000049 0,00 0,000049 0,00 0,000048 0,00
Очередь.Данные.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число")); 0,00004 0,00 0,000041 0,00 0,000041 0,00
Очередь.Вставить("Позиция", 0); 0,000014 0,00 0,000014 0,00 0,000014 0,00
Очередь.Отсортировано = Ложь; 0,059319 1,92 0,296483 1,81 0,599376 1,83
НоваяСтрока = Очередь.Данные.Добавить(); 0,128262 4,15 0,758155 4,63 1,073491 3,28
НоваяСтрока.Значение = Значение; 0,066091 2,14 0,332992 2,03 0,672613 2,05
НоваяСтрока.Приоритет = Приоритет; 0,060047 1,94 0,305085 1,86 0,610112 1,86
НоваяСтрока.Позиция = Очередь.Позиция + 1; 0,098084 3,17 0,461481 2,82 0,903573 2,76
Очередь.Позиция = НоваяСтрока.Позиция; 0,060872 1,97 0,298918 1,83 0,616223 1,88
Данные = Очередь.Данные; 0,06077 1,97 0,305511 1,87 0,603819 1,84
Если Не Очередь.Отсортировано Тогда 0,050897 1,65 0,252758 1,54 0,499659 1,52
Очередь.Отсортировано = Истина; 0,000004 0,00 0,000005 0,00 0,000004 0,00
Данные.Сортировать("Приоритет, Позиция"); 0,127592 4,13 1,042711 6,37 2,588318 7,90
КонецЕсли; 0,029566 0,96 0,148514 0,91 0,290742 0,89
Значение = Данные[0].Значение; 0,10961 3,55 0,583075 3,56 1,152302 3,52
Данные.Удалить(0); 0,142949 4,63 0,738205 4,51 1,485553 4,53
Возврат Очередь.Данные.Количество() = 0; 0,112023 3,63 0,57625 3,52 1,118525 3,41
             
Приоритетная очередь (список значений) 1,983387 64,19 10,273666 62,74 20,553372 62,72
Очередь = Новый Структура; 0,000016 0,00 0,000016 0,00 0,000025 0,00
Очередь.Вставить("Отсортировано", Истина); 0,000022 0,00 0,000023 0,00 0,000024 0,00
Очередь.Вставить("Данные", Новый СписокЗначений); 0,000019 0,00 0,000019 0,00 0,000019 0,00

Очередь.Вставить("ФорматнаяСтрокаПриоритета",

"ЧЦ=" + РазрядностьПриоритета + "; ЧН=; ЧВН=; ЧГ=0");

0,000063 0,00 0,000052 0,00 0,000051 0,00
Очередь.Вставить("ФорматнаяСтрокаПозиции", "ЧЦ=16; ЧН=; ЧВН=; ЧГ=0"); 0,000014 0,00 0,000014 0,00 0,000014 0,00
Очередь.Вставить("Позиция", 0); 0,000014 0,00 0,000014 0,00 0,000014 0,00
Очередь.Отсортировано = Ложь; 0,056188 1,82 0,284132 1,74 0,560949 1,71
Очередь.Позиция = Очередь.Позиция + 1; 0,104786 3,39 0,443424 2,71 0,866142 2,64

ПриоритетСтрока =  Формат(Приоритет, Очередь.ФорматнаяСтрокаПриоритета)+

Формат(Очередь.Позиция, Очередь.ФорматнаяСтрокаПозиции);

0,951056 30,78 4,927951 30,10 9,781007 29,85
Очередь.Данные.Добавить(Значение, ПриоритетСтрока); 0,125726 4,07 0,630631 3,85 1,257842 3,84
Данные = Очередь.Данные; 0,052208 1,69 0,261573 1,60 0,51975 1,59
ИндексПоследнегоЭлемента = Данные.Количество() - 1; 0,092614 3,00 0,508852 3,11 0,949622 2,90
Если Не Очередь.Отсортировано Тогда 0,049787 1,61 0,239129 1,46 0,478487 1,46
Очередь.Отсортировано = Истина; 0,000005 0,00 0,000005 0,00 0,000005 0,00
Данные.СортироватьПоПредставлению(НаправлениеСортировки.Убыв); 0,1789 5,79 1,101879 6,73 2,400442 7,33
КонецЕсли; 0,027553 0,89 0,134654 0,82 0,271737 0,83
Значение = Данные[ИндексПоследнегоЭлемента].Значение; 0,069322 2,24 0,344562 2,10 0,690922 2,11
Данные.Удалить(ИндексПоследнегоЭлемента); 0,159925 5,18 0,774589 4,73 1,612728 4,92
Возврат Очередь.Данные.Количество() = 0; 0,115169 3,73 0,622147 3,80 1,163592 3,55
             
Итого 3,089687 100,00 16,374042 100,00 32,767891 100,00

 

Важное замечание - метод сортировки во всех случаях запускался 1 раз. Сначала набиралась очередь до нужного количества элементов (10 000, 50 000 или 100 000), а потом при при первом получении происходила сортировка. Как видим, что сортировка занимает не мало времени.

У списка значений большую часть времени зняло вычисление проиоритета - перевода чисел в строку. При тестировнии я не указывал разрядность и она по умолчанию была 16, т.е. длина сортировочной строки была 32 символа (16 приоритет и 16 позиция в очереди). В тестируемых примерах я мог указать разрядность 6 и тогда сортировочная строка была бы 12 символов, что, в свою очередь, должно положительно сказаться на сортировке (а может еще и на вычислении приоритетной строки).

 

ПС: тесты проводились на платформе 1С 8.3.10 в файловом режиме и на процессоре Core 2 Duo 2,33GHz. И соответственно, при тестировании на другом компьютере чистое время будет другим, но процентное соотношение должно остаться прежним.

ПСС: Конструктивная критика приветствуется.

Обновлено: избавился в коде от конструкции Попытка - Исключение. Считаю, что проверка на пустую коллекцию лишняя, потому как у каждой структуры данных есть метод Пустой(), которым и должен пользоваться разработчик.

 

51

Специальные предложения

Лучшие комментарии
31. herfis 283 25.06.19 09:35 Сейчас в теме
По классике, приоритетная очередь реализуется на двоичном дереве, уложенном в непрерывный участок памяти (обычный массив) и не требует явной сортировки. Операции добавления и удаления элементов в него осуществляются путем "всплытия" и "погружения" элементов дерева, которые выполняются за O(log N) и при этом как бы автоматически сохраняется нужный порядок элементов. Т.н. сортирующее дерево. Как красно-черное дерево, только намного проще в реализации за счет того, что и требования к приоритетной очереди более простые. И в этом прелесть этой структуры данных. С одной стороны - она относительно простая. С другой - чрезвычайно эффективна по производительности и ресурсам.
Krio2; new_user; for_sale; RonX01; +4 Ответить
36. herfis 283 25.06.19 13:29 Сейчас в теме
В общем, таки не поленился сделать простейшую реализацию на 1С :) Прелесть этой структуры данных еще в том, что можно сделать очередь фиксированного размера и прогонять через нее ЛЮБЫЕ объемы данных. И она всегда будет содержать ТОП 100 элементов (для убывающей очереди в 100 элементов), не падая в производительности и не потребляя больше ресурсов. Чаще всего для подобных алгоритмов ее и используют.
&НаКлиенте
Перем ПриоритетнаяОчередь;

&НаКлиенте
Функция ДобавитьЭлемент(Элемент)
	ПриоритетнаяОчередь.Добавить(Элемент);
	Всплытие(ПриоритетнаяОчередь.Количество() - 1);
КонецФункции

&НаКлиенте
Функция ИзвлечьМаксимум()
	Максимум = ПриоритетнаяОчередь[1];
	ИндексПоследнегоЭлемента = ПриоритетнаяОчередь.Количество() - 1;
	Рокировка(1, ИндексПоследнегоЭлемента);
	ПриоритетнаяОчередь.Удалить(ИндексПоследнегоЭлемента);
	Погружение(1);
	Возврат Максимум;
КонецФункции

&НаКлиенте
Процедура Всплытие(Знач ИндексЭлемента)
	Пока ИндексЭлемента > 1 И ПриоритетнаяОчередь[Цел(ИндексЭлемента / 2)] < ПриоритетнаяОчередь[ИндексЭлемента] Цикл
		ИндексРодительскогоЭлемента = Цел(ИндексЭлемента / 2);
		Рокировка(ИндексЭлемента, ИндексРодительскогоЭлемента);
		ИндексЭлемента = ИндексРодительскогоЭлемента;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура Погружение(Знач ИндексЭлемента)
	ИндексПоследнегоЭлемента = ПриоритетнаяОчередь.Количество() - 1;
	Пока ИндексЭлемента*2 <= ИндексПоследнегоЭлемента Цикл
		ИндексПервогоДочернегоЭлемента = ИндексЭлемента*2;
		ИндексВторогоДочернегоЭлемента = ИндексПервогоДочернегоЭлемента + 1;
		ИндексДочернегоЭлементаДляПогружения = ИндексПервогоДочернегоЭлемента;
		Если ИндексДочернегоЭлементаДляПогружения < ИндексПоследнегоЭлемента И ПриоритетнаяОчередь[ИндексВторогоДочернегоЭлемента] > ПриоритетнаяОчередь[ИндексПервогоДочернегоЭлемента] Тогда
			ИндексДочернегоЭлементаДляПогружения = ИндексВторогоДочернегоЭлемента;
		КонецЕсли;
		Если ПриоритетнаяОчередь[ИндексЭлемента] < ПриоритетнаяОчередь[ИндексДочернегоЭлементаДляПогружения] Тогда
			Рокировка(ИндексЭлемента, ИндексДочернегоЭлементаДляПогружения);
			ИндексЭлемента = ИндексДочернегоЭлементаДляПогружения;
		Иначе
			//погружение не требуется
			Прервать;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура Рокировка(ИндексПервогоЭлемента, ИндексВторогоЭлемента)
	ПервыйЭлемент = ПриоритетнаяОчередь[ИндексПервогоЭлемента];
	ПриоритетнаяОчередь[ИндексПервогоЭлемента] = ПриоритетнаяОчередь[ИндексВторогоЭлемента];
	ПриоритетнаяОчередь[ИндексВторогоЭлемента] = ПервыйЭлемент;
КонецПроцедуры

&НаКлиенте
Процедура Опустошение()
	Для ИндексЭлемента = 1 По ПриоритетнаяОчередь.Количество() - 1 Цикл
		Сообщить(ИзвлечьМаксимум());
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ДемоИнициализация()
	ПриоритетнаяОчередь.Очистить();
	ПриоритетнаяОчередь.Добавить(0);
	ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
	Для НомерЭлемента = 1 По 30 Цикл
		СЧ = ГСЧ.СлучайноеЧисло(0, 100);
		Сообщить(СЧ);
		ДобавитьЭлемент(СЧ);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура Тест(Команда)
	Сообщить("Инициализация");
	ДемоИнициализация();
	Сообщить("Опустошение");
	Опустошение();
КонецПроцедуры

ПриоритетнаяОчередь = Новый Массив;
Показать
Krio2; beefit; for_sale; RonX01; +4 Ответить
37. herfis 283 25.06.19 13:48 Сейчас в теме
Еще одна прикольная особенность такой реализации - расходы на "сортировку" делятся между помещением элемента в очередь и извлечением элемента из очереди. Каждый момент времени гарантируется только, что корневой элемент является максимальным/минимальным. Чтобы получить всю последовательность в отсортированном виде необходимо выполнить процедуру по извлечению всех элементов из очереди (с соответствующей перестройкой дерева в процессе).
for_sale; RonX01; +2 Ответить
45. Alias 153 26.06.19 15:34 Сейчас в теме
(36)
Объясните мне, пожалуйста, ведь это Вы явно не двоичное дерево организовали, верно? Это всё тот же массив. Просто после добавления элемента Вы начинаете всплывать, погружаться и рокироваться элементами чтобы он занял более-менее правильную позицию (первый всегда правильный)?

Но в наше время это называлось просто "методом половинного деления", и выглядело как-то попроще. Вместо погружений-всплытий-рокировок для этого было бы достаточно одной функции, которая будет возвращать номер позиции, куда нужно поместить новый элемент. Как-то так:
&НаКлиенте
Функция НайтиКудаВставлять(ЧтоВставлять, Очередь, Начиная, Заканчивая)
	Если Начиная=Заканчивая Тогда
		Ответ = Начиная
	Иначе
		Проверяем = Окр((Начиная+Заканчивая)/2, 0, 0);
		Если Проверяем=Заканчивая Тогда
			Ответ = Заканчивая; // уже ясно что новый в конец
		ИначеЕсли Очередь[Проверяем]<ЧтоВставлять Тогда // с начала
			Ответ = НайтиКудаВставлять(ЧтоВставлять, Очередь, Начиная, Проверяем);
		Иначе // до конца
			Ответ = НайтиКудаВставлять(ЧтоВставлять, Очередь, Проверяем+1, Заканчивая);
		КонецЕсли;
	КонецЕсли;
	Возврат Ответ
КонецФункции
Показать


Смотрите, я сделал обработку, в которой есть как Ваш метод, так и мой, более простой. На 100 элементов Ваш тратит 115 мс на инициализацию и 458 на опустошение (всего 673). Мой, в тех же условиях, 406 на инициализацию и только 6 на опустошение (всего 412). То есть на треть меньше -- и эта закономерность сохраняется с увеличением количества элементов. При этом также, в каждый момент времени гарантируется то что корневой является максимальным. Но кроме того бонусом ещё и то что остальные все сразу упорядочены.

Вопрос -- зачем тогда сложности? Только ради быстрой инициализации -- в каких-то системах возможно и имеет смысл (ценой общего увеличения времени!). Но для 1С, если смотреть на общее количество кода и общее время выполнения -- лучше как проще и быстрее.
Прикрепленные файлы:
ТестПриоритетнаяОчередь.epf
chng; new_user; +2 Ответить
46. herfis 283 26.06.19 16:17 Сейчас в теме
(45)
ведь это Вы явно не двоичное дерево организовали, верно? Это всё тот же массив.

Нет, это именно двоичное дерево, несмотря на то, что оно в массиве :)
"Всплытие" и "погружение" элементов происходит именно "по дереву", между дочерними и родительскими элементами.
Ессно в 1С это решение не претендует на эффективность. Это просто модель "настоящей" низкоуровневой реализации priority queue, выполненная средствами 1С. Я поэтому и писал в (30) и продублирую здесь:
priority queue - моя любимая структура данных по изяществу и эффективности.
К сожалению, в 1С возможно реализовать лишь модели такого рода структур. Вся прелесть эффективности их реализации недоступна в 1С.
Остальные комментарии
Избранное Подписка Сортировка: Древо
1. ArchLord42 68 24.06.19 13:20 Сейчас в теме
        Попытка
		Значение = Стек[ИндексПоследнегоЭлемента];
		Стек.Удалить(ИндексПоследнегоЭлемента);
		Возврат Значение;
	Исключение
		Возврат Неопределено;
	КонецПопытки;
Показать


тут (и в других методах) не так сложно проверить количество элементов в массиве, зачем все эти попытки \ исключения ? code smells в общем
taiwanchik; for_sale; imushov; TODD22; boln; +5 Ответить
6. RonX01 201 24.06.19 13:57 Сейчас в теме
(1) Страсть как захотелось использовать здесь попытку вместо условия. Кому code smells используйте так:
	Если Стек_Пустой(Стек) Тогда
		Возврат Неопределено;
	Иначе
		ИндексПоследнегоЭлемента = Стек.ВГраница();
		Значение = Стек[ИндексПоследнегоЭлемента];
		Стек.Удалить(ИндексПоследнегоЭлемента);
		Возврат Значение;
	КонецЕсли;
Показать
7. TODD22 18 24.06.19 14:16 Сейчас в теме
(6)
Страсть как захотелось использовать здесь попытку вместо условия.

В 1С не рекомендуется в общем случае перехватывать исключения.
Rustig; boln; +2 Ответить
8. RonX01 201 24.06.19 14:27 Сейчас в теме
(7) Не знал, спасибо. Теперь страсть свою поумерю.
21. for_sale 783 24.06.19 21:14 Сейчас в теме
9. for_sale 783 24.06.19 17:19 Сейчас в теме
(6)
Страсть чем-то объясняется или просто "страсть"?)

Ещё момент - Неопределено теоретически может быть правильным значением элемента. Т.е. Неопределено и "Такого элемента не существует" будут разными случаями.
12. RonX01 201 24.06.19 20:38 Сейчас в теме
(9) Я думал по поводу Неопределено, можно возвращать NULL, но это также теоретически может быть правильным значением.
Вообще эти структуры данных используют программисты, а не пользователи, поэтому мне кажется, что проверки на пустую структуру данных внутри методов _Получить() излишни. Для проверки предполагается использовать метод _Пустой(), который возвращает вполне себе однозначный ответ :)

Здесь "страсть" объясняется тем, что с одной стороны мне не нравится проверка на пустую структуру данных внутри методов, а с другой стороны нужно предусмотреть появление ошибки, не нагромаждая код. Хотелось сделать как можно меньше кода.
13. for_sale 783 24.06.19 20:40 Сейчас в теме
(12)
Я думал по поводу Неопределено, можно возвращать NULL, но это также теоретически может быть правильным значением.

Я думаю, тут можно просто разделить сущности. Т.е. возвращаемое значение - это возвращаемое значение, а сама функция возвращает (или устанавливает переданный) флаг того, что что-то было найдено или ничего не было найдено.
19. RonX01 201 24.06.19 21:04 Сейчас в теме
22. for_sale 783 24.06.19 21:15 Сейчас в теме
(19)
Функция Стек_ВзятьБезУдаления(Стек, Значение)
	
	Если _СтекПустой() Тогда
		Возврат Ложь;
	Иначе
Значение = Стек[ИндексПоследнегоЭлемента];
Возврат Истина;
	КонецЕсли;
КонецФункции

Значение = "";
Если Стек_ВзятьБезУдаления(Стек, Значение) Тогда
// значение можно использовать
Иначе
// ничё нет
КонецЕсли;
Показать


Или наоборот:

Функция Стек_ВзятьБезУдаления(Стек, ЕстьЗначение = Истина)
	
	Если _СтекПустой() Тогда
		ЕстьЗначение = Ложь;
	Иначе
ЕстьЗначение = Истина;
Возврат  Стек[ИндексПоследнегоЭлемента];
	КонецЕсли;
КонецФункции

// если у меня могут быть Неопределено как значения, тогда
ЕстьЗнч = Ложь;
Если Стек_Взять(Стек, ЕстьЗнч) Тогда
КонецЕсли;

// если немогут или неважно
Знч = Стек_Взять(Стек);
Показать
oleganatolievich; PLAstic; RonX01; +3 Ответить
23. RonX01 201 24.06.19 21:23 Сейчас в теме
(22) Понял, получается 2 в одном. Почему бы и нет.
24. leemuar 25.06.19 01:11 Сейчас в теме
(23) попытка получить значение из пустой коллекции всегда должна бросать исключение. Любое значение встроенного языка может храниться в коллекции, поэтому не допустимо использовать «особое» возвращаемое значение как признак невозможности получения жначения

для проверки стека и организации цикла стеку необходим метод, возвращающий количество элементов в нем:

Пока Стек.Количество() > 0 Цикл
    //
КонецЦикла 

Пока Не Стек.Пустой() > 0 Цикл
    //
КонецЦикла 
Показать


p.s. Подумайте на досуге, а так ли нужна вообще операция получения без удаления (peek)? Когда вы ею последний раз пользовались и зачем?
ltfriend; RonX01; +2 Ответить
27. RonX01 201 25.06.19 07:29 Сейчас в теме
(24) Совсем недавно использовал операцию без удаления из приоритетной очереди. Необходимо было найти вершину графа, которая ближе всех расположена к углу (по оси х и у). Обход вершин графа с правильным вычислением приоритетов дал результат и вконце требовалось только получить один элемент с наивысшим приоритетом. Поэтому использовал получить без удаления, хотя мог использовать и с удалением. Выигрыш конечно микро секунды, но все же.
Думаю могут быть ситуации, когда это будет полезно.
Perfolenta; leemuar; +2 Ответить
40. ltfriend 408 25.06.19 19:43 Сейчас в теме
(22) Лучше ни каких проверок не делать. Пусть возникает исключение, а программист должен сам его обрабатывать на своё усмотрение. Тогда получиться так:
Функция Стек_ВзятьБезУдаления(Стек)
   
    Возврат Стек[ИндексПоследнегоЭлемента];

КонецФункции

Попытка
    Значение = Стек_ВзятьБезУдаления(Стек)
Исключение
    // Обработка по своим требованиям
КонецПопытки;
Показать
41. for_sale 783 25.06.19 20:23 Сейчас в теме
(40)
Кому лучше?
Тем более, мы рассматриваем ситуацию, когда Неопределено может быть значением. У вас, по-моему, другая ситуация описывается.
42. RonX01 201 26.06.19 06:02 Сейчас в теме
(40) Я уже убрал в статье какие либо проверки. В данном случае считается, что программист сам решает как ему обработать исключение, либо вообще не допустит такой ситуации. Есть функция Пустой()
11. MikeI 72 24.06.19 20:37 Сейчас в теме
(6)Дурацкий вопрос: Если заменить Стек.ВГраница(), на Стек.Количество()-1. Шустрее не будет?

Или вообще не использовать метод Количество() для подсчета элементов в очереди, а Один раз посчитать, а потом уменьшать это число на единицу
14. RonX01 201 24.06.19 20:45 Сейчас в теме
(11) Вопрос, кстати не дурацкий, я им сам задавался :). Стек.Количество()-1 будет медленней.
15. MikeI 72 24.06.19 20:47 Сейчас в теме
(14)тогда в методах Пустая нужно использовать Стек.Вграница()+1
16. MikeI 72 24.06.19 20:49 Сейчас в теме
(15)Но ИМХО , когда в 1С стали приходить true программеры с ООП, то стало конфы стали тормознее, заморочитей, менее логичны и сложны для отладки. ))))
Irwin; Perfolenta; tsukanov; +3 Ответить
18. RonX01 201 24.06.19 21:03 Сейчас в теме
(16) Согласен. с ООП тоже есть проблемы, и часто всё превращается в лапшу.
Поэтому "Простота требует проектирования и хорошего вкуса" Линус Торвальдс.
17. RonX01 201 24.06.19 20:55 Сейчас в теме
(15) Стек.Количество() = 0; будет работать чуть-чуть быстрее нежели Стек.ВГраница() = -1; Почему-то
25. kuzyara 797 25.06.19 06:23 Сейчас в теме
(6)
code smells

Guard clauses
мб так?

    Если Стек_Пустой(Стек) Тогда
        Возврат Неопределено;
    КонецЕсли;
    ИндексПоследнегоЭлемента = Стек.ВГраница();
    Значение = Стек[ИндексПоследнегоЭлемента];
    Стек.Удалить(ИндексПоследнегоЭлемента);
    Возврат Значение;


https://softwareengineering.stackexchange.com/questions/350472/developer-insists-if-statements-shouldnt-have-negated-conditions-and-should-al
26. RonX01 201 25.06.19 07:09 Сейчас в теме
36. herfis 283 25.06.19 13:29 Сейчас в теме
В общем, таки не поленился сделать простейшую реализацию на 1С :) Прелесть этой структуры данных еще в том, что можно сделать очередь фиксированного размера и прогонять через нее ЛЮБЫЕ объемы данных. И она всегда будет содержать ТОП 100 элементов (для убывающей очереди в 100 элементов), не падая в производительности и не потребляя больше ресурсов. Чаще всего для подобных алгоритмов ее и используют.
&НаКлиенте
Перем ПриоритетнаяОчередь;

&НаКлиенте
Функция ДобавитьЭлемент(Элемент)
	ПриоритетнаяОчередь.Добавить(Элемент);
	Всплытие(ПриоритетнаяОчередь.Количество() - 1);
КонецФункции

&НаКлиенте
Функция ИзвлечьМаксимум()
	Максимум = ПриоритетнаяОчередь[1];
	ИндексПоследнегоЭлемента = ПриоритетнаяОчередь.Количество() - 1;
	Рокировка(1, ИндексПоследнегоЭлемента);
	ПриоритетнаяОчередь.Удалить(ИндексПоследнегоЭлемента);
	Погружение(1);
	Возврат Максимум;
КонецФункции

&НаКлиенте
Процедура Всплытие(Знач ИндексЭлемента)
	Пока ИндексЭлемента > 1 И ПриоритетнаяОчередь[Цел(ИндексЭлемента / 2)] < ПриоритетнаяОчередь[ИндексЭлемента] Цикл
		ИндексРодительскогоЭлемента = Цел(ИндексЭлемента / 2);
		Рокировка(ИндексЭлемента, ИндексРодительскогоЭлемента);
		ИндексЭлемента = ИндексРодительскогоЭлемента;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура Погружение(Знач ИндексЭлемента)
	ИндексПоследнегоЭлемента = ПриоритетнаяОчередь.Количество() - 1;
	Пока ИндексЭлемента*2 <= ИндексПоследнегоЭлемента Цикл
		ИндексПервогоДочернегоЭлемента = ИндексЭлемента*2;
		ИндексВторогоДочернегоЭлемента = ИндексПервогоДочернегоЭлемента + 1;
		ИндексДочернегоЭлементаДляПогружения = ИндексПервогоДочернегоЭлемента;
		Если ИндексДочернегоЭлементаДляПогружения < ИндексПоследнегоЭлемента И ПриоритетнаяОчередь[ИндексВторогоДочернегоЭлемента] > ПриоритетнаяОчередь[ИндексПервогоДочернегоЭлемента] Тогда
			ИндексДочернегоЭлементаДляПогружения = ИндексВторогоДочернегоЭлемента;
		КонецЕсли;
		Если ПриоритетнаяОчередь[ИндексЭлемента] < ПриоритетнаяОчередь[ИндексДочернегоЭлементаДляПогружения] Тогда
			Рокировка(ИндексЭлемента, ИндексДочернегоЭлементаДляПогружения);
			ИндексЭлемента = ИндексДочернегоЭлементаДляПогружения;
		Иначе
			//погружение не требуется
			Прервать;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура Рокировка(ИндексПервогоЭлемента, ИндексВторогоЭлемента)
	ПервыйЭлемент = ПриоритетнаяОчередь[ИндексПервогоЭлемента];
	ПриоритетнаяОчередь[ИндексПервогоЭлемента] = ПриоритетнаяОчередь[ИндексВторогоЭлемента];
	ПриоритетнаяОчередь[ИндексВторогоЭлемента] = ПервыйЭлемент;
КонецПроцедуры

&НаКлиенте
Процедура Опустошение()
	Для ИндексЭлемента = 1 По ПриоритетнаяОчередь.Количество() - 1 Цикл
		Сообщить(ИзвлечьМаксимум());
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ДемоИнициализация()
	ПриоритетнаяОчередь.Очистить();
	ПриоритетнаяОчередь.Добавить(0);
	ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
	Для НомерЭлемента = 1 По 30 Цикл
		СЧ = ГСЧ.СлучайноеЧисло(0, 100);
		Сообщить(СЧ);
		ДобавитьЭлемент(СЧ);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура Тест(Команда)
	Сообщить("Инициализация");
	ДемоИнициализация();
	Сообщить("Опустошение");
	Опустошение();
КонецПроцедуры

ПриоритетнаяОчередь = Новый Массив;
Показать
Krio2; beefit; for_sale; RonX01; +4 Ответить
43. RonX01 201 26.06.19 06:09 Сейчас в теме
(36) Огромное спасибо за реализацию. Одно дело понимать теорию, а другое реализовать, да еще и в 1с :)
44. herfis 283 26.06.19 09:36 Сейчас в теме
(43) Не за что. Самому было интересно :) Я практически один к одному передрал ключевые моменты принстонской реализации https://algs4.cs.princeton.edu/24pq/MaxPQ.java.html из их книжки по алгоритмам.
45. Alias 153 26.06.19 15:34 Сейчас в теме
(36)
Объясните мне, пожалуйста, ведь это Вы явно не двоичное дерево организовали, верно? Это всё тот же массив. Просто после добавления элемента Вы начинаете всплывать, погружаться и рокироваться элементами чтобы он занял более-менее правильную позицию (первый всегда правильный)?

Но в наше время это называлось просто "методом половинного деления", и выглядело как-то попроще. Вместо погружений-всплытий-рокировок для этого было бы достаточно одной функции, которая будет возвращать номер позиции, куда нужно поместить новый элемент. Как-то так:
&НаКлиенте
Функция НайтиКудаВставлять(ЧтоВставлять, Очередь, Начиная, Заканчивая)
	Если Начиная=Заканчивая Тогда
		Ответ = Начиная
	Иначе
		Проверяем = Окр((Начиная+Заканчивая)/2, 0, 0);
		Если Проверяем=Заканчивая Тогда
			Ответ = Заканчивая; // уже ясно что новый в конец
		ИначеЕсли Очередь[Проверяем]<ЧтоВставлять Тогда // с начала
			Ответ = НайтиКудаВставлять(ЧтоВставлять, Очередь, Начиная, Проверяем);
		Иначе // до конца
			Ответ = НайтиКудаВставлять(ЧтоВставлять, Очередь, Проверяем+1, Заканчивая);
		КонецЕсли;
	КонецЕсли;
	Возврат Ответ
КонецФункции
Показать


Смотрите, я сделал обработку, в которой есть как Ваш метод, так и мой, более простой. На 100 элементов Ваш тратит 115 мс на инициализацию и 458 на опустошение (всего 673). Мой, в тех же условиях, 406 на инициализацию и только 6 на опустошение (всего 412). То есть на треть меньше -- и эта закономерность сохраняется с увеличением количества элементов. При этом также, в каждый момент времени гарантируется то что корневой является максимальным. Но кроме того бонусом ещё и то что остальные все сразу упорядочены.

Вопрос -- зачем тогда сложности? Только ради быстрой инициализации -- в каких-то системах возможно и имеет смысл (ценой общего увеличения времени!). Но для 1С, если смотреть на общее количество кода и общее время выполнения -- лучше как проще и быстрее.
Прикрепленные файлы:
ТестПриоритетнаяОчередь.epf
chng; new_user; +2 Ответить
46. herfis 283 26.06.19 16:17 Сейчас в теме
(45)
ведь это Вы явно не двоичное дерево организовали, верно? Это всё тот же массив.

Нет, это именно двоичное дерево, несмотря на то, что оно в массиве :)
"Всплытие" и "погружение" элементов происходит именно "по дереву", между дочерними и родительскими элементами.
Ессно в 1С это решение не претендует на эффективность. Это просто модель "настоящей" низкоуровневой реализации priority queue, выполненная средствами 1С. Я поэтому и писал в (30) и продублирую здесь:
priority queue - моя любимая структура данных по изяществу и эффективности.
К сожалению, в 1С возможно реализовать лишь модели такого рода структур. Вся прелесть эффективности их реализации недоступна в 1С.
47. Alias 153 26.06.19 16:33 Сейчас в теме
(46)
>"Всплытие" и "погружение" элементов происходит именно "по дереву", между дочерними и родительскими элементами.
Ну что ж, попробую разобраться повнимательнее -- в механизме отображения дерева на массив... возможно, будет интересно. А то когда я вижу в коде Цел(ИндексЭлемента/2), я вижу обычное половинное деление, даже если назвать переменную ИндексРодительскогоЭлемента :) в дереве всё же наполнение веток может быть сильно неравномерным, да и связи где-то должны храниться (или хотя бы неизменно определяться). А тут мы всё время середину интервала берём.
Но мой код всё равно короче и в общем быстрее :)
48. herfis 283 26.06.19 18:01 Сейчас в теме
(47) Здесь не середина интервала берется. Здесь вычисляется адрес дочерних/родительских элементов умножением/делением на 2. Проще всего разобраться с бумажкой и ручкой. 1 2 3 - 2 и 3 это листья 1. 1 2 3 4 5 6 7 - 4 и 5 - это листья 2, а 6 и 7 - это листья у 3 и так далее.
Но мой код всё равно короче и в общем быстрее :)

Нашли чем хвастаться :) А если использовать встроенную сортировку списка значений, то может получиться еще быстрее чем половинным делением на определенном размере очереди.
1С - это тормознутый скриптовый язык без низкоуровневых примитивов. Оптимизация на нем как правило упирается не в знание базовых алгоритмов, а в эффективное использование библиотечного функционала.
Даже массив в 1С - это достаточно высокоуровневая динамическая структура данных под капотом. Оригинальный алгоритм priority queue строится поверх неизменяемых массивов (фактически просто непрерывных кусков памяти) и оптимизирован под минимальное количество перестановок и копирований. Реализовывать ее с помощью динамического массива - это уже смешно. Эти алгоритмы и структуры данных как раз и составляют "потроха" реализации библиотечной функциональности высокоуровневых языков.
Alias; RonX01; +2 Ответить
49. RonX01 201 27.06.19 06:43 Сейчас в теме
(45) Вот здесь в пункте 4 "Массив и двоичное дерево" можете более детально посмотреть как на массиве отобразить двоичное дерево
2. VmvLer 24.06.19 13:32 Сейчас в теме
не понятно, что делать с этим кодом в практическом плане.
возможно его стоит предложить старшему воспитателю группы детского сада
"1С: пупс"
3. vadim1011985 71 24.06.19 13:44 Сейчас в теме
(2) При желании можно найти применение , например с помощью стека проверяют соответствие открывающихся и закрывающихся скобок (или тех же кавычек) в выражениях. В любом случае это полезные структуры
Rustig; CyberCerber; for_sale; Perfolenta; RonX01; boln; +6 Ответить
51. ValeriVP 1016 27.06.19 14:54 Сейчас в теме
(3)
соответствие открывающихся и закрывающихся скобок (или тех же кавычек)

это легче проверить по количеству символов - четность для кавычек, равенство для скобок
52. vadim1011985 71 27.06.19 15:23 Сейчас в теме
53. vadim1011985 71 27.06.19 15:25 Сейчас в теме
(51) В приведенном примере количество скобок четное , но для [ нет закрывающей скобки , так что по количеству не проверишь
54. ValeriVP 1016 27.06.19 16:55 Сейчас в теме
(53) странный пример
((([(((([)))))
((((((( 7
[[ 2
))))) 5

7 <> 5 для ()
2 <> 0 для []
т.е. по количеству проверяется элементарно

Другое дело, что со строкой типа ([)] есть некоторые проблемы. Но все то же самое - считаем количество квадратных скобок между круглых скобок - получаем не сходимость.
new_user; +1 Ответить
55. vadim1011985 71 27.06.19 18:11 Сейчас в теме
(54) Со стеком проще гораздо , просто если будут [({)]} т.е. 3 вида скобок как тогда измениться ваш способ ? А при стеке - изменения минимальный. Поэтому стек в данном случае удобнее
58. ValeriVP 1016 28.06.19 13:03 Сейчас в теме
(55) я задачу разбора такой строки решал бы рекурсией
60. RonX01 201 28.06.19 13:48 Сейчас в теме
(58) Кстати, использование стека - это один из способов избавления от рекурсии :).
56. RonX01 201 28.06.19 06:33 Сейчас в теме
(54) Со стеком это решается так - кладем в стек только открывающие скобки, а когда встречается закрывающая, то берем из стека и смотрим соответствие вида скобки.
Вконце стек должен быть пустым, т.е. в стеке не должно остаться открывающих скобок. Так же, если встречается закрывающая скобка, а стек пустой, то тоже ошибка.
Мне кажется здесь проще и надежнее использовать стек, нежели подсчет скобок.
57. ValeriVP 1016 28.06.19 10:23 Сейчас в теме
(56)а кавычки? Когда класть и забирать?
Я решал задачу разбора файлов 1С с фигурными скобками и кавычками - решение получилось без стека.

Т.о. практического применения описанных механизмов не понимаю, хотя и не отрицаю возможность применения.
Но как я уже говорил - это частные задачи и они требуют индивидуального подхода.
new_user; +1 Ответить
59. RonX01 201 28.06.19 13:37 Сейчас в теме
(57) Если есть открывающая и закрывающая («»), то можно также. А можно с помощью состояний или флага.
Мне больше нравится состояние, получится конечный автомат. Встретилась кавычка - кладем ее в стек и переходим в состояние, например ЦИТАТА. Когда в этом состоянии еще раз встретилась кавычка - берем из стека и переходим в прежнее состояние. В состоянии ЦИТАТА можно, например, не считать скобки, все зависит от поставленной задачи.
4. boln 999 24.06.19 13:47 Сейчас в теме
(2)
не понятно, что делать с этим кодом в практическом плане.
возможно его стоит предложить старшему воспитателю группы детского сада
Я, например, использую стек для организации последовательности завершения вложенных асинхронных процедур:
https://www.1c-uc3.ru/modal.html
Rustig; mvxyz; RonX01; +3 Ответить
5. VmvLer 24.06.19 13:56 Сейчас в теме
(4) я имел ввиду
этот код
, то что многие используют подобные алгоритмы я не сомневаюсь.
63. RonX01 201 10.07.19 11:37 Сейчас в теме
(5) вот здесь https://infostart.ru/public/1088569/ примеры практического применение этого кода (очередь и приоритетная очередь)
10. acsent 1138 24.06.19 18:20 Сейчас в теме
а если сделать раелизацию на списке.
те на структуре, где один из элементов - другая структура?
20. RonX01 201 24.06.19 21:11 Сейчас в теме
(10) Тогда необходимо подумать что будет ключами структуры? И для получения первого элемента необходимо вызывать конструкцию типа Для каждого Из Цикл. Мне кажется это будет затратно по времени, но надо тестить.
39. acsent 1138 25.06.19 18:12 Сейчас в теме
(20) ссылку на последний можно хранить в первом.
Если эта куча то вообще ни чего этого не нужно
28. Scorpion4eg 251 25.06.19 07:54 Сейчас в теме
Хорошая статья. Твою бы статью, да когда я LRU кэш организовывал...
Получилась очень сложная конструкция из таблицы значение, соответствия и пары параметров. Зато без проблем кэширую http запросы с контролем памяти.
29. RonX01 201 25.06.19 08:54 Сейчас в теме
30. herfis 283 25.06.19 09:06 Сейчас в теме
priority queue - моя любимая структура данных по изяществу и эффективности.
К сожалению, в 1С возможно реализовать лишь модели такого рода структур. Вся прелесть эффективности их реализации недоступна в 1С.
31. herfis 283 25.06.19 09:35 Сейчас в теме
По классике, приоритетная очередь реализуется на двоичном дереве, уложенном в непрерывный участок памяти (обычный массив) и не требует явной сортировки. Операции добавления и удаления элементов в него осуществляются путем "всплытия" и "погружения" элементов дерева, которые выполняются за O(log N) и при этом как бы автоматически сохраняется нужный порядок элементов. Т.н. сортирующее дерево. Как красно-черное дерево, только намного проще в реализации за счет того, что и требования к приоритетной очереди более простые. И в этом прелесть этой структуры данных. С одной стороны - она относительно простая. С другой - чрезвычайно эффективна по производительности и ресурсам.
Krio2; new_user; for_sale; RonX01; +4 Ответить
32. RonX01 201 25.06.19 10:01 Сейчас в теме
(31) Вначале статьи я указал, что буду использовать готовые типы данных 1с. Как бы намекая на то, что не буду пытаться реализовывать кучи для приоритетной очереди :). Хотя мне очень интересно посмотреть реализацию "по классике" в 1с.
33. herfis 283 25.06.19 10:26 Сейчас в теме
(32) На массиве делается вполне аутентично. Но вот эффективность может хромать вследствие тормознутости 1С как скриптового языка (вполне может оказаться, что использование библиотечной сортировки на больших коллекциях более эффективно, чем "ручные" операции на массиве, несмотря на O(log N)).
34. herfis 283 25.06.19 10:30 Сейчас в теме
(32) Вот тут глянь в самом начале: http://ti.math.msu.su/wiki/lib/exe/fetch.php?media=algo:algo-13.pdf
Там все очень просто и красиво.
35. RonX01 201 25.06.19 11:14 Сейчас в теме
37. herfis 283 25.06.19 13:48 Сейчас в теме
Еще одна прикольная особенность такой реализации - расходы на "сортировку" делятся между помещением элемента в очередь и извлечением элемента из очереди. Каждый момент времени гарантируется только, что корневой элемент является максимальным/минимальным. Чтобы получить всю последовательность в отсортированном виде необходимо выполнить процедуру по извлечению всех элементов из очереди (с соответствующей перестройкой дерева в процессе).
for_sale; RonX01; +2 Ответить
38. comol 4075 25.06.19 15:26 Сейчас в теме
Ну спасибо! Теперь вопросы на собеседования новые выдумывать :(
50. Jimbo 6 27.06.19 12:45 Сейчас в теме
Зачем вот это вот всё ? А если на С написать тоже подобное или С++ с шаблонами STL, где всё это уже реализовано и позасекать время?
61. new_user 173 08.07.19 16:53 Сейчас в теме
62. RonX01 201 09.07.19 06:25 Сейчас в теме
(61) Ну это как посмотреть. Я считаю, что первый добавленный элемент кладется на "дно", следующий на него. Если по другому представить массив, то у него есть голова и хвост, я считаю, что новый элемент увеличивает хвост, вы же считаете, что новый элемент увеличивает голову. А слово "вставка" пусть не вводит вас в заблуждение.
new_user; +1 Ответить
Оставьте свое сообщение

См. также

Агрегатные функции СКД, о которых мало кто знает 318

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    10003    ids79    42       

Обмен данными. Консистентность vs Многопоточность 25

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Интеграция

Рассмотрим теоретические основы обмена данными. Какие бывают обмены, какие гарантии при этом даются, зачем идти на компромиссы и что при этом может пойти не так. Есть ли идеальная схема?

03.09.2019    3147    m-rv    1       

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив 242

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    10386    ids79    24       

Алгоритмы поиска пути в графе 82

Инструменты и обработки Программист Архив с данными v8 1cv8.cf Абонемент ($m) Практика программирования Разработка

Реализуем алгоритмы поиска пути в графе на платформе 1С 8.3, такие как алгоритм А*, поиск в ширину, жадный поиск, алгоритм Дейкстры и вконце волновой.

1 стартмани

09.07.2019    3453    8    RonX01    10       

Выгрузка документа по условию 5

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Разработка

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

25.04.2019    4824    m-rv    2       

Как настроить правильную техподдержку (helpdesk, service desk на коленке) 38

Статья Программист Бизнес-аналитик Руководитель проекта Нет файла v8 УУ Управление взаимоотношениями с клиентами (СRM) Документооборот и делопроизводство Монитор заказов Учет рабочего времени Бесплатно (free) Управление услугами и сервисом

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

24.04.2019    7193    siddy    0       

Как прикрутить ГУИД к регистру сведений 23

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8 Разработка

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

16.04.2019    7358    m-rv    16       

Копирование числовых ячеек из 1С в Excel 26

Статья Системный администратор Программист Нет файла v8 1cv8.cf Windows Бесплатно (free) Загрузка и выгрузка в Excel Администрирование данных 1С

Решение проблемы, когда значения скопированных ячеек из табличных документов 1С в Excel воспринимаются последним как текст, т.е. без дополнительного форматирования значений невозможно применить арифметические операции. Поводом для публикации послужило понимание того, что целое предприятие с более сотней активных пользователей уже на протяжении года мучилось с такой, казалось бы на первый взгляд, тривиальной проблемой. Варианты решения, предложенные специалистами helpdesk, обслуживающими данное предприятие, а так же многочисленные обсуждения на форумах, только подтвердили убеждение в необходимости описания способа, который позволил мне качественно и быстро справиться с ситуацией.

15.01.2019    10435    itriot11    21       

Универсальные функции ЗУП 3.1 / ЗКГУ 3.1, которые помогут в разработке 464

Статья Программист Нет файла v8 v8::СПР ЗКГУ3.0 ЗУП3.x БУ Зарплата Управление персоналом (HRM) Бесплатно (free) Универсальные функции

В статье размещен список стандартных процедур и функций с примерами, которые могут помочь при разработке (доработке) конфигураций Зарплата и управление персоналом ред. 3.1 и Зарплата и кадры государственного учреждения 3.1. Иногда бывает довольно сложно правильно получить данные или долго, поэтому лучшим вариантом будет использование стандартных процедур. Буду очень признателен, если Вы поделитесь своим опытом и предложите свои варианты стандартных процедур которые помогают в работе. Или предложите, как дополнить имеющиеся процедуры.

14.11.2018    31757    GeterX    93       

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С 126

Статья Программист Нет файла v8 v8::blocking 1cv8.cf Бесплатно (free) Математика и алгоритмы Практика программирования

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    20835    ids79    40       

Git + 1С. Часть 1. Как подключиться к команде разработки и начать использовать Git 268

Статья Системный администратор Программист Нет файла v8 1cv8.cf Бесплатно (free) Инструментарий разработчика Управление проектом

Первая статья из цикла инструкций по работе с Git в 1С-разработке. Рассмотрим, как настроить рабочее место, как получить свою "копию" проекта для разработки и приступить к полезным действиям. Все примеры будут изложены в рамках трёх практических кейсов: 1. Моя команда дорабатывает типовую конфигурацию, использует приватный репозиторий на BitBucket, в котором версионируются внешние отчеты/обработки, расширения конфигураций и правила обмена; 2. Я участвую в стартап-команде, которая разрабатывает свою конфигурацию с использованием Git и GitLab; 3. Я принимаю участие в развитии OpenSource-продукта на GitHub как заинтересованный разработчик (контрибьютор).

18.10.2018    33600    stas_ganiev    72       

Вспомогательные инструкции в коде 1С 104

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    20445    tormozit    100       

Из Excel в 1С запросом 33

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Загрузка и выгрузка в Excel

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

14.08.2018    13533    m-rv    5       

Повышаем эффективность разработки правил обмена 123

Статья Программист Нет файла v8 КД ОС Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8

Как повысить скорость и качество разработки правил обмена? Как вести групповую разработку правил обмена? Как облегчить сопровождение правил обмена после передачи в эксплуатацию? Об этом и многом другом вы можете узнать из этой статьи.

25.06.2018    19306    olegtymko    47       

Как сделать запрос на изменение данных 75

Статья Программист Нет файла v8 v8::Запросы 1cv8.cf Бесплатно (free) Практика программирования

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    21176    m-rv    21       

Строим графы средствами 1С (без GraphViz) 42

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Множество статей на Инфостарте описывают, как работать с компонентой GraphViz, чтобы построить ориентированный граф. Но практически нет материалов, как работать с такими графами средствами 1С. Сегодня я расскажу, как красиво строить графы с минимальным пересечением. Нам этот метод пригодился для отрисовки алгоритмов в БИТ.Финансе, т.к. типовой механизм не устраивал. Еще это может быть полезно для визуализации различных зависимостей: расчета себестоимости, графы аффилированности компаний и т.д. Надеюсь, эта статья поможет сделать мир 1С красивее и гармоничней:) Итак, поехали...

23.05.2018    16953    slozhenikin_com    19       

Распределение расходов пропорционально продажам 9

Статья Программист Пользователь Нет файла v8 v8::ОУ УТ10 УУ Финансовый учет и бюджетирование (FRP) Учет доходов и расходов Бесплатно (free) Практика программирования

Финансовая модель. Распределение административных расходов по подразделениям пропорционально продажам за месяц. Дополнительные реквизиты против бизнес-процессов!

13.05.2018    11331    Rustig    9       

Универсальный обмен между идентичными конфигурациями через REST интерфейс OData. Часть І: Справочники 96

Статья Программист Нет файла v8 Бесплатно (free) Перенос данных из 1C8 в 1C8

Сейчас все чаще интеграции различных конфигураций проектируются через HTTP-сервисы - они и работают быстрее, и "войти" в режим отладки гораздо проще, тем самым обойдя "черный ящик" универсального обмена через xml, например. Более года назад я начал работать в компании, в которой разработчики работали с конфигурациями 1С в режиме совместимости еще 8.2.16 (менять режим совместимости в типичных базах мы не хотели) - а как Вы наверное знаете, если интересовались HTTP-сервисами в 1С, их использование в режиме совместимости 8.3.4 и ниже недопустимо - и здесь я уже не надеялся на разработку и использование HTTP-сервисов. Но позже меня заинтересовал такой "сервис" как REST интерфейс OData, так как его можно использовать не меняя режим совместимости конфигурации - именно он и стал для меня идеальным вариантом решения "нетривиальных" задач.

11.05.2018    16214    V.Stavinsky    11       

Минимализмы 3 351

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.

19.02.2018    35558    ildarovich    44       

Этюды по программированию. Взаимодействие с Microsoft Word 109

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Часто приходится заниматься созданием сложных документов Word с таблицами, вложенными фрагментами, хитрым оформлением и прочими радостями жизни. Это - попытка как-то структурировать полученный опыт, чтобы не приходилось перерывать ворох старых обработок в поисках крупиц истины. Надеюсь, эта статья будет полезна и Вам.

11.12.2017    25833    milkers    23       

Метод формирования движений в типовых регистрах нетиповыми регистраторами 31

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    21311    itriot11    34       

1С: Конвертация данных 3. Инструкции и примеры. EnterpriseData (универсальный формат обмена) 720

Статья Программист Нет файла v8 КД Бесплатно (free) Перенос данных из 1C8 в 1C8 Практика программирования Обмен через XML

Что такое КД3? Как начать использовать? Полезные дополнения к документации. Что нужно исправить в типовых обработках и конфигурации. Как изменить правила обмена не снимая конфигурацию с поддержки. Как отлаживать правила обмена?

19.11.2017    137508    MaxS    251       

Обзор имеющихся библиотек OneScript 299

Статья Системный администратор Программист Нет файла v8 Бесплатно (free) OneScript

Экосистема OneScript активно развивается. Количество пользователей данного интерпретатора и имеющихся библиотек неуклонно растет, количество решаемых проблем - тоже. Однако остро встает вопрос некоторой разобщенности и размазанности информации по имеющимся библиотекам, их функциональности и проблемам, которые они решают. Данная статья призвана навести порядок в этой теме.

14.11.2017    30796    nixel    85       

Программные перечисления, ч.2: приемы кэширования при разработке 66

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Все знают, что такое кэш, и зачем он нужен. Но в 1С разработчик обычно использует кэширование только на уровне конфигурации, а в какой-нибудь обработке скорее ломает голову над запросом - как получить все данные за один заход... Хочется рассказать о том, как можно добиться хороших результатов с стратегией "разделяй и властвуй".

30.10.2017    21054    unichkin    17       

Легкий способ обновления измененной конфигурации 41

Статья Системный администратор Программист Нет файла v8 Бесплатно (free) Инструментарий разработчика

Легкий способ обновления измененной конфигурации. Сервис подготовки расширения конфигурации

25.10.2017    18546    avk72    63       

Работа с Excel 288

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Загрузка и выгрузка в Excel

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

23.10.2017    24682    arakelyan    39       

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере 125

Статья Программист Нет файла v8 1cv8.cf Россия Бесплатно (free) Практика программирования

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    34216    tormozit    72       

Ускоряем 1С: модули с повторным использованием возвращаемых значений 136

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

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

04.09.2017    43121    m-rv    60       

Как просто запомнить алгоритм программного вывода в СКД 205

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Практика программирования

Порой нужно быстро вывести на экран таблицу значений, используя СКД \ получить данные отчета в таблицу значений.. Несмотря на очевидность алгоритма - раньше мне проще было загуглить программный вывод, благо эта инфа есть везде. Но постепенно понял как его можно быстро вспомнить, и лишний раз ничего не искать. Конечно эта статья не для Гуру :) Но я думаю - что любой неопытный в СКД программист сделает для себя небольшое открытие...

01.09.2017    41487    unichkin    15       

Как формируется GUID? 463

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

"Коллеги, есть идеи, как получить последнюю созданную характеристику? Реквизиты полностью идентичны(код, наименование, и т.п.)."(c) "Насколько я знаю, ссылка не обеспечивает последовательность, а только уникальность."(c) "Я сделал по Максимум(Ссылка). Но, чета, мне кажется, это неправильно."(c) "Слышал что в ГУИд содержится как раз время создания и по всей логике вещей сортировка по ссылке должна сортировать по моменту создания объекта"(c) Сколько раз вы слышали такие фразы? На удивление я не обнаружил информации по этой теме, пришлось разбираться самому...

16.06.2017    52371    kuzyara    55       

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

Статья Программист Нет файла v8 КД Бесплатно (free) Перенос данных из 1C8 в 1C8

Пара трюков, благодаря которым жить становится намного проще...

05.05.2017    22571    unichkin    3       

Работа с конвертацией данных 349

Статья Программист Нет файла v8 КД Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8

Поскольку к конвертации обращаюсь время от времени и какие-то детали забываются, хочу выделить несколько пунктов, чтобы "было где посмотреть". Статья сделана преимущественно «для себя», так что просьба не судить строго. (Примечание читающим/комментирующим: код в примерах очень сильно сокращен.)

16.03.2017    61833    perepetulichka    25       

Online телефонный справочник из 1С: Зарплата и управление персоналом 33

Статья Системный администратор Программист Нет файла v8 ЗУП3.x Россия Управление персоналом (HRM) Бесплатно (free) WEB

В интернете представлено много реализаций online телефонных справочников организаций. Есть справочники, которые использует для хранения информации базу Active Directory (LDAP), есть справочники, которые реализованы с использованием СУБД (например, MySQL). Но я не нашел справочника, который использует информацию из базы 1С. Далее я рассмотрю данную разработку.

10.03.2017    19057    ruha    14       

Библиотека стандартных подсистем (Механизм БСП) 74

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования БСП (Библиотека стандартных подсистем)

Конфигурации в 1С пишутся для пользователей и по их «правилам» (клиент всегда прав), поэтому в основном все конфигурации разные, но достаточно часто в них используются одни и те же объекты, которые незначительно отличаются друг от друга. Действительно, сложно представить конфигурацию, где не фигурировали бы такие сущности как номенклатура, контрагенты, пользователи, валюта. И некоторые задачи являются типичными: возможность базового разграничения прав, работа с электронной почтой, задачи пользователям и т.д. Но...!

03.03.2017    51293    V.Stavinsky    21       

Автоматизированная проверка конфигураций… и пара слов о стандартах разработки 266

Статья Программист Нет файла v8 1cv8.cf Windows Бесплатно (free) Практика программирования Тестирование и исправление

Предлагаю познакомиться с инструментом "Автоматизированная проверка конфигураций" и получить практику его применения

18.01.2017    43455    3    Vladimir Litvinenko    20       

Отладка подключаемых обработок 195

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

На самом деле для этого не нужно ни изменять конфигурацию, ни пользоваться вспомогательной обработкой-отладчиком.. Все просто :)

04.01.2017    43532    unichkin    77       

Использование программных перечислений, ч.1: строковые константы 142

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    29904    unichkin    45       

РИБ 200 узлов. Середина пути 116

Статья Системный администратор Программист Нет файла v8 Розница Россия Бесплатно (free) Распределенная БД (УРИБ, УРБД)

Между настройкой и поддержкой РИБ на 2 узла и на 10 большой разницы нет, а вот когда число удаленных точек переваливает за сотню, приходится решать уже совсем другие вопросы

25.10.2016    34140    comol    215       

Использование git для доработки типовых конфигураций 1С 230

Статья Программист Нет файла v8 Беларусь Украина Россия Бесплатно (free) Математика и алгоритмы

Рассмотрены способы доработок типовой конфигурации 1C для различных изменений, и на картинках продемонстрирован подход к разработке с использованием git и частично с тестами.

11.10.2016    186193    pumbaE    31       

Отладка конфигураций на мобильной платформе 107

Статья Программист Нет файла v8 Бесплатно (free) Мобильная разработка

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

25.09.2016    35013    spezc    44       

Обновление доработанной Бухгалтерии предприятия. Как проверить и убедиться, что все сделано хорошо? 89

Статья Системный администратор Программист Бухгалтер Нет файла v8 БП2.0 Бесплатно (free) Практика программирования

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

05.09.2016    24802    kraynev-navi    33       

Старые обработки в новом (Управляемом) интерфейсе 101

Статья Программист Нет файла v8 v8::УФ Windows Бесплатно (free) Практика программирования

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

12.08.2016    57981    valerasv    7       

Регистры сведений 1С. Как это устроено. 714

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

Основная идея публикации - собрать в одном месте информацию о внутреннем устройстве такой абстрактной сущности, как "Регистр сведений 1С" и ответить на ряд вопросов: Что происходит при записи регистра в различных режимах? Что такое на самом деле "СрезПервых" и "СрезПоследних"? Как оптимально выбрать структуру регистра? Это та информация, владея которой, начинаешь лучше понимать как это работает и как правильно использовать регистры сведений.

05.08.2016    146866    Sergey.Noskov    154       

Простая и быстрая эмуляция операций с битовыми строками 67

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Битовые строки могли бы упростить реализацию некоторых алгоритмов на языке платформы «1С: Предприятие 8». Но пока в платформе операций с битовыми строками нет. В то же время уже сделанные попытки смоделировать эти операции преобразованиями над числами опираются на циклы обработки отдельных битов, что плохо сказывается на скорости их работы. Предлагается новое простое решение, основанное на представлении битовых строк строками символов «0» и «1». Приводится примеры кода выполнения основных логических операций AND, OR, XOR, NO без использования циклов. В качестве прикладной задачи рассмотрено получение последовательных значений кода Грэя, который можно использовать для ускорения перебора вариантов.

22.06.2016    25959    ildarovich    14