Instead of just cutting the backward string into just 2 parts, the number of loops into for can be reduced to a certain mediocre level.
With only two characters converted, there are a maximum of about 4000 times in the loop.
With the maximum line length approx 700 characters can be shifted at once.
But that would be 700 times in a for loop.
With the correct calculation, this can be reduced to a maximum of about 200 times recurring forloops.
So a maximum of 90 conversions at once within a line and 90 times the string in total swap.
can this also be calculated by logarithm?
but maybe that's enough. I have no idea how I can calculate otherwise.
Code: Select all
@echo off
setlocal disableDelayedExpansion
if NOT defined stringVar set "stringVar=%~1"
if NOT defined stringVar echo no stringVar defined! & exit /b
call :setAllMacros
setlocal enabledelayedexpansion
%strLen(var):var=!stringVar!%
set /a loop=3
if %len% gtr 150 set /a loop=len/10
if %len% gtr 600 set /a loop=len/25
if %len% gtr 1500 set /a loop=len/90
endlocal & set /a loop=%loop%, len=%len%
rem Reverse var
set "rev=!R:X,1!"
set "revers="
set "reverStr="
setlocal enabledelayedexpansion
for /l %%L in (1 1 %loop%) do set "revers=!Rev:X=~%%L!!revers!"
for /l %%L in (0 %loop% %len%) do (
set "R= !stringVar:~%%L!"
set "ReverStr=%revers%!ReverStr!"
)
if "%~2" equ "" echo !ReverStr!
for /f delims^=^ eol^= %%i in ("!ReverStr!") do (
endlocal
endlocal
if "%~2" neq "" set "%~2=%%i"
)
exit /b
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:setAllMacros
:: define LF as a Line Feed (newline) character
set ^"LF=^
^" Above empty line is required - do not remove
:: define a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:strLen.var
:: create a macro with reduced For loops
:: Parenthesis are included
:: usage: %strLen(var):var=!stringVar!%
::
@for %%T in ("%temp%\%~n0.tmp.cmd") do @(
@ >%%T (
echo( @set strLen(var^)=(%%\n%%
echo( set "str=Avar"%%\n%%
echo( set "len=0"%%\n%%
for /l %%i in (12 -1 0) do @(
echo( set /a "len|=1<<%%i"%%\n%%
echo( for %%%%# in (!len!^) do if .!str:~%%%%#^^^^^^,1!==. set /a "len&=~1<<%%i"%%\n%%
)
echo(^)
)
call %%T
del %%T
)
set "LF="
set "\n="
exit /B
edit
Ok I have now combined the calculation of the number of substitutions per line with a square check.
Can these be calculated faster as a root?
Creation of the macro with reduced loop (saves read and execute) I pushed without temporary file - for it partially within delayedexpansion.
Since the assembly for the variable of the substitutions for line eh must start from 1, the calculation of the quatrate is carried out in the same loop.
Thus, the number of replacements and the assembly of the string are approximately balanced and increased evenly.
the coarse maximum number for the quadratic calculation is calculated when determining the string length.
Thus, the code has become a bit shorter.
Overall, in total, in all loops there are between 25 and 200 repetitions for the whole batch.
Code: Select all
@echo off
setlocal disableDelayedExpansion
if NOT defined stringVar set "stringVar=%~1"
if NOT defined stringVar echo no stringVar defined! & exit /b
set "rev=!R:~X,1!"
set "revMax="
set "revers="
set "reverStr="
set ^"LF=^
^" Above empty line is required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
set forI= set /a "len|=1<<FORi"%\n%
for %%# in (!len!^) do if .!str:~%%#^^^,1!==. ( set /a "len&=~1<<FORi"%\n%
^) else if not defined revMax set /a "revMax=(FORi-3)*(FORi-3)+10"
@set strLen(var^)=(%\n%
set "str=Avar"%\n%
set "len=0"
setlocal enabledelayedexpansion
for /l %%i in (12 -1 0) do @ set "strLen(var)=!strLen(var)!!lf!!forI:FORi=%%i!"
set strLen(var)=!strLen(var)!!lf!)
%strLen(var):var=!stringVar!%
set /a L=loop=1
for /l %%L in (1 1 %revMax%) do if !L! lss %len% ( set /a L=%%L*%%L, loop=%%L
set "revers=!Rev:X=%%L!!revers!"
)
if not defined revers ( set "ReverStr=!stringVar!"
) else for /l %%L in (0 %loop% %len%) do ( set "R= !stringVar:~%%L!"
set "ReverStr=%revers%!ReverStr!"
)
if "%~2" equ "" echo !ReverStr!
for /f delims^=^ eol^= %%i in ("!ReverStr!") do (
endlocal
endlocal
if "%~2" neq "" set "%~2=%%i"
)
exit /b