Что нового

Буквенный счётчик/Буквенная последовательность

Andrey_A

Знающий
Сообщения
127
Репутация
12
Всем добрый...
На офф форуме встретил 2 функции https://www.autoitscript.com/forum/topic/196260-three-letter-increment/?tab=comments#comment-1407241
Там не стал писать, т.к. аглицкого не знаю
Функции неплохие, но есть 2 проблемы
1) _Base26ToDec - выдаёт всегда 0 при 'A', 'AA', 'AAA', 'AAAAAAAA' и.т.д.
т.е. должно быть
0 - "A"
25 - "Z"
26 - "AA"
и.т.д
2) _Dec2Base26 - пропускает 'AA', 'AAA' ... при получении счётчика в цикле
Если кто может подправить эти функции было бы здорово - я к ним и слева и справа подходил, но что-то никак, борьба со смещением сместила мозг)))

Код:
#include <Array.au3>
; Modified functions from https://www.autoitscript.com/forum/topic/194949-array-troubles/?do=findComment&comment=1398101

$str='AA' ; 'ZZ'
$Res=_Base26ToDec($str)
MsgBox(4096,"Переменная $Res",$Res)

Local $sNum = "Z"

$Res=_Base26ToDec($sNum)
MsgBox(4096,"Переменная $Res",$Res)

MsgBox(0, "", $sNum & " + 1 = " & _Dec2Base26(_Base26ToDec($sNum) +1) & @CRLF)

; Parameter $iLen - Number of characters in returned string.
Func _Dec2Base26($iDec, $iLen = 6)
    Local $aBase26 = StringSplit("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 2)
    Local $sRet = ""
    $n=Int(Log($iDec) / Log(26))
    For $i = 0 To Int(Log($iDec) / Log(26))
        $sRet = $aBase26[Mod($iDec / 26 ^ $i, 26)] & $sRet
    Next
    Return StringRight("AAAAAAAAAAAA" & $sRet, $iLen)
EndFunc

Func _Base26ToDec($str)
    Local $iRet, $a = StringSplit($str, "", 2), $UB = UBound($a) - 1
    For $i = 0 To $UB
        $iRet += 26 ^ ($UB - $i) * (StringInStr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", $a[$i], 1) - 1)
    Next
    Return $iRet
EndFunc

Сообщение автоматически объединено:

Спасибо... Решил вопрос
 
Последнее редактирование:
Автор
A

Andrey_A

Знающий
Сообщения
127
Репутация
12
Пытался изменить эти функции, но потом бросил эту затею и написал новые
Кстати функции _Base26ToDec... имеют место быть и используются в ряде программ, к примеру в Total Commander при переименовании файлов на буквенный счётчик
А вот что получилось:

Код:
#include <Array.au3>

$sString=''
$sSS='abcdefghijklmnopqrstuvwxyz'
$sSS='абвгдеёжзийклмнопрстуфхцчшщъыьэюя'
$sSS='АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
$sSS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
$nnnn=StringLen($sSS)
$aAAA=StringSplit($sSS,'',2)

$sSym=__Dec2Base_Num_ToString_ABC(18279,$aAAA,$nnnn)
MsgBox(4096,"Переменная $sSym","$sSym =>"&$sSym&"<=")

$k=__Dec2Base_String_ToNum_ABC('ZZZ',$sSS,$nnnn)
MsgBox(4096,"Переменная $k","$k =>"&$k&"<=")

$k=__Dec2Base_String_ToNum_ABC_Old('ZZZ',$aAAA,$nnnn)
MsgBox(4096,"Переменная $k","$k =>"&$k&"<=")

For $i=1 To 20000
  $sString&=__Dec2Base_Num_ToString_ABC($i,$aAAA,$nnnn)&'|'
Next
$aArray=StringSplit($sString,'|')
_ArrayDisplay($aArray,"Массив $aArray")


; A, B, C, ... Z, AA, AB, ... ZZ, AAA, AAB, ... ZZZ, AAAA
Func __Dec2Base_Num_ToString_ABC($iIndex, ByRef $aRet,ByRef $n,$sLine='')
  Do
    $iIndex-=1
    $sLine=$aRet[Mod($iIndex,$n)]&$sLine
    $iIndex/=$n
  Until $iIndex<1
  Return $sLine
EndFunc
; немного подправил функцию
; из 'A' получает 1, 'AA'=27, 'AAA'=703, 'AAAA'=18279 минус 1
Func __Dec2Base_String_ToNum_ABC(ByRef $sLine,ByRef $sString,ByRef $n,$iIndex=0)
  $avArray=StringSplit($sLine,'')
  For $i=1 To $avArray[0]
    $iIndex+=StringInStr($sString,$avArray[$i])*$n^($i-1)
  Next
  Return $iIndex-1
EndFunc
; из 'A' получает 1, 'AA'=27, 'AAA'=703, 'AAAA'=18279 минус 1
Func __Dec2Base_String_ToNum_ABC_Old(ByRef $sLine,ByRef $aRet,ByRef $n,$iIndex=0)
  $R=StringSplit($sLine,'')
  For $i=1 To $R[0]
    For $j=0 To $n-1
      If $R[$i]=$aRet[$j]Then ExitLoop
    Next
    $iIndex+=($j+1)*$n^($i-1)
  Next
  Return $iIndex-1
EndFunc
 
Последнее редактирование:
Верх