По заданному выражению ваша задача - оценить его. Однако ваш ответ не может содержать больше цифр, чем необходимо, поскольку это создает впечатление более точных измерений, чем реальность.
Число значащих цифр, которое имеет число, - это количество цифр, которые оно имеет, когда написано в научной записи, включая нули в конце, если присутствует десятичная точка. Например, 1200
имеет 2 значащие цифры, потому что он имеет, 1.2*10^3
но 1200.
имеет 4 значащих цифры и 1200.0
имеет 5 значащих цифр.
При добавлении двух чисел результат должен быть округлен до того же числа мест, что и число, наименее значимая цифра которого находится дальше всего слева. Например, 1200 + 3 = 1200
(округляется до сотни, поскольку с 1200 округляется до сотни) 1200.01 + 3 = 1203
, и 4.59 + 2.3 = 6.9
. Обратите внимание, что 5
округляется. Это же правило относится и к вычитанию. 0
округляется до одного места. Обратите внимание, что сложение и вычитание не зависят от количества значащих цифр. Например,999 + 2.00 = 1001
потому что 999 округляется до единицы, а 2,00 округляется до сотых места; единица, округленная до меньшего числа, равна 999, поэтому результат, равный 1001,00, должен быть округлен до тех же мест. Точно так же 300 + 1 - 300 точно равно 1, но 300 округляется до сотен, поэтому конечный результат также должен быть округлен до сотен, давая 0. 300. + 1 - 300. будет равно 1 на с другой стороны.
При умножении или делении двух чисел округляют до числа значащих цифр числа с наименьшими значащими цифрами. Например, 3.839*4=20
поскольку точное значение, 15.356
округляет до, 20
поскольку 4
имеет только одну значащую цифру. Аналогично, 100/4=30
поскольку оба числа имеют одну значащую цифру, но 100./4.00=25.0
поскольку оба числа имеют 3 значащие цифры. 0
определяется, чтобы иметь 1 значащую цифру.
Выражения будет содержать только *
, /
, +
, и -
, (и круглые скобки). Порядок операций должен соблюдаться, а результаты должны округляться после каждой операции. Если скобки не указаны в строке сложений или вычитаний или в строке умножений и делений, то после выполнения всех операций округляются. Например, 6*0.4*2 = 5
(одна значимая цифра), а 0.4*(2*6)=0.4*10=4
и (6*0.4)*2=2*2=4
.
Ввод : строка с выражением, содержащим ()*/+-
и цифры. Чтобы упростить вещи, -
будет использоваться только как оператор вычитания, а не для обозначения отрицательных чисел; ответы, однако, все еще могут быть отрицательными и потребуют -
в качестве префикса.
Вывод : результат выражения, оцененный и округленный до правильного количества цифр. Обратите внимание, что 25
это неправильно для 25.0
.
Тестовые случаи :
3 + 0.5 --> 4
25.01 - 0.01 --> 25.00
4*7*3 --> 80
(4*7)*3 --> 90
(8.0 + 0.5)/(2.36 - 0.8 - 0.02) --> 5.7
6.0 + 4.0 --> 10.0
5.0 * 2.0 --> 10.0
1/(2.0 * (3.0 + 5.0)) --> 0.06
0.0020 * 129 --> 0.26
300 + 1 - 300 --> 0
0 - 8.8 --> -9
3*5/2*2 --> 20
Крайний случай: рассмотрим проблему 501*2.0
. Точное значение 1002
. Печать 1002
дает слишком много значащих цифр (4, когда нам нужно 2), но 1000
дает слишком мало (1, когда нам нужно 2). В этом случае ваша программа должна 1000
все равно печатать .
Этот источник также объясняет существенные цифры: http://www.purplemath.com/modules/rounding2.htm
999 + 2.00
,.300 + 1 - 300
, это строка сложений и вычитаний, поэтому не нужно округлять до конца.(300 + 1) - 300
будет ноль.Ответы:
Ява 11,
1325,1379,1356,1336,1290 байт.+54 байта, чтобы исправить крайний случай
501*2.0
(давал результат1002
раньше, но теперь исправлю1000
).Теперь я понимаю, почему этот вызов оставался без ответа в течение почти двух лет.>.> В этом вызове есть более особые случаи, чем в голландском языке, который что-то говорит.
Java, безусловно, не является подходящим языком для такого рода вызовов (или для любого программиста) вызов в этом отношении ...; р), но это единственный язык, который я знаю достаточно хорошо, чтобы даже попытаться сделать трудный вызов, как этот.
Формат ввода
String
без пробелов (если это не разрешено, вы можете добавитьs=s.replace(" ","")
(+19 байт) в начало метода).Попробуйте онлайн.
Объяснение:
Извините, за длинную статью.
Эта часть используется для ввода, содержащего круглые скобки. Он получит разделенные части и будет использовать рекурсивные вызовы.
0.4*(2*6)
становится0.4*A
, гдеA
рекурсивный вызовc(2*6)
(8.3*0.02)+(1.*(9*4)+2.2)
становитсяA+B
, гдеA
рекурсивный вызовc(8.3*0.02)
иB
рекурсивный вызовc(1.*(9*4)+2.2)
→ который в свою очередь становится1.*C+2.2
, гдеC
рекурсивный вызовc(9*4)
Этот первый цикл используется для заполнения значений
M
иk
гдеM
наибольшая целочисленная длина относительно значащих цифр иk
наибольшая десятичная длина.1200+3.0
становитсяM=2, k=1
(12, .0
)999+2.00
становитсяM=3, k=2
(999, .00
)300.+1-300.
становитсяM=3, k=0
(300, .
)Этот второй контур используется для заполнения массивов
A
иb
так же , как значениеq
, гдеA
это количество значащих цифр,b
провести целые числа с ведущими нулями , чтобы соответствоватьM
, аq
самый низкий длина без учета точек.1200+3.0
становитсяA=[2, 5] (12, 00030)
,b=[1200, 0003.0]
иq=2
(30
)999+2.00
становитсяA=[3, 5] (999, 00200)
,b=[999, 002.00]
иq=3
(как999
и200
)300.+1-300.
становитсяA=[3, 3, 3] (300, 001, 300)
,b=[300., 001, 300.]
иq=1
(1
)501*2.0
становитсяA=[3, 4] (501, 0020)
,b=[501, 002.0]
иq=2
(20
)Использует движок JavaScript для оценки ввода, который будет сохранен
R
как двойной.1200+3.0
становитсяR=1203.0
999+2.00
становитсяR=1001.0
300.+1-300.
становитсяR=1.0
Это устанавливает
m
наименьшее значение в массивеA
.A=[2, 5]
становитсяm=2
A=[3, 5]
становитсяm=3
A=[3, 3, 3]
становитсяm=3
Это модифицируется
m
на основе нескольких факторов.999+2.00 = 1001.0
&m=3,q=3
становитсяm=4
(потому чтоm==M
(оба3
) →R%1==0
(1001.0
не имеет десятичных значений) →(int)R/10%10<1
((int)1001.0/10
становится100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q<=1
(4-3<=1
) → такm
становится длиной целочисленной части"1001"
(4
))3.839*4 = 15.356
&m=1,q=1
остаетсяm=1
(потому чтоm==M
(оба1
) →R%1!=0
(15.356
имеет десятичные значения) →R<=99
→R%10!=0
(15.356%10==5.356
) →m!=0
→m
остается неизменным (1
)4*7*3 = 84.0
&m=1,q=1
остаетсяm=1
(потому чтоm==M
(оба1
) →R%1==0
(84.0
не имеет десятичных значений) →(int)R/10%10>=1
((int)84/10
становится8
→8%10>=1
) →R<=99
→R%10!=0
(84%10==4
) →m!=0
→m
остается неизменным (1
))6.0+4.0 = 10.0
&m=2,q=2
становитсяm=3
(потому чтоm!=M
(m=2, M=1
) →R<=99
→R%10==0
(10%10==0
) → такm
становится общей длинойR
(минус точка)"10.0".length()-1
(3
))0-8.8 = -8.8
&m=0,q=1
становитсяm=1
(потому чтоm!=M
(m=0, M=1
) →R<=99
→R%10!=0
(-8.8%10==-8.8
) →m<1
→ такm
становится1
)501*2.0 = 1001.0
&m=3,q=2
становитсяm=2
(потому чтоm==M
(оба3
) →R%1==0
(1001.0
не имеет десятичных значений) →(int)R/10%10<1
((int)1001.0/10
становится100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q>1
(4-2>1
) → такm
становитсяq
(2
))Теперь
R
округляется на основеm
.1001.0
&m=4
становится1001.0
0.258
&m=3
становится0.26
(потому чтоabs(R)<1
,m-1
(2
) вместоm=3
используется внутриMathContext
)-8.8
&m=1
становится-9.0
1002.0
&m=2
становится1000.0
Это изменяет целую часть
R
при необходимости.300.+1-300. = 1.0
&m=3,M=3
остается1.0
(потому чтоm>=M
→ так жеR
остается (1.0
))0.4*10 = 4.0
&m=1,M=2
остается4.0
(потому чтоm<M
→(10^(M-m))/10<=R
((10^1)/10<=4.0
→10/10<=4.0
→1<=4.0
) → так жеR
остается (4.0
)300+1-300 = 1.0
&m=1,M=3
становится0.0
(потому чтоm<M
→(10^(M-m))/10>R
((10^2)/10>1.0
→100/10>1.0
→10>1.0
) → такR
становится0.0
из-заint(R/(10^(M-m)))*(10^(M-m))
(int(1.0/(10^2))*(10^2)
→int(1.0/100)*100
→0*100
→0
)Это устанавливает
R
вr
качестве строки и модифицирует его на основе нескольких факторов.1203.0
&m=4,k=2
становится1203.
(потому чтоk>=1
→ такr
становится1001.000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>=m
(8>=4
) → подстрока из индекса0
вm+1
(5
))6.9
&m=2,k=2
остается6.9
(потому чтоk>=1
→ такr
становится6.900
;r.length()>=m
(5>=2
) →r.contains(".")
→r.length()>=m
(5>=2
) → подстрока из индекса0
вm+1
(3
))1.0
&m=3,k=0
становится1
(потому чтоk<1
→ такr
становится1
;r.length()<m
(1<3
) → подстрока из индекса0
вr.length()
(1
))25.0
&m=4,k=4
становится25.00
(потому чтоk>=1
→ такr
становится25.00000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>+m
(8>=4
) → подстрока из индекса0
вm+1
(5
))0
&m=1,k=0
остается0
(потому чтоk<1
→ такr
остается0
;r.length()>=m
(1>=1
) →!r.contains(".")
→ подстрока из индекса0
вm
(1
))Это при необходимости возвращает конечные нули обратно к целочисленной части.
r="12"
&R=1200.0
становитсяr="1200"
r="1"
&R=10.0
становитсяr="10"
r="8"
&R=80.0
становитсяr="80"
И, наконец, мы возвращаем результат, после того как мы удалили все конечные точки.
1203.
становится1203
5.
становится5
Можно определенно сыграть пару сотен байтов, но я просто рад, что сейчас это работает. Потребовалось некоторое время, чтобы понять каждый из случаев и то, что было задано в задаче. А потом потребовалось много проб и ошибок, тестирование и повторное тестирование, чтобы получить результат выше. И при написании этого объяснения выше я смог удалить еще ± 50 байт неиспользуемого кода.
источник
501*2.0
чтобы вывод1000
(вы должны вывести в1000
любом случае , который я интерпретирую как "все еще", не так или иначе ). Великолепная работа в любом случае.