Толик Панков
hex_laden
............ .................. ................
October 2025
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Длина строки в переменной CMD/BAT (быстрый, но сложный алгоритм).

Продолжение. Начало здесь (копия)

Алгоритм с бинарными операциями


Распишу алгоритм, реализованный в функции:

1. Устанавливаем режимы работы:

SetLocal EnableExtensions EnableDelayedExpansion

Справка по команде Копия в PDF

2. Устанавливаем начальные переменные в функции:

Set Out=%~0

Записываем в локальную переменную имя функции (%~0). Зачем? А спросите у дизайнеров языка CMD, он ебанутый, и без этой фишки вывод данных из функции не сработает.

Set "param=%~1"

Записываем первый и единственный параметр переданный функции (%~1), т.е. строку, в локальную переменную param.

Set "str=A!param!"

Добавляем символ A к строке param с начала строки, сохраняем результат в локальную переменную str. На самом деле, можно добавить любой печатный латинский символ. Пусть будет A.

Set "len=0"

Счетчик длины устанавливаем в ноль.

3. Запускаем основной цикл:

for /l %%a in (30,-1,0) do (
	[см. далее]
)


Второй параметр цикла (-1) означает, что цикл пойдет в обратном порядке, от 30 до 0.

4. Внутри цикла:

4.1. set /a "len|=1<<%%a"
Производится битовый сдвиг переменной цикла (%%a), т.е. к единице (двоичной) добавляется %%a нолей (двоичных).

4.2. Над полученным числом производится операция побитового ИЛИ (|), результат записывается в переменную len.

4.3. Запускается второй (внутренний) цикл, количество итераций которого проводится по полученной ранее длине (len):

for %%b in (!len!) do [...]

4.3.1. if "!str:~%%b,1!"==""

Внутри второго цикла, если мы нашли пустой символ на позиции, которую указывает счетчик (%%b), проводим битовые операции над длиной:

4.3.2. set /a "len&=~1<<%%a"

4.3.2.1. Сначала проводится битовый сдвиг с единицей на %%a разрядов (нолей)
4.3.2.2. Полученные биты инвертируются (~) т.е., например, если полученное значение было равно 1000 (в двоичной системе счисления), то после операции ~ оно превращается в 0111.
4.3.2.3. Последней производится операция побитового И (&) и значение присваивается переменной len.

5. Функция возвращает результат:

endlocal & set %Out:~1%=%len%

Функция целиком:

::Start Strlen function
:Strlen 
	SetLocal EnableExtensions EnableDelayedExpansion
	Set Out=%~0
	Set "param=%~1"
	Set "str=A!param!"
	echo %str%
	Set "len=0"
        for /l %%a in (30,-1,0) do (
        	set /a "len|=1<<%%a"
				
        	for %%b in (!len!) do if "!str:~%%b,1!"=="" set /a "len&=~1<<%%a"
    )
endlocal & set %Out:~1%=%len%
exit /b 0


Сделал разбор алгоритма по шагам, при меньшем числе итераций (установил в основном цикле первый параметр равным 4 и строку для измерения длины сделал 10 символов - 0123456789). Все свел в таблицу:

Посмотреть разбор алгоритма по шагам (PDF)

Пример на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: https://tolik-punkoff.com/2023/04/27/dlina-stroki-v-peremennoj-cmd-bat-bystryj-no-slozhnyj-algoritm/

From:
(will be screened)
Identity URL: 
имя пользователя:    
Вы должны предварительно войти в LiveJournal.com
 
E-mail для ответов: 
Вы сможете оставлять комментарии, даже если не введете e-mail.
Но вы не сможете получать уведомления об ответах на ваши комментарии!
Внимание: на указанный адрес будет выслано подтверждение.
Username:
Password:
Subject:
No HTML allowed in subject
Message:



Notice! This user has turned on the option that logs IP addresses of anonymous posters.