Автор Тема: [Данные, строки] Реализовать необычный счётчик  (Прочитано 310 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ynbIpb [?]

  • Скриптер
  • ****
  • Сообщений: 397
  • Репутация: 109
  • Пол: Мужской
    • Награды
Здравствуйте.
Возникла такая задача: Есть некая строка, которая может состоять из цифр и букв. Необходимо к ней прибавлять + 1 как будто это строка с цифрами.
Например была она 123abc, сделали +1 и стала 123abd и т.д. Прошли весь набор символов, сдвигаем соседний символ 123ac0 и снова перебираем 123ac1...
Никак не придумаю как это реализовать.
Код: AutoIt [Выделить]
$iCounter = 1 ;счётчик
$sCharacterString = "123abc" ; исходная строка
$aSymbols = StringSplit ("0123456789abcdefghijklmnopqrstuvwxyz", ""); массив из допустимых символов

While 1 ; бесконечный цикл
    ;$sCharacterString += 1
    $sCharacterString = "123ab"&$aSymbols[13+1] ; 123abd
    $sCharacterString = "123abe"
    $sCharacterString = "123abf"
    ;....
    $sCharacterString = "123a"&$aSymbols[13]&$aSymbols[1] ; 123ac0
    $sCharacterString = "123ac1"
    ;....
    $iCounter += 1 ; каждый проход добавляем + 1
    TrayTip ("", "Текущий круг: "&$iCounter &@CRLF& "Текущее значение строки: "&$sCharacterString, 3)
    Sleep (1000)
WEnd
 


Русское сообщество AutoIt


Оффлайн Torotin [?]

  • Новичок
  • *
  • Сообщений: 10
  • Репутация: 2
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Доброго дня.
Как вариант - можно через регулярное выражение читать последний символ строки -> перевести в номер символа ascii -> прибавить единицу-> перевести обратно в символ.

Код: AutoIt [Выделить]
; ascii table
; https://www.autoitscript.com/autoit3/docs/appendix/ascii.htm

$string = "0" ; строка
$startSybm = 0; символ начала отсчета
$endSybm = "z"; символ конца отсчета. после чего добавляется символ начала в конец строки


; 0 - 9
; asc = 48 - 57

; A - Z
; asc = 65 - 90

; a  - z
; asc = 97 - 122

For $i = 1 to 100
;~  ConsoleWrite($i)
    ConsoleWrite(@CRLF & @CRLF)
    ConsoleWrite('Строка на входе в цикл: "'&$String & '"' &  @CRLF)
    ConsoleWrite(@CRLF & @CRLF)
   
    $aString = StringRegExp($string, ".*(.)", 3)                        ;поиск последнего символа строки
    $sString = $aString[0]
    ConsoleWrite("Последний символ строки: " & $sString & @CRLF)

    If $sString = $endSybm Then                                         ;условие добавление нового символа в конец строки
        ConsoleWrite("Добавляем к строке символ старта" & @CRLF)       
        $string &= $startSybm
        ConsoleWrite("Новое содержимое строки: "& $string & @CRLF)
        $aString = StringRegExp($string, ".*(.)", 3)
        $sString = $aString[0]
        ConsoleWrite("Новый последний символ строки: " & $sString & @CRLF)
    EndIf

    $AscCode = Asc($sString)                                            ;вычисление кода ascii последнего символа строки
;~  ConsoleWrite($AscCode & @CRLF)
    $CheckAcsCode = _SymbCheck($AscCode)                               
;~  ConsoleWrite($CheckAcsCode & @CRLF)
;~  ConsoleWrite(Chr($CheckAcsCode) & @CRLF)
    $NewAscCode = $CheckAcsCode+1
   
    if StringLen($string) = 1 Then                                      ;провеврка на длину строки
        $string = Chr($NewAscCode)  ; условие выполнения в случае 1-символьной строки
    Else
        $string = StringRegExpReplace($string, "(.*)(.)", "${1}"&Chr($NewAscCode), 0) ;в случае строки более 1 символа
    EndIf
   
;~  ConsoleWrite($NewAscCode & @CRLF)
;~  ConsoleWrite(Chr($NewAscCode) & @CRLF)
Next

Func _SymbCheck($CheckData) ; функция проверки допустимого диапазаона последнего сивмвола строки по коду scii table
    Local $newData = $CheckData
    ConsoleWrite("ASCII-код символа на входе в функцию   _SymbCheck: " & $newData & @CRLF)
    If $CheckData > 57 And $CheckData < 65 Then $newData = 65
    If $CheckData > 90 And $CheckData < 97 Then $newData = 97
    ConsoleWrite("ASCII-код символа на выходе из функции _SymbCheck: " & $newData & @CRLF)
    Return $newData
EndFunc
 

« Последнее редактирование: Март 13, 2019, 03:53:52 от Torotin, Причина: Добавлен вариант кода »

Оффлайн ynbIpb [?]

  • Скриптер
  • ****
  • Сообщений: 397

  • Автор темы
  • Репутация: 109
  • Пол: Мужской
    • Награды
Благодарю за идею. Не задумывался про то, что ascii коды идут по порядку.
Пытаюсь понять механизм, откуда-то лезет символ двоеточия вместо заглавной буквы A. И если начальная строка $string = "0" больше 1-го символа, то они не учитываются.
Буду думать как подогнать эту идею под себя.

Возможно кто-то ещё подкинет альтернативные решения.
« Последнее редактирование: Март 13, 2019, 13:55:58 от ynbIpb »

Русское сообщество AutoIt

Re: [Данные, строки] Реализовать необычный счётчик
« Ответ #2 Отправлен: Март 13, 2019, 13:50:42 »

Оффлайн ra4o [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 938
  • Репутация: 173
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Если к 123zzz прибавить 1 должно быть 124000 ?
Пересчитать последний символ строки в ascii, добавить 1 и перевести в символ не проблема, как быть в случае переполнения , те нужно уже 1 добавлять к старшему разряду , а младший начинать с начала.
« Последнее редактирование: Март 13, 2019, 16:21:36 от ra4o »

Оффлайн ynbIpb [?]

  • Скриптер
  • ****
  • Сообщений: 397

  • Автор темы
  • Репутация: 109
  • Пол: Мужской
    • Награды
Да, именно так.  Старший разряд должен меняться, младший начинаться сначала.

Вот как-то так мне это видится, но как правильно обрабатывать старшие разряды не придумаю. Столько костылей получится.
Код: AutoIt [Выделить]
$iCounter = 1 ;счётчик
$sCharacterString = "123abc" ; исходная строка
$aSymbols = StringSplit ($sCharacterString, ""); массив из исходной строки, разбитый по символам
$sCurAsciiStr = "" ; текущая строка преобразованная в ASCII код

While 1 ; бесконечный цикл
    $sCurAsciiSymb = Asc ($aSymbols[$aSymbols[0]]); получаем код последнего символа
    If $sCurAsciiSymb >= 48 And $sCurAsciiSymb <= 56 Then ; проверка входил ли код в диапазаон от 0 до 8
        $sCurAsciiSymb += 1
        $aSymbols[$aSymbols[0]] = Chr ($sCurAsciiSymb); записывает новый символ в массив
        $sCurAsciiSymb = "" ; обнуляем текущий символ
    EndIf
    If $sCurAsciiSymb = 57 Then ; проверка является ли код символом "9"
        $aSymbols[$aSymbols[0]] = Chr (97); перескакиваем к букве "a" и записываем новый символ в массив
        $sCurAsciiSymb = "" ; обнуляем текущий символ
    EndIf
    If $sCurAsciiSymb >= 97 And $sCurAsciiSymb <= 121 Then ; проверка входил ли код в диапазаон от a до y
        $sCurAsciiSymb += 1
        $aSymbols[$aSymbols[0]] = Chr ($sCurAsciiSymb); записывает новый символ в массив
        $sCurAsciiSymb = "" ; обнуляем текущий символ
    EndIf
    If $sCurAsciiSymb = 122 Then ; проверка является ли код последним символом z
        $aSymbols[$aSymbols[0]] = Chr (48); обнуляем последний символ в массиве
        $aSymbols[$aSymbols[0]-1] = Chr (Asc ($aSymbols[$aSymbols[0]-1])+1); делаем +1 в старшем разряде
    EndIf
    For $i=1 To $aSymbols[0]; формируем новую строку из массива
        $sCurAsciiStr &= $aSymbols[$i]
    Next

    $iCounter += 1 ; каждый проход добавляем + 1
    ;TrayTip ("", "Текущий круг: "&$iCounter &@CRLF& "Текущее значение строки: "&$sCurAsciiStr, 3)
    ConsoleWrite ("Текущее значение строки:  ["&$sCurAsciiStr&"]  Текущий круг: "&$iCounter&@CRLF)
    Sleep (500)
    $sCurAsciiStr = "" ;обнуляем переменную
WEnd
 

« Последнее редактирование: Март 13, 2019, 21:56:11 от ynbIpb »

Русское сообщество AutoIt

Re: [Данные, строки] Реализовать необычный счётчик
« Ответ #4 Отправлен: Март 13, 2019, 20:56:14 »

Оффлайн Torotin [?]

  • Новичок
  • *
  • Сообщений: 10
  • Репутация: 2
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Да, именно так.  Старший разряд должен меняться, младший начинаться сначала.

Вот как-то так мне это видится, но как правильно обрабатывать старшие разряды не придумаю. Столько костылей получится.
Код: AutoIt [Выделить]
$iCounter = 1 ;счётчик
$sCharacterString = "123abc" ; исходная строка
$aSymbols = StringSplit ($sCharacterString, ""); массив из исходной строки, разбитый по символам
$sCurAsciiStr = "" ; текущая строка преобразованная в ASCII код

While 1 ; бесконечный цикл
    $sCurAsciiSymb = Asc ($aSymbols[$aSymbols[0]]); получаем код последнего символа
    If $sCurAsciiSymb >= 48 And $sCurAsciiSymb <= 56 Then ; проверка входил ли код в диапазаон от 0 до 8
        $sCurAsciiSymb += 1
        $aSymbols[$aSymbols[0]] = Chr ($sCurAsciiSymb); записывает новый символ в массив
        $sCurAsciiSymb = "" ; обнуляем текущий символ
    EndIf
    If $sCurAsciiSymb = 57 Then ; проверка является ли код символом "9"
        $aSymbols[$aSymbols[0]] = Chr (97); перескакиваем к букве "a" и записываем новый символ в массив
        $sCurAsciiSymb = "" ; обнуляем текущий символ
    EndIf
    If $sCurAsciiSymb >= 97 And $sCurAsciiSymb <= 121 Then ; проверка входил ли код в диапазаон от a до y
        $sCurAsciiSymb += 1
        $aSymbols[$aSymbols[0]] = Chr ($sCurAsciiSymb); записывает новый символ в массив
        $sCurAsciiSymb = "" ; обнуляем текущий символ
    EndIf
    If $sCurAsciiSymb = 122 Then ; проверка является ли код последним символом z
        $aSymbols[$aSymbols[0]] = Chr (48); обнуляем последний символ в массиве
        $aSymbols[$aSymbols[0]-1] = Chr (Asc ($aSymbols[$aSymbols[0]-1])+1); делаем +1 в старшем разряде
    EndIf
    For $i=1 To $aSymbols[0]; формируем новую строку из массива
        $sCurAsciiStr &= $aSymbols[$i]
    Next

    $iCounter += 1 ; каждый проход добавляем + 1
    ;TrayTip ("", "Текущий круг: "&$iCounter &@CRLF& "Текущее значение строки: "&$sCurAsciiStr, 3)
    ConsoleWrite ("Текущее значение строки:  ["&$sCurAsciiStr&"]  Текущий круг: "&$iCounter&@CRLF)
    Sleep (500)
    $sCurAsciiStr = "" ;обнуляем переменную
WEnd
 

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

Главный вопрос к вводной задачи: сама строка ограничена количеством символов по длине?

Реализация счётчика "горит" по срокам?

Отправлено с моего SM-N950F через Tapatalk

Оффлайн ra4o [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 938
  • Репутация: 173
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Вот мой вариант , смысл такой - переводим число из тридцатишестиричного  в десятичное, прибавляем единицу, затем обратно.
(нажмите для показа/скрытия)
« Последнее редактирование: Март 14, 2019, 02:13:52 от ra4o »

Оффлайн ynbIpb [?]

  • Скриптер
  • ****
  • Сообщений: 397

  • Автор темы
  • Репутация: 109
  • Пол: Мужской
    • Награды
Torotin  [?]
Цитировать
Главный вопрос к вводной задачи: сама строка ограничена количеством символов по длине?Реализация счётчика "горит" по срокам?
Стока может начинаться и с 1-го символа, а может и сразу с 4-х. Длинна может увеличиться, если все старшие разряды достигнут "z".
Нет, конечно не горит. Это обычная самоделка для себя.

ra4o  [?]
Цитировать
Вот мой вариант
Отличная идея! Выдумать свою систему счислений)
В пределах своего количества символов отлично прибавляет. На zzzzzz падает.

Русское сообщество AutoIt

Re: [Данные, строки] Реализовать необычный счётчик
« Ответ #7 Отправлен: Март 14, 2019, 12:25:42 »

Оффлайн ra4o [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 938
  • Репутация: 173
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Цитировать
На zzzzzz падает.
У меня нормально работает и дальше . Измените строку в функции "_IntTo36" на
Код: AutoIt [Выделить]
While $Value > 35

Пробовал, максимальное число, после которого падает - это "zzzzzzzzzu" (у меня система 64 битная).

Оффлайн ynbIpb [?]

  • Скриптер
  • ****
  • Сообщений: 397

  • Автор темы
  • Репутация: 109
  • Пол: Мужской
    • Награды
Да, больше 10 символов "z" не переваривает. Видимо упираемся в какое-то ограничение языка.
В общем благодаря идее о 36-ричной системе счисления я пришёл к такому результату:
Код: AutoIt [Выделить]
$iCounter = 1 ;счётчик
$sCharacterString = "123adc" ; исходная строка

While 1 ; бесконечный цикл
    ConsoleWrite ("Текущее значение строки:  ["&$sCharacterString&"]  Текущий круг: "&$iCounter&@CRLF) ; Выводим результат
    $result = _BaseToBase($sCharacterString, 36, 10) + 1; преобразуем из 36-ричной в десятичную и добавляем +1
    $sCharacterString = _BaseToBase($result, 10, 36); преобразуем из десятичной в 36-ричную
    $iCounter += 1 ; каждый проход добавляем + 1
    Sleep (300)
WEnd

Func _BaseToBase($sIn, $iBaseIn, $iBaseOut)
    Local $sOut = 0
    If $iBaseIn <> 10 Then ; iBaseIn to decimal
        $aVal = StringSplit(StringUpper ($sIn), ""); разбиваем строку на массив, предварительно переводим в верхний регистр
        For $x = 1 to $aVal[0]
         $iDec = Asc($aVal[$x]) - (48 + ($aVal[$x] > "9") * 7)
            $sOut += $iDec * ($iBaseIn ^ ($aVal[0] - $x))
        Next
        $sIn = $sOut
    EndIf
    If $iBaseOut <> 10 Then ; decimal to iBaseOut
        $sOut = ""
        While $sIn >= 1
            $x = Mod($sIn, $iBaseOut)
            $sOut = Chr($x + 48 + ($x > 9) * 7) & $sOut
            $sIn = ($sIn - $x) / $iBaseOut
        WEnd
    EndIf
    Return StringLower ($sOut); возвращаем строку в нижнем регистре
EndFunc

Функцию нашёл тут
Большое спасибо всем!

Русское сообщество AutoIt

Re: [Данные, строки] Реализовать необычный счётчик
« Ответ #9 Отправлен: Март 17, 2019, 21:14:16 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
1 Ответов
2846 Просмотров
Последний ответ Июнь 25, 2011, 16:04:40
от Fever
17 Ответов
6486 Просмотров
Последний ответ Август 16, 2011, 20:57:49
от madmasles
4 Ответов
3219 Просмотров
Последний ответ Сентябрь 10, 2011, 07:32:28
от at
11 Ответов
5231 Просмотров
Последний ответ Ноябрь 16, 2011, 13:36:23
от running-frag
1 Ответов
2709 Просмотров
Последний ответ Декабрь 28, 2011, 19:23:44
от madmasles
9 Ответов
5741 Просмотров
Последний ответ Сентябрь 05, 2013, 17:11:49
от naix9
2 Ответов
2518 Просмотров
Последний ответ Декабрь 06, 2013, 04:30:27
от joiner
2 Ответов
1139 Просмотров
Последний ответ Июнь 01, 2016, 11:25:04
от Yukka
2 Ответов
986 Просмотров
Последний ответ Сентябрь 11, 2016, 08:55:29
от DezmontDeXa
5 Ответов
1047 Просмотров
Последний ответ Июнь 06, 2017, 00:44:51
от Garrett