Tёмный: Задачка: перестановка цифр в числе
Tёмный 20 фев 2016 16:51 Изменен 17 мая 2016 05: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ёмный 20 фев 2016 16:52 Редактировать Ссылка на этот пост |
вот такой не хитрый код
если вводишь слишком большое число, или отрицательное - ругается и просит ввести корректные цифирки кроме того, обратите внимание, Dim x As Integer т.е. если вводишь дробное число, он его округляет до целого, и дальше работает как с обычным целым. Вот тут то мы и приблизились к задачке. |
Tёмный 20 фев 2016 16: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ёмный 20 фев 2016 18: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ёмный 20 фев 2016 18:41 Редактировать Ссылка на этот пост |
да, с запятой встаёт немного философский вопрос число ABCD следует переворачивать как DCBA (как было в первоначальной задачке), или таки логичнее будет выглядеть 0,DCBA |
Tёмный 20 фев 2016 18:58 Редактировать Ссылка на этот пост |
o! а если переменную y изначально задать как целое Integer, то в пункте первом не надо будет целоисчисленно делить (ну и умножать на порядок меньше, етц) |
Tёмный 20 фев 2016 19:08 Изменен 20 фев 2016 19:10 Редактировать Ссылка на этот пост |
ну и да, даже в первоначальном варианте возвращали пользователю не число, а набор символов
следовало из символов собрать число z=d*1000+c*100+b*10+a и только после этого выдать в мсгбокс или ячейку полученное число z так гораздо корректнее, имхо. ну а во втором случае, в число z вставляем запятую в нужное место, и потом уже выдаем результат |
Tёмный 20 фев 2016 20:15 Редактировать Ссылка на этот пост |
o! а если переменную y изначально задать как целое Integer, никуя. умножать и делить придётся. просто делить можно будет так / , а не так \ |
Tёмный 20 фев 2016 21: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ёмный 20 фев 2016 21:57 Редактировать Ссылка на этот пост |
какое-то совсем кривое решение
да ещё и, например, 9999,9999 считает не удовлетворяющим условию |
MoRS 23 фев 2016 15:02 Редактировать Ссылка на этот пост |
в PHP есть встроенная функция array_reverse(), в VBA незнаю, может есть чтото похожее.. Если нет то можно написать свою функцию которая разобьет введенную строку в массив символов. Потом в цикле считать эементы массива в обратном порядке.. как то так |
MoRS 23 фев 2016 15:06 Изменен 23 фев 2016 15:18 Редактировать Ссылка на этот пост |
т.е работать не с числом а со строкой, перестановка знаков это строковая задача имхо.. А потом конвертнуть в число |
Tёмный 23 фев 2016 15:59 Редактировать Ссылка на этот пост |
о! спасибо. говорят, есть StrReverse() попробую. но, увы, не сегодня. (сначала по другим дисциплинам заморочки добить надо) |
MoRS 25 фев 2016 04:15 Редактировать Ссылка на этот пост |
тема ап. Тёмный не пропадай |
Tёмный 04 мар 2016 11: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ёмный 04 мар 2016 11:56 Изменен 04 мар 2016 12:23 Редактировать Ссылка на этот пост |
Оставлю здесь пару табличек.
Типы данных
Преобразование типов
|
Tёмный 04 мар 2016 12: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ёмный 04 мар 2016 12:57 Изменен 04 мар 2016 13:00 Редактировать Ссылка на этот пост |
(имхо, сработает только в экселе, в других работать скорее всего не будет) Ага, так и есть. Например, если в том же ворде попробовать, то будет ругаться Method or data member not found (Error 461) не понимает Application.InputBox надо попробовать как-то иначе от type mismatch на этапе ввода пользователем избавиться, универсальнее. |
Tёмный 07 мар 2016 08:34 Изменен 07 мар 2016 08:36 Редактировать Ссылка на этот пост |
ну можно басню ещё сократить, засунув операции реверса в мсгбокс, тогда можно будет обойтись одной переменной
Text Sub perevertish03()
Dim x As Double x = Application.InputBox("x=", Type:=1) MsgBox ("Введённое число = " & x & vbNewLine & "Перевертыш = " & CDbl(StrReverse(CStr(x)))) End Sub |
Tёмный 12 мар 2016 21:20 Редактировать Ссылка на этот пост |
есть мнение, что последняя CDbl избыточна, т.к. пользователь всё-равно не заметит разницы на мониторе. но если понадобится не просто вывести результат в мсгбокс, а произвести ещё какие-то вычисления с результатом, то она вполне себе уместна. |
phasma 17 мая 2016 05: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 вот можно почитать какой это ад. |
Новое сообщение
Наверх>Страницы 1