Определение длины строки в запросе методом половинного деления

0. Vladimir Vasiliev (vasvl123) 66 26.12.15 10:37 Сейчас в теме
Во встроенном языке запросов 1С не реализована функция определения длины строки. В тех случаях, когда длину строки необходимо определять именно в запросе, приходится прибегать к различным ухищрениям. Как вариант, предлагается использовать быстрый метод половинного деления.

Перейти к публикации

Комментарии
1. Максим *** (premier) 140 27.12.15 15:48 Сейчас в теме
(0) На скриншот посмотрел и страшно стало... за 1С-ников.
2. Vladimir Vasiliev (vasvl123) 66 27.12.15 16:51 Сейчас в теме
Выглядит, конечно, не очень, но работает замечательно
3. Александр Капустин (kapustinag) 27.12.15 17:56 Сейчас в теме
Скрин №2 точно в порядке? Номера ВСЕХ строк совпадают с их длинами.
Или это особенность алгоритма? -:)
4. Vladimir Vasiliev (vasvl123) 66 27.12.15 18:04 Сейчас в теме
(3) kapustinag, для отладки сделал так, чтобы в начале каждой строки была написана своя длина)
5. Сергей (ildarovich) 5415 29.12.15 16:27 Сейчас в теме
Вот гораздо более компактная реализация той же самой идеи:
ВЫБРАТЬ
	"12345678901234567890123456789012345678901234567890" КАК Стр,
	1023 КАК Х
ПОМЕСТИТЬ Дано
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Стр, Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   0, 1) = "" ТОГДА Х -   1 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   1, 1) = "" ТОГДА Х -   2 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   3, 1) = "" ТОГДА Х -   4 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   7, 1) = "" ТОГДА Х -   8 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  15, 1) = "" ТОГДА Х -  16 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  31, 1) = "" ТОГДА Х -  32 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  63, 1) = "" ТОГДА Х -  64 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 127, 1) = "" ТОГДА Х - 128 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 255, 1) = "" ТОГДА Х - 256 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 511, 1) = "" ТОГДА Х - 512 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	Дано КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ
Показать
Этим запросом можно получить длину строки до 1023 быстро и без дополнительных таблиц.
ZOMI; yurii_host; jsr; Операция1Ы; vasvl123; +5 Ответить
6. Vladimir Vasiliev (vasvl123) 66 29.12.15 19:28 Сейчас в теме
(5) ildarovich, Супер! Возьму на вооружение в новой обработке. Переносите способ в Ваш пост про минимализмы. Длину подстроки, однако, следует брать 3 символа, иначе пробел дает ложный конец строки, например, после 31 символа.
7. Олег Загородний (jsr) 31.12.15 11:20 Сейчас в теме
(6) vasvl123, чтобы "отловить" любое количество внутренних пробелов, идущих подряд, длина подстроки должна быть достаточной, чтобы "дотянуться" до конца строки. Не вникая особо, можно везде поставить 1024. А хвостовые пробелы вообще не ловятся.
9. Vladimir Vasiliev (vasvl123) 66 31.12.15 12:34 Сейчас в теме
(7) jsr, чтобы наверняка, тогда да. Но не 1024, а половина длины строки, причем можно с каждым шагом уменьшать вдвое.
13. Sergey Andreev (starik-2005) 1222 12.10.17 23:28 Сейчас в теме
(5)
Этим запросом можно получить длину строки до 1023 быстро и без дополнительных таблиц.
Странная странность, но если в строке есть пробел, то будет найдена длина строки до пробела (платформа 8.3.10).
14. Сергей (ildarovich) 5415 13.10.17 12:02 Сейчас в теме
(13) Странно под пятницу 13-е тринадцатое сообщение спряталось у меня в середину списка комментариев, поэтому не сразу его нашел, так как смотрел в конце ленты.

По сути вопроса:
Проверил на 8.3.11. У меня не подтверждается, пробелы в середине не учитываются, вот скриншот. Возможно, просто Х не задаете. Попробуйте в консоли точно такой запрос как в (5).
Прикрепленные файлы:
15. Sergey Andreev (starik-2005) 1222 13.10.17 18:43 Сейчас в теме
(14)
Проверил на 8.3.11. У меня не подтверждается, пробелы в середине не учитываются, вот скриншот.
Короче, проблема возникает, если в конце строки через пробел добавляется одиночные символы, но как-то странно вообще (см. картинки):
Строка "1234567890123456789012345678901234567890123456789 1 2 3 ff zz zz" показывает 64, что правильно, но стоит только вместо "ff" указать "f" - и все! Дальше как пойдет - поведение системы непредсказуемо...
Прикрепленные файлы:
17. Сергей (ildarovich) 5415 13.10.17 23:12 Сейчас в теме
(15) Теперь увидел ошибку. Она алгоритмическая. Самое интересное, что уже попадался в эту ловушку и писал об этом в статье Агрегатное суммирование строк в запросе – сложно, но не невозможно. В комментарии http://forum.infostart.ru/forum9/topic93629/message980659/#message980659 . Можно поправить вот так:
ВЫБРАТЬ
    "1234567890123456789012345678901234567890123456789 1 2 3 f zz zz" КАК Стр,
    1023 КАК Х
ПОМЕСТИТЬ Дано
;
ВЫБРАТЬ
    Стр, Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   0, 1) + "!" = "!" ТОГДА Х -   1 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   1, 1) + "!" = "!" ТОГДА Х -   2 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   3, 1) + "!" = "!" ТОГДА Х -   4 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   7, 1) + "!" = "!" ТОГДА Х -   8 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  15, 1) + "!" = "!" ТОГДА Х -  16 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  31, 1) + "!" = "!" ТОГДА Х -  32 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  63, 1) + "!" = "!" ТОГДА Х -  64 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 127, 1) + "!" = "!" ТОГДА Х - 128 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 255, 1) + "!" = "!" ТОГДА Х - 256 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 511, 1) + "!" = "!" ТОГДА Х - 512 ИНАЧЕ Х КОНЕЦ Х
ИЗ    Дано КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ
Показать
Хотя, наверное, можно и вот так:
ВЫБРАТЬ
    "1234567890          " КАК Стр,
    1023 КАК Х
ПОМЕСТИТЬ Дано
;
ВЫБРАТЬ
    Стр, Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   0, 512) = "" ТОГДА Х -   1 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   1, 512) = "" ТОГДА Х -   2 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   3, 512) = "" ТОГДА Х -   4 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   7, 512) = "" ТОГДА Х -   8 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  15, 512) = "" ТОГДА Х -  16 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  31, 512) = "" ТОГДА Х -  32 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  63, 512) = "" ТОГДА Х -  64 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 127, 512) = "" ТОГДА Х - 128 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 255, 512) = "" ТОГДА Х - 256 ИНАЧЕ Х КОНЕЦ Х
ИЗ    (ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 511, 512) = "" ТОГДА Х - 512 ИНАЧЕ Х КОНЕЦ Х
ИЗ    Дано КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ
Показать
Разница в реакции на хвостовые пробелы. В первом варианте они считаются в длине строки, а во втором случае - нет.
Большое спасибо за внимательность. Очередная "последняя" обнаруженная ошибка, которая, как известно, всегда предпоследняя.
Нужно будет еще в минимализмах поправить.
18. Sergey Andreev (starik-2005) 1222 13.10.17 23:28 Сейчас в теме
(17) я сравнивал обрезанную и необрезанную строку, чтобы решить подобную проблему, хотя, конечно, смысла особого в получении длины строки таким образом нет (на мой скромный взгляд). Но как упражнение весьма интересно.
19. Сергей (ildarovich) 5415 13.10.17 23:41 Сейчас в теме
(18) Да, больше как упражнение (во всяком случае, не помню, чтобы самому приходилось на практике применять). Тем более, кто-то писал (сам не проверил еще), что в Postgre есть более жесткое ограничение на максимальный уровень вложенности. С другой стороны, для небольших строк это лучше чем гребенка "подобно" или соединение с искусственной таблицей. Поэтому пусть будет как возможный вариант.
8. Vladimir Vasiliev (vasvl123) 66 31.12.15 12:28 Сейчас в теме
Сравнил производительность обоих способов, выложил обработку и скрин. Думаю способ с деревом все же имеет право на жизнь.
10. Uladzimir - (nvv1970) 11.10.17 14:15 Сейчас в теме
(0) ...и последний вопрос
Скоро напишу, для чего это было нужно
ЗАЧЕМ? ))) Два года ждем )
11. Vladimir Vasiliev (vasvl123) 66 12.10.17 20:25 Сейчас в теме
12. Uladzimir - (nvv1970) 12.10.17 21:06 Сейчас в теме
(11) Хммм.... Интересненько, любопытненько... Хотя не ясно как эти две статьи связать.

ЗЫ: и сразу полезли мысли (про нечеткий поиск) "где такое можно применить, внедрить в решение, продать наконец. )))
Нигде, никого это не заинтересует. Как и отсутствие дублей...
Если только вы не программист на предприятии и вам эти косяки исправлять.
20. Vladimir Vasiliev (vasvl123) 66 14.10.17 16:52 Сейчас в теме
(12) способ определения длины строки в запросе применил при определении схожести строк в нечетком поиске. По поводу применить/продать - автоматизировать что-то таким способом нельзя, нужно пользоваться очень осторожно и перепроверять результаты.
16. Sergey Andreev (starik-2005) 1222 13.10.17 18:46 Сейчас в теме
"1234567890123456789012345678901234567890123456 7 8 9 1 2 3 ff zz zz" - 67 символов, убираю одну "f": "1234567890123456789012345678901234567890123456 7 8 9 1 2 3 f zz zz" - и уже 63!
Оставьте свое сообщение