Заходи заходи
Имя

Пароль



Регистрация
Сейчас в чате 0
никого нет
Их боялся Флинт
Модеры:
Orkana Джа Cyber_Ghost zl0l

Админы:
del Tёмный DreamX MoRS
Бесполезные линки

Valid XHTML 1.0 Transitional

Tёмный: Задачка: перестановка цифр в числе
Tёмный
pic
20 фев 2016 13:51
Изменен 17 мая 2016 02:32
Редактировать
Ссылка на этот пост
Сначала обрисую исходную решенную задачку, чтоб было понятно откуда ноги растут.
 
Пользователь вводит число ABCD, программа возвращает ему число DCBA.
 
Например:
1234 - 4321
5678 - 8765
123 - 3210
5610 - 0165
 
Код
(Да, смейтесь, VBA. Но это тоже одно из условий задачи - сделать на VBA)
 
Text

Sub перестановкацифр()
 
'ЗАДАТЬ ПЕРЕМЕННЫЕ
Dim x As Integer, a As Single, b As Single, c As Single, d As Single
 
'Ввод и проверка числа
x = InputBox("x=")
Do While x > 9999 Or x < 0
    x = InputBox("число не удовлетворяет условию, вводи заново")
Loop
 
'Поиск цифр
a = x \ 1000
b = (x - a * 1000) \ 100
c = (x - (a * 1000 + b * 100)) \ 10
d = (x - (a * 1000 + b * 100 + c * 10))
 
'Просто мсгбокс
'MsgBox x
 
'Вывод перевёрнутого числа
 
'В мсгбокс
MsgBox ("Введённое число = " & x & vbNewLine & "перевёрнутое число = " & d & c & b & a)
 
'В ячейку
'cells(2,2)= d & c & b & a
 
End Sub
Tёмный
pic
20 фев 2016 13:52

Редактировать
Ссылка на этот пост
вот такой не хитрый код
 
если вводишь слишком большое число, или отрицательное - ругается и просит ввести корректные цифирки
 
кроме того, обратите внимание, Dim x As Integer
т.е. если вводишь дробное число, он его округляет до целого, и дальше работает как с обычным целым.
 
Вот тут то мы и приблизились к задачке.
Tёмный
pic
20 фев 2016 13:54

Редактировать
Ссылка на этот пост
Собственно задачка: заставить программку работать и с десятичными дробями тоже.
Т.е. ввод - ответ должны понимать и такую логику тоже:
123,5 - 5,321
45,87 - 78,54
1,052 - 250,1
0,05 - 50
 
а также программка должна откидывать округлением лишнюю дробную часть
23,564489236 - 65,23
4,93251872 - 339,4
 
Вот свиду такая простая задачка, а вызывает у меня затруднения.
Нид хелп.
В целом, я не прошу написать код,
просто подскажите парой фраз алгоритм, пожалуйста.
Tёмный
pic
20 фев 2016 15:24

Редактировать
Ссылка на этот пост
покачто приходит на ум только такая абракадабра
 
после ввода и проверки числа на условие больше 0 и меньше 10000 (т.е. в первоначальном решении чуток подправить проверку условия ввода)
 
1 Привести x к виду "целое, не более четырёх знаков" y=ABCD
1.1. если x<1000 or x=100 то y=x*100\10
1.2. иначе если x<100 or x=10 то y=x*1000\10
1.3. иначе если x<10 or x=1 то y=x*10000\10
1,4, иначе если x<1 то y=x*100000\10
1.5. иначе y=x*10\10
 
2. По вышеописанной методе расчленить y на цифры, переставить их местами, и получить z=DCBA
 
3. Воткнуть в z запятую в нужное место, и получить число q, которое потом и вернём пользователю
3.1. если x<1000 or x=100 то q=y/1000
3.2. иначе если x<100 or x=10 то q=y/100
3.3. иначе если x<10 or x=1 то q=y/10
3.4.
3.5. иначе q=y
 
вернуть число q пользователю
 
------
примерно как-то так.
через дважды анал, но других мыслей пока нет
Tёмный
pic
20 фев 2016 15:41

Редактировать
Ссылка на этот пост
да, с запятой встаёт немного философский вопрос
число ABCD следует переворачивать как DCBA (как было в первоначальной задачке), или таки логичнее будет выглядеть 0,DCBA
Tёмный
pic
20 фев 2016 15:58

Редактировать
Ссылка на этот пост
o! а если переменную y изначально задать как целое Integer,
то в пункте первом не надо будет целоисчисленно делить (ну и умножать на порядок меньше, етц)
Tёмный
pic
20 фев 2016 16:08
Изменен 20 фев 2016 16:10
Редактировать
Ссылка на этот пост
ну и да, даже в первоначальном варианте возвращали пользователю не число, а набор символов
 
следовало из символов собрать число
z=d*1000+c*100+b*10+a
 
и только после этого выдать в мсгбокс или ячейку полученное число z
 
так гораздо корректнее, имхо.
 
ну а во втором случае, в число z вставляем запятую в нужное место, и потом уже выдаем результат
Tёмный
pic
20 фев 2016 17:15

Редактировать
Ссылка на этот пост
предыдущая мысль
o! а если переменную y изначально задать как целое Integer,
то в пункте первом не надо будет целоисчисленно делить (ну и умножать на порядок меньше, етц)

никуя.
умножать и делить придётся.
просто делить можно будет так / , а не так \
Tёмный
pic
20 фев 2016 18:45

Редактировать
Ссылка на этот пост
примерно как-то так.
ещё добавить проверку соответствия типа вводимых данных
 
Text (Unknown Language)

Sub perevertish()
 
'Краткое иписание макроса
'ABCD => DCBA
 
'==============================================================================
'0. Задаём переменные. Разбил на несколько строк, чтобы легче читать комменты
'0.1. Число, которое будет вводить пользователь (возможно с запятой)
Dim x As Single
 
'0.2. Вспомогательное число, которое будем раскидывать по цифрам порядков.
'ЦЕЛОЕ - чтобы отбросить лишние знаки после запятой в числе x
Dim y As Integer
 
'0.3. Переменнные для цифр порядков. они не могут быть не целыми
Dim a As Integer, b As Integer, c As Integer, d As Integer
 
'0.4. Вспомогательное число-перевёртыш, в которое соберем цифры в обратном порядке
'это y с обратным порядком цифр. следовательно оно получится целым
Dim z As Integer
 
'0.5. Число, которое вернём пользователю (поставив запятую в нужное место z)
Dim q As Single
 
'==============================================================================
'1. Даем пользователю форму ввода числа
x = InputBox("Введите неотрицательное число меньше 10`000, x=")
 
'2. Проверяем введенное число на соответствие условиям,
'при ошибке просим пользователя скорректировать ввод
'ДОПИСАТЬ ПРОВЕРКУ НА ВВОД ТЕКСТА, ТОЧКИ ВМЕСТО ЗАПЯТОЙ И Т.П.
'убрать ошибку type mismatch (несоответствие типов)
Do While x < 0 Or x >= 10000
    x = InputBox("число не удовлетворяет условию, вводи заново")
Loop
'вспомогательный бокс для проверки выполнения предыдущего блока
'MsgBox x
 
'==============================================================================
'3. Преобразуем введённое число в целое ABCD, из которого и будем вытаскивать цифры
If x < 1000 And x >= 100 Then
    y = x * 100 \ 10
    Else
        If x < 100 And x >= 10 Then
            y = x * 1000 \ 10
            Else
                If x < 10 And x >= 1 Then
                    y = x * 10000 \ 10
                    Else
                        If x < 1 Then
                            y = x * 100000 \ 10
                            Else: y = x * 10 \ 10
                       
                        End If
                End If
        End If
End If
 
'вспомогательный бокс для проверки выполнения предыдущего блока
'MsgBox y
 
'==============================================================================
'4. Разбиваем число на цифры
a = y \ 1000
b = (y - a * 1000) \ 100
c = (y - (a * 1000 + b * 100)) \ 10
d = (y - (a * 1000 + b * 100 + c * 10))
 
'==============================================================================
'5. Собираем вспомогательное число-перевёртыш с обратным порядком цифр
z = d * 1000 + c * 100 + b * 10 + a
 
'==============================================================================
'6. Вставляем запятую в нужное место, "зеркально" заданному числу
If x < 1000 And x >= 100 Then
    q = z / 1000
    Else
        If x < 100 And x >= 10 Then
            q = z / 100
            Else
                If x < 10 And x >= 1 Then
                    q = z / 10
                    Else
                        If x < 1 Then
                            q = z
                            Else: q = z / 10000
                       
                        End If
                End If
        End If
End If
 
'==============================================================================
'7. Отдаём результат пользователю
'7.1. В мсгбокс
MsgBox ("Введённое число = " & x & vbNewLine & "Перевертыш = " & q)
 
'В ячейку
'cells(2,2)=q
 
End Sub
 
Tёмный
pic
20 фев 2016 18:57

Редактировать
Ссылка на этот пост
какое-то совсем кривое решение
 
да ещё и, например, 9999,9999 считает не удовлетворяющим условию
MoRS
pic
23 фев 2016 12:02

Редактировать
Ссылка на этот пост
в PHP есть встроенная функция array_reverse(),
в VBA незнаю, может есть чтото похожее.. Если нет то можно написать свою функцию которая разобьет введенную строку в массив символов. Потом в цикле считать эементы массива в обратном порядке.. как то так
 
MoRS
pic
23 фев 2016 12:06
Изменен 23 фев 2016 12:18
Редактировать
Ссылка на этот пост
т.е работать не с числом а со строкой, перестановка знаков это строковая задача имхо.. А потом конвертнуть в число
Tёмный
pic
23 фев 2016 12:59

Редактировать
Ссылка на этот пост
о! спасибо.
говорят, есть StrReverse()
попробую.
но, увы, не сегодня.
(сначала по другим дисциплинам заморочки добить надо)
MoRS
pic
25 фев 2016 01:15

Редактировать
Ссылка на этот пост
тема ап. Тёмный не пропадай
Tёмный
pic
04 мар 2016 08:43

Редактировать
Ссылка на этот пост
Минималистичненько
 
Text (Unknown Language)

Sub perevertish02()
Dim x As Double, q As Double
 
x = InputBox("x=")
q = CDbl(StrReverse(CStr(x)))
 
MsgBox ("Введённое число = " & x & vbNewLine & "Перевертыш = " & q)
 
End Sub
 

надо дописать проверку ввода: чтоб на буквы, пробелы, точку вместо запятой и т.п. - ругался
Tёмный
pic
04 мар 2016 08:56
Изменен 04 мар 2016 09:23
Редактировать
Ссылка на этот пост
Оставлю здесь пару табличек.
 

Типы данных

 

Преобразование типов

Tёмный
pic
04 мар 2016 09:52

Редактировать
Ссылка на этот пост
Остановлюсь пока на таком варианте
(имхо, сработает только в экселе, в других работать скорее всего не будет)
 
Text (Unknown Language)

Sub perevertish02()
 
Dim x As Double, q As Double
 
x = Application.InputBox("x=", Type:=1)
q = CDbl(StrReverse(CStr(x)))
 
MsgBox ("Введённое число = " & x & vbNewLine & "Перевертыш = " & q)
 
End Sub
 
Tёмный
pic
04 мар 2016 09:57
Изменен 04 мар 2016 10:00
Редактировать
Ссылка на этот пост
Tёмный
(имхо, сработает только в экселе, в других работать скорее всего не будет)

Ага, так и есть.
Например, если в том же ворде попробовать, то будет ругаться
 
Method or data member not found (Error 461)
 
не понимает Application.InputBox
 
надо попробовать как-то иначе от type mismatch на этапе ввода пользователем избавиться, универсальнее.
Tёмный
pic
07 мар 2016 05:34
Изменен 07 мар 2016 05:36
Редактировать
Ссылка на этот пост
ну можно басню ещё сократить, засунув операции реверса в мсгбокс, тогда можно будет обойтись одной переменной
 
Text
Sub perevertish03()
 
Dim x As Double
 
x = Application.InputBox("x=", Type:=1)
 
MsgBox ("Введённое число = " & x & vbNewLine & "Перевертыш = " & CDbl(StrReverse(CStr(x))))
 
End Sub
Tёмный
pic
12 мар 2016 18:20

Редактировать
Ссылка на этот пост
есть мнение, что последняя CDbl избыточна,
т.к. пользователь всё-равно не заметит разницы на мониторе.
 
но если понадобится не просто вывести результат в мсгбокс, а произвести ещё какие-то вычисления с результатом, то она вполне себе уместна.
phasma
pic
17 мая 2016 02:32

Редактировать
Ссылка на этот пост
Обычно задачи такого типа решаются через степени десятки и остаток от деления. Вообще она решается за линейное время как-нибудь вот так http://ideone.com/cRhq1b
 
> Собственно задачка: заставить программку работать и с десятичными дробями тоже.
С десятичными дробями так не работают. Вообще работать с дробями на x86 не есть хорошо и тем более хранить в БД эти числа, т.к. теряется точность и в какой-то момент времени ты можешь получить совсем другое число. http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB вот можно почитать какой это ад.
Новое сообщение