Что нового

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

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
Автор
G

gora

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

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, тот хорошо владеет регулярными выражениями.
 
Автор
G

gora

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

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

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323

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:
 
Верх