Что нового

Разделить число на цифровые тройки пробелами

gora

Знающий
Сообщения
315
Репутация
19
Требуется разделить число (от одной цифры до 12) на цифровые тройки пробелами. Сделал так:
Код:
$n1 = _TabNum0('1')
$n2 = _TabNum0('12')
$n3 = _TabNum0('123')
$n4 = _TabNum0('1234')
$n5 = _TabNum0('12345')
$n6 = _TabNum0('123456')
$n7 = _TabNum0('1234567')
$n8 = _TabNum0('12345678')
$n9 = _TabNum0('123456789')
$n10 = _TabNum0('1234567890')
$n11 = _TabNum0('12345678901')
$n12 = _TabNum0('123456789012')
MsgBox(1, "табулирование цифр", @CRLF & _
"$n1  :	" & $n1 & @CRLF & _
"$n2  :	" & $n2 & @CRLF & _
"$n3  :	" & $n3 & @CRLF & _
"$n4  :	" & $n4 & @CRLF & _
"$n5  :	" & $n5 & @CRLF & _
"$n6  :	" & $n6 & @CRLF & _
"$n7  :	" & $n7 & @CRLF & _
"$n8  :	" & $n8 & @CRLF & _
"$n9  :	" & $n9 & @CRLF & _
"$n10:	" & $n10 & @CRLF & _
"$n11:	" & $n11 & @CRLF & _
"$n12:	" & $n12 & @CRLF & _
@CRLF)
Exit

Func _TabNum0($tn)
	$len = StringLen($tn)
	If $len > 3 And $len <= 6 Then $tn = StringMid($tn, 1, $len-3) & " " & StringMid($tn, $len-2, 3)
	If $len > 6 And $len <= 9 Then $tn = StringMid($tn, 1, $len-6) & " " & StringMid($tn, $len-5, 3) _
	& " " & StringMid($tn, $len-2, 3)
	If $len > 9 Then $tn = StringMid($tn, 1, $len-9) & " " & StringMid($tn, $len-8, 3) _
	& " " & StringMid($tn, $len-5, 3) & " " & StringMid($tn, $len-2, 3)
	Return $tn
EndFunc


Может быть можно решить как-то проще?

Спасибо.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
попробуй так
Код:
$str = ''
For $i = 1 to 12
    $str &= '1'
    $len = StringLen($str)
    $Int = Int($len/3)
    $Mod = Mod($len/3)
    For $j = 1 to $Int
        $res &= StringMid($str, 3*($j - 1) + 1, 3*$j) & ' '
    Next
    If $Mod Then
        $res &= StringTrimRight($str, $Mod)
    Else
        $res = StringTrimRight($str, 1)
    EndIf
    ConsoleWrite($res & @CRLF)
Next

проверить возможности нет, но идея надеюсь понятна
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
qsort
Ваш вариант сработал, но не правильно. Я специально привел работающий пример. Например, число 1234 у Вас преобразуется в 123 4, а у меня в 1 234. Т.е. цифровые тройки нужно отсчитывать с конца числа, а не с его начала.
Kaster
Ваш вариант не заработал. Исправил пару ошибок в нем, но все равно после запуска ни чего не происходит.
Как я понял у Вас там само число генерируется, а мне этого не надо. Мне нужна именно функция обработки числа, которое ей будет передано. Т.е. Func _TabNum0($tn), а все что выше у меня в коде - это лишь проверка работы функции.
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Код:
$sNumber = '111111111111'
MsgBox(0,"", _TabNum($sNumber))

Func _TabNum($sNumber)
	Local $tNumber
	While 1
		$tNumber = " " & StringRight($sNumber, 3) & $tNumber
		$sNumber = StringTrimRight($sNumber, 3)
		If $sNumber = "" Then ExitLoop
	WEnd
	Return StringTrimLeft($tNumber, 1)
EndFunc
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Вот еще вариант :
Код:
#include <String.au3>

Dim $sString
For $i=1 To 12
   $sString &= $i
   $sNewString=_TabNum($sString)
   ConsoleWrite("$n "& $i & " ="& $sNewString & @LF )
Next

Func _TabNum($tn)
   $Ret=_StringReverse($tn)
   $Ret=StringRegExpReplace ( $Ret ,'(\d{1,3})',' \1' )
   $Ret=_StringReverse($Ret)
   Return $Ret
EndFunc
 

Suppir

Продвинутый
Сообщения
967
Репутация
62
Вариант gregaz'а самый правильный.


А у меня покороче:


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

Код:
#include <String.au3>
For $i=1 To 12
	local $x
	$x &= $i
	ConsoleWrite(_StringReverse(StringRegExpReplace (_StringReverse($x),'(\d{1,3})',' \1' )) & @CR)
Next



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

кто сможет написать без _StringReverse, тот хорошо владеет регулярными выражениями.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Код:
Func _TabNum0($str)
	$str = StringStripWS(StringRegExpReplace($str, "(\d{3})?(\d{3})?(\d{3})$", " \1 \2 \3"), 7)
    Return $str
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
До кучи (для строки любой длины).

Код:
Func _TabNum0($tn)
    Return StringStripWS(StringRegExpReplace(StringFormat('%' & (3 * (Floor(StringLen($tn) / 3) + 1)) & 's', $tn), '(.{3})', '\1 '), 1)
EndFunc
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Раз пошла такая :beer:
Еще один мой изврат:
Код:
Func _TabNum0($tn)
   $Ret=StringRegExpReplace ( $tn ,'(\d{3})','\1 ' )
   $ii=3-StringLen(StringRegExpReplace ( $Ret ,'\d{3}\s?','' ))
   $Ret=StringSTripWS(StringRegExpReplace ( $Ret ,'(\d{'& $ii  &'})(\s)','\2\1' ),1)
   Return $Ret
EndFunc
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Управился одной командой :laugh::

Код:
Func _TabNum0($tn)
	Return StringRegExpReplace($tn, '(\d{3}(?=\d))', '\1 ')
EndFunc
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
dwerf [?]
Управился одной командой

gora [?]
Ваш вариант сработал, но не правильно. Я специально привел работающий пример. Например, число 1234 у Вас преобразуется в 123 4, а у меня в 1 234. Т.е. цифровые тройки нужно отсчитывать с конца числа, а не с его начала.
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
dwerf сказал(а):
Управился одной командой :laugh::

Код:
Func _TabNum0($tn)
	Return StringRegExpReplace($tn, '(\A\d{1,3}(?=\d{3}\z)|\A\d{1,3}(?=\d{6}\z)|\A\d{1,3}(?=\d{9}\z)|\d{3}(?=\d))', '\1 ')
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
До кучи :smile:
Код:
#include <String.au3>

For $i = 1 To 100
	MsgBox(0, $i, _TabNum0(_StringRepeat(Random(1, 9, 1), $i)), 1)
Next

Func _TabNum0($tn)
	If StringLen($tn) <= 3 Then Return $tn
	$sRes = StringRight($tn, Mod(StringLen($tn), 3)) & Chr(32)
	$aRes = StringRegExp(StringTrimLeft($tn, Mod(StringLen($tn), 3)), '\d{3}', 3)
	For $i = 0 To UBound($aRes) - 1
		$sRes &= $aRes[$i] & Chr(32)
	Next
	Return StringTrimRight($sRes, 1)
EndFunc   ;==>_TabNum0
 

Suppir

Продвинутый
Сообщения
967
Репутация
62
dwerf
dwerf сказал(а):
#include <String.au3>

Dim $sString
For $i=1 To 12
$sString &= $i
$sNewString=_TabNum($sString)
ConsoleWrite("$n "& $i & " ="& $sNewString & @LF )
Next


После определенной строки начинает с ошибками писать:

1
12
123
1 234
12 345
123 456
1 234 567
12 345 678
123 456 789
12 345 678 910
123 456 789 101 1
123 456 789 101 112
123 456 789 101 112 13
123 456 789 101 112 131 4
123 456 789 101 112 131 415
123 456 789 101 112 131 415 16
123 456 789 101 112 131 415 161 7
123 456 789 101 112 131 415 161 718
123 456 789 101 112 131 415 161 718 19
123 456 789 101 112 131 415 161 718 192 0
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219

Suppir

Продвинутый
Сообщения
967
Репутация
62
Имхо, без переворота строки одним регулярным выражением (для очень длинного числа) эту задачу решить довольно сложно.



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

dwerf [?]
Надо больше - надо дописывать \A\d{1,3}(?=\d{12}\z), \A\d{1,3}(?=\d{15}\z) итд.

Получается, что это не универсальное решение?
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
OffTopic:
Suppir [?]
Значит, это не универсальное решение.
Оно изначально и не спрашивалось.
А совсем универсальное невозможно:
Maximum string length: 2,147,483,647 characters.
 

Suppir

Продвинутый
Сообщения
967
Репутация
62
dwerf

интересно ведь сделать именно универсальное, чтобы подходило для любых цифр (в пределах типа переменной).
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Suppir [?]
интересно ведь сделать именно универсальное, чтобы подходило для любых цифр (в пределах типа переменной).
Как бы я без вас критиков жил? ;)
Код:
Func _TabNum0($tn)
    Return StringRegExpReplace($tn, '(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))', '\1 ')
EndFunc


edit: Поставил вместо * +, лишних пробелов не осталось.
 

Suppir

Продвинутый
Сообщения
967
Репутация
62
dwerf [?]
Как бы я без вас критиков жил? Код: AutoIt [Выделить]Func _TabNum0($tn) Return StringRegExpReplace($tn, '(\A\d{1,3}(?=(\d{3})*\z)|\d{3}(?=\d))', '\1 ')EndFunc


Снимаю шляпу, код работает. Это лучшее из предложенных решений. :ok:


Черт, пытался примерно такой же код написать, но до этого фрагмента не додумался:
(\A\d{1,3}(?=(\d{3})*\z)|\d{3}(?=\d))


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

В очередной раз убеждаюсь, что регулярные выражения рулят :smile:
 
Верх