Bei einem gegebenen Ausdruck besteht Ihre Aufgabe darin, ihn zu bewerten. Ihre Antwort kann jedoch nicht mehr Ziffern als nötig anzeigen, da dies den Eindruck erweckt, dass die Messungen präziser sind als die Realität.
Die Anzahl der signifikanten Ziffern einer Zahl gibt an, wie viele Ziffern sie in wissenschaftlicher Notation hat, einschließlich Nullen am Ende, wenn ein Dezimalpunkt vorhanden ist. Zum Beispiel 1200
hat 2 signifikante Zahlen, weil es 1.2*10^3
aber 1200.
4 signifikante Zahlen und 1200.0
5 signifikante Zahlen hat.
Wenn Sie zwei Zahlen hinzufügen, sollte das Ergebnis auf die gleiche Anzahl von Stellen gerundet werden wie die Zahl, deren niedrigstwertige Ziffer am weitesten links liegt. Zum Beispiel 1200 + 3 = 1200
(auf die Hunderterstelle gerundet, seit 1200 auf die Hunderterstelle gerundet) 1200.01 + 3 = 1203
und 4.59 + 2.3 = 6.9
. Beachten Sie, dass 5
aufgerundet. Dieselbe Regel gilt für die Subtraktion. 0
ist auf den einen Platz gerundet. Beachten Sie, dass das Addieren und Subtrahieren nicht von der Anzahl der signifikanten Stellen abhängt. Zum Beispiel,999 + 2.00 = 1001
weil 999 auf die Einerstelle gerundet ist und 2,00 auf die Hundertstelstelle gerundet ist; Diejenige, die auf weniger Stellen gerundet wird, ist 999, daher sollte das Ergebnis 1001,00 ebenfalls auf die Stelle gerundet werden. In ähnlicher Weise ist 300 + 1 - 300 genau gleich 1, aber 300 ist auf die Hunderterstelle gerundet, so dass das Endergebnis auch auf die Hunderterstelle gerundet werden sollte, was 0 ergibt. 300. + 1 - 300. würde 1 auf der Stelle entsprechen andere Hand.
Runden Sie beim Multiplizieren oder Teilen von zwei Zahlen auf die Anzahl der signifikanten Stellen der Zahl mit den niedrigstwertigen Stellen. Zum Beispiel, 3.839*4=20
weil der genaue Wert 15.356
,, auf 20
seitdem rundet, 4
nur eine signifikante Zahl hat. Ebenso, 100/4=30
da beide Zahlen eine signifikante Zahl haben, aber 100./4.00=25.0
da beide Zahlen 3 signifikante Zahlen haben. 0
ist definiert als 1 signifikante Zahl.
Ausdrücke werden nur enthalten *
, /
, +
, und -
, (und Klammern). Die Reihenfolge der Operationen sollte eingehalten und die Ergebnisse nach jeder Operation gerundet werden. Wenn Klammern in einer Folge von Additionen oder Subtraktionen oder einer Folge von Multiplikationen und Divisionen weggelassen werden, runden Sie nach Abschluss aller Operationen. Zum Beispiel 6*0.4*2 = 5
(eine signifikante Zahl), während 0.4*(2*6)=0.4*10=4
und (6*0.4)*2=2*2=4
.
Eingabe : Eine Zeichenfolge mit einem Ausdruck, der ()*/+-
Ziffern enthält. Zur Vereinfachung -
wird nur als Subtraktionsoperator verwendet, nicht um negative Zahlen zu kennzeichnen; Antworten könnten jedoch immer noch negativ sein und würden -
als Präfix benötigt.
Ausgabe : Das Ergebnis des Ausdrucks, ausgewertet und auf die richtige Anzahl von Stellen gerundet. Beachten Sie, dass dies 25
für falsch ist 25.0
.
Testfälle :
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
Randfall: Betrachten Sie das Problem von 501*2.0
. Der genaue Wert ist 1002
. Beim Drucken werden 1002
zu viele signifikante Zahlen angegeben (4, wenn wir 2 benötigen), aber 1000
zu wenige (1, wenn wir 2 benötigen). In diesem Fall sollte Ihr Programm 1000
trotzdem drucken .
Diese Quelle erklärt auch wichtige Ziffern: http://www.purplemath.com/modules/rounding2.htm
999 + 2.00
.300 + 1 - 300
handelt es sich um eine Reihe von Additionen und Subtraktionen, die also nicht bis zum Ende gerundet werden müssen.(300 + 1) - 300
wäre Null.Antworten:
Java 11,
13251379135613361290 Bytes+54 Bytes, um den Randfall zu beheben
501*2.0
(Ergebnis1002
vorher gegeben, aber jetzt korrekt1000
).Ich verstehe jetzt, warum diese Herausforderung fast zwei Jahre lang unbeantwortet blieb.>.> Diese Herausforderung hat mehr Sonderfälle als die niederländische Sprache, die etwas aussagt.
Java ist sicherlich nicht die richtige Sprache für diese Art von Herausforderungen (oder einen Codegolf) Herausforderung für diese Angelegenheit ..; p), aber es ist die einzige Sprache, die ich gut genug kenne, um überhaupt eine schwierige Herausforderung wie diese zu versuchen.
Eingabeformat wie
String
ohne Leerzeichen (wenn dies nicht zulässig ist, können Sies=s.replace(" ","")
oben in der Methode (+19 Byte) hinzufügen ).Probieren Sie es online aus.
Erläuterung:
Entschuldigung für den langen Beitrag.
Dieser Teil wird für Eingaben in Klammern verwendet. Es werden die getrennten Teile abgerufen und rekursive Aufrufe verwendet.
0.4*(2*6)
wird0.4*A
, woA
ist ein rekursiver Aufruf anc(2*6)
(8.3*0.02)+(1.*(9*4)+2.2)
wirdA+B
, woA
ist ein rekursiver Aufruf anc(8.3*0.02)
undB
ein rekursiver Aufruf anc(1.*(9*4)+2.2)
→ was wiederum wird1.*C+2.2
, woC
ist ein rekursiver Aufruf anc(9*4)
Diese erste Schleife wird verwendet, um die Werte zu füllen
M
undk
wobeiM
die größte Ganzzahllänge in Bezug auf signifikante Zahlen undk
die größte Dezimallänge ist.1200+3.0
wirdM=2, k=1
(12, .0
)999+2.00
wirdM=3, k=2
(999, .00
)300.+1-300.
wirdM=3, k=0
(300, .
)Diese zweite Schleife wird verwendet, um die Arrays
A
und denb
Wert zu füllenq
, wobeiA
die Anzahl der signifikanten Zahlenb
die Ganzzahlen mit führenden Nullen übereinstimmenM
undq
die niedrigste Länge ohne Berücksichtigung von Punkten ist.1200+3.0
wirdA=[2, 5] (12, 00030)
,b=[1200, 0003.0]
undq=2
(30
)999+2.00
wirdA=[3, 5] (999, 00200)
,b=[999, 002.00]
undq=3
(beide999
und200
)300.+1-300.
wirdA=[3, 3, 3] (300, 001, 300)
,b=[300., 001, 300.]
undq=1
(1
)501*2.0
wirdA=[3, 4] (501, 0020)
,b=[501, 002.0]
undq=2
(20
)Verwendet eine JavaScript-Engine, um die Eingabe auszuwerten, die
R
doppelt gespeichert wird .1200+3.0
wirdR=1203.0
999+2.00
wirdR=1001.0
300.+1-300.
wirdR=1.0
Dies wird
m
auf den kleinsten Wert im Array gesetztA
.A=[2, 5]
wirdm=2
A=[3, 5]
wirdm=3
A=[3, 3, 3]
wirdm=3
Dies ändert sich
m
basierend auf mehreren Faktoren.999+2.00 = 1001.0
&m=3,q=3
wirdm=4
(weilm==M
(beide3
) →R%1==0
(1001.0
hat keine Dezimalwerte) →(int)R/10%10<1
((int)1001.0/10
wird100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q<=1
(4-3<=1
) → wird som
die Länge des ganzzahligen Teils"1001"
(4
))3.839*4 = 15.356
&m=1,q=1
bleibtm=1
(weilm==M
(beide1
) →R%1!=0
(15.356
hat Dezimalwerte) →R<=99
→R%10!=0
(15.356%10==5.356
) →m!=0
→m
bleibt also gleich (1
))4*7*3 = 84.0
&m=1,q=1
bleibtm=1
(weilm==M
(beide1
) →R%1==0
(84.0
hat keine Dezimalwerte) →(int)R/10%10>=1
((int)84/10
wird8
→8%10>=1
) →R<=99
→R%10!=0
(84%10==4
) →m!=0
→m
bleibt also gleich (1
))6.0+4.0 = 10.0
&m=2,q=2
wirdm=3
(weilm!=M
(m=2, M=1
) →R<=99
→R%10==0
(10%10==0
) → som
wird die Länge der SummeR
(minus dem Punkt)"10.0".length()-1
(3
))0-8.8 = -8.8
&m=0,q=1
wirdm=1
(weilm!=M
(m=0, M=1
) →R<=99
→R%10!=0
(-8.8%10==-8.8
) →m<1
→ som
wird1
)501*2.0 = 1001.0
&m=3,q=2
wirdm=2
(weilm==M
(beide3
) →R%1==0
(1001.0
hat keine Dezimalwerte) →(int)R/10%10<1
((int)1001.0/10
wird100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q>1
(4-2>1
) → som
wirdq
(2
))Jetzt
R
wird basierend auf gerundetm
.1001.0
&m=4
wird1001.0
0.258
&m=3
Wird0.26
(weilabs(R)<1
,m-1
(2
) stattm=3
verwendet innenMathContext
)-8.8
&m=1
wird-9.0
1002.0
&m=2
wird1000.0
Dies ändert
R
bei Bedarf den ganzzahligen Teil von .300.+1-300. = 1.0
&m=3,M=3
bleibt1.0
(weilm>=M
→ so gleichR
bleibt (1.0
))0.4*10 = 4.0
&m=1,M=2
bleibt4.0
(weilm<M
→(10^(M-m))/10<=R
((10^1)/10<=4.0
→10/10<=4.0
→1<=4.0
) → so gleichR
bleibt (4.0
))300+1-300 = 1.0
&m=1,M=3
Wird0.0
(weilm<M
→(10^(M-m))/10>R
((10^2)/10>1.0
→100/10>1.0
→10>1.0
) → soR
wird0.0
wegenint(R/(10^(M-m)))*(10^(M-m))
(int(1.0/(10^2))*(10^2)
→int(1.0/100)*100
→0*100
→0
)Diese Sätze
R
zur
als String und modifiziert es auf mehreren Faktoren.1203.0
&m=4,k=2
wird1203.
(weilk>=1
→ sor
wird1001.000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>=m
(8>=4
) → Teilzeichenfolge von Index0
zum+1
(5
))6.9
&m=2,k=2
bleibt6.9
(weilk>=1
→ sor
wird6.900
;r.length()>=m
(5>=2
) →r.contains(".")
→r.length()>=m
(5>=2
) → Teilzeichenfolge von Index0
zum+1
(3
))1.0
&m=3,k=0
wird1
(weilk<1
→ sor
wird1
;r.length()<m
(1<3
) → Teilzeichenfolge von Index0
zur.length()
(1
))25.0
&m=4,k=4
wird25.00
(weilk>=1
→ sor
wird25.00000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>+m
(8>=4
) → Teilzeichenfolge von Index0
zum+1
(5
))0
&m=1,k=0
bleibt0
(weilk<1
→ sor
bleibt0
;r.length()>=m
(1>=1
) →!r.contains(".")
→ Teilzeichenfolge von Index0
zum
(1
))Dadurch werden nachfolgende Nullen bei Bedarf wieder auf den ganzzahligen Teil zurückgesetzt.
r="12"
&R=1200.0
wirdr="1200"
r="1"
&R=10.0
wirdr="10"
r="8"
&R=80.0
wirdr="80"
Und schließlich geben wir das Ergebnis zurück, nachdem wir alle nachfolgenden Punkte entfernt haben.
1203.
wird1203
5.
wird5
Kann definitiv um ein paar hundert Bytes gespielt werden, aber ich bin nur froh, dass es jetzt funktioniert. Es dauerte bereits eine Weile, um jeden der Fälle und die Fragen der Herausforderung zu verstehen. Und dann war viel Versuch und Irrtum, Testen und erneutes Testen erforderlich, um zum obigen Ergebnis zu gelangen. Und während ich diese Erklärung oben schrieb, konnte ich weitere ± 50 Bytes nicht verwendeten Codes entfernen.
quelle
501*2.0
Ausgabe zu erfordern1000
(Sie sollten1000
trotzdem ausgeben , was ich als "still" interpretiere, nicht so oder so ). Trotzdem großartige Arbeit.