Bu kapalı sorunun başlığını gördüğümde ilginç bir kod golf mücadelesine benziyordum. Öyleyse onu şu şekilde sunmama izin verin:
Meydan okuma:
Bir aritmetik ifade verilen bir program, ekspresyonu ya da alt yordam Yazın infix gösterimde gibi 1 + 2
, aynı ifadeyi verir sonek gösterimde , yani 1 2 +
.
(Not: Ocak ayında daha önce de benzer bir mücadele yayınlanmıştı. Bununla birlikte, bu ayrı meseleyi haklı çıkarmak için iki görevin yeterince farklı olduğunu düşünüyorum. sadece hepsini atmak değil.
Giriş:
Giriş oluşan geçerli bir çatı ve çatı aritmetik ifade oluşur numaraları (negatif olmayan tamsayılardır, bir ya da daha fazla ondalık haneli dizileri olarak ifade edilir), dengeli parantez gruplandırılmış bir alt ifade gösterir ve dört çatı ve çatı ikili operatörler +
, -
, *
ve /
. Bunlardan herhangi biri (ve tüm ifadeyi çevreleyen), ihmal edilmesi gereken rastgele sayıda boşluk karakteri ile ayrılabilir. 1
Resmi dilbilgisi sevenler için, geçerli girdileri tanımlayan basit bir BNF benzeri dilbilgisi. Kısalık ve açıklık için, dilbilgisi, iki belirteç arasında (bir sayıdaki rakamlar dışında) oluşabilecek isteğe bağlı alanları içermez:
expression := number | subexpression | expression operator expression
subexpression := "(" expression ")"
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
1 Boşlukların varlığının ayrıştırmayı etkileyebileceği tek durum, iki ardışık sayıyı ayırmalarıdır; bununla birlikte, bir operatör tarafından ayrılmayan iki sayı geçerli bir ek ifadesinde bulunamadığından, bu durum hiçbir zaman geçerli girdide olamaz.
Çıktı:
Çıktı, girişe eşdeğer bir postfix ifadesi olmalıdır. Çıkış ifade ile, sadece sayı ve operatörlerin oluşmalıdır tek bir boşluk karakteri aşağıdaki gramer (ki burada, komşu jeton çifti arasında etmez boşluk) 2 :
expression := number | expression sp expression sp operator
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
sp := " "
2 Yine sadelik için, number
bu gramerdeki üretim, aşağıdaki kurallara göre çıktıda yasaklanmış olsalar bile, önde gelen sıfırlarla sayıları kabul eder.
Operatör Önceliği:
Parantez yokluğunda, aşağıdaki öncelik kuralları geçerlidir:
- Operatörler
*
ve/
daha yüksek önceliğe sahiptir+
ve-
. - Operatörler
*
ve/
birbirlerine eşit önceliğe sahiptir. - Operatörler
+
ve-
birbirlerine eşit önceliğe sahiptir. - Tüm operatörler birleşiktir.
Örneğin, aşağıdaki iki ifade eşdeğerdir:
1 + 2 / 3 * 4 - 5 + 6 * 7
((1 + ((2 / 3) * 4)) - 5) + (6 * 7)
ve her ikisi de aşağıdaki çıktıyı vermelidir:
1 2 3 / 4 * + 5 - 6 7 * +
(Bunlar aynı öncelik kuralları C dilinde olduğu gibi ve bundan kaynaklanan birçok dilde bulunmaktadır. Muhtemelen, sen ilkokulda öğretilen kurallarla benzer nispi öncelik için muhtemelen hariç *
ve /
.)
Çeşitli kurallar:
Verilen çözüm bir ifade veya alt yordamsa, giriş sağlanmalı ve çıkış tek bir dize olarak döndürülmelidir. Çözüm tam bir programsa, standart girdiden infix ifadesini içeren bir satırı okumalı ve postfix versiyonunu içeren bir satırı standart çıktıya yazdırmalıdır.
Giriş sayılar olabilir gelen sıfırların. Çıktıdaki sayılar, baştaki sıfırlara sahip olmamalıdır (olduğu gibi çıkacak 0 sayısı hariç
0
).İfadeyi hiçbir şekilde değerlendirmeniz veya optimize etmeniz beklenmez. Özellikle, operatörlerin zorunlu, her türlü ortak, değişmeli veya diğer cebirsel kimlikleri sağladığını varsaymamalısınız. Yani,
1 + 2
eşittir2 + 1
ya da1 + (2 + 3)
eşittir olduğunu varsaymamalısınız(1 + 2) + 3
.Girişteki sayıların 2 31 - 1 = 2147483647 değerini aşmadığını varsayabilirsiniz .
Bu kurallar, doğru çıkışın girdi tarafından benzersiz bir şekilde tanımlanmasını sağlamak için tasarlanmıştır.
Örnekler:
İşte bazı geçerli giriş ifadeleri ve formda sunulan ilgili çıkışlar "input" -> "output"
:
"1" -> "1"
"1 + 2" -> "1 2 +"
" 001 + 02 " -> "1 2 +"
"(((((1))) + (2)))" -> "1 2 +"
"1+2" -> "1 2 +"
"1 + 2 + 3" -> "1 2 + 3 +"
"1 + (2 + 3)" -> "1 2 3 + +"
"1 + 2 * 3" -> "1 2 3 * +"
"1 / 2 * 3" -> "1 2 / 3 *"
"0102 + 0000" -> "102 0 +"
"0-1+(2-3)*4-5*(6-(7+8)/9+10)" -> "0 1 - 2 3 - 4 * + 5 6 7 8 + 9 / - 10 + * -"
(En azından, bunların hepsinin doğru olduğunu umuyorum ; dönüşümü elle yaptım, bu yüzden hatalar çarptı.)
Sadece açık olmak gerekirse, aşağıdaki girişlerin tümü geçersiz; o mu değil (tabii ki, örneğin bellek sonsuz miktarda tüketen, diyelim ki, bir hata mesajı daha güzel dönen, rağmen) çözüm onlara verdiği takdirde ne olursa olsun:
""
"x"
"1 2"
"1 + + 2"
"-1"
"3.141592653589793"
"10,000,000,001"
"(1 + 2"
"(1 + 2)) * (3 / (4)"
1 2 3 4 + *
?
1 2 3 4 +
ortalama 1 + 2 + 3 + 4`.