Ketika saya melihat judul pertanyaan tertutup ini , saya pikir itu tampak seperti tantangan kode golf yang menarik. Jadi izinkan saya menyajikannya sebagai berikut:
Tantangan:
Tulis sebuah program, ekspresi atau subrutin yang, diberi ekspresi aritmetika dalam notasi infiks , seperti 1 + 2
, menghasilkan ekspresi yang sama dalam notasi postfix , yaitu 1 2 +
.
(Catatan: Tantangan serupa telah diposting sebelumnya pada bulan Januari. Namun, saya merasa kedua tugas tersebut cukup berbeda secara detail untuk membenarkan tantangan terpisah ini. Juga, saya hanya melihat utas lainnya setelah mengetik semua yang di bawah ini, dan saya lebih suka tidak hanya membuang semuanya.)
Memasukkan:
Input terdiri dari infix ekspresi aritmatika yang valid terdiri dari angka (bilangan bulat non-negatif direpresentasikan sebagai urutan satu atau lebih desimal digit), seimbang kurung untuk menunjukkan subexpression dikelompokkan, dan empat infiks biner operator +
, -
, *
dan /
. Semua ini dapat dipisahkan (dan seluruh ekspresi dikelilingi) oleh sejumlah karakter spasi, yang harus diabaikan. 1
Bagi mereka yang menyukai tata bahasa formal, inilah tata bahasa sederhana seperti BNF yang mendefinisikan input yang valid. Untuk singkatnya dan kejelasan, tata bahasa tidak termasuk spasi opsional, yang dapat terjadi antara dua token (selain dari digit dalam angka):
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 Satu-satunya kasus di mana keberadaan spasi dapat mempengaruhi penguraian adalah ketika mereka memisahkan dua angka berurutan; Namun, karena dua angka yang tidak dipisahkan oleh operator tidak dapat terjadi dalam ekspresi infiks yang valid, kasus ini tidak akan pernah terjadi pada input yang valid.
Keluaran:
Outputnya harus berupa ekspresi postfix yang setara dengan input. Ekspresi output hanya boleh terdiri dari angka dan operator, dengan karakter spasi tunggal antara setiap pasangan token yang berdekatan, seperti dalam tata bahasa berikut (yang tidak termasuk spasi) 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 Sekali lagi untuk kesederhanaan, number
produksi dalam tata bahasa ini mengakui angka dengan nol di depan, meskipun mereka dilarang dalam output oleh aturan di bawah ini.
Diutamakan operator:
Dengan tidak adanya tanda kurung, aturan diutamakan berikut ini berlaku:
- Operator
*
dan/
memiliki prioritas lebih tinggi daripada+
dan-
. - Operator
*
dan/
memiliki prioritas yang sama satu sama lain. - Operator
+
dan-
memiliki prioritas yang sama satu sama lain. - Semua operator bersifat asosiatif kiri.
Misalnya, dua ekspresi berikut ini setara:
1 + 2 / 3 * 4 - 5 + 6 * 7
((1 + ((2 / 3) * 4)) - 5) + (6 * 7)
dan keduanya harus menghasilkan output berikut:
1 2 3 / 4 * + 5 - 6 7 * +
(Ini adalah aturan presedensi yang sama seperti dalam bahasa C dan dalam sebagian besar bahasa yang berasal darinya. Mereka mungkin menyerupai aturan yang diajarkan pada Anda di sekolah dasar, kecuali mungkin untuk diutamakan relatif dari *
dan /
.)
Aturan lain-lain:
Jika solusi yang diberikan adalah ekspresi atau subrutin, input harus diberikan dan output dikembalikan sebagai string tunggal. Jika solusinya adalah program yang lengkap, ia harus membaca baris yang berisi ekspresi infiks dari input standar dan mencetak baris yang berisi versi postfix ke output standar.
Angka dalam input mungkin termasuk nol di depan. Angka dalam output tidak boleh memiliki nol di depannya (kecuali untuk angka 0, yang akan menjadi output sebagai
0
).Anda tidak diharapkan untuk mengevaluasi atau mengoptimalkan ekspresi dengan cara apa pun. Secara khusus, Anda tidak boleh berasumsi bahwa operator harus memenuhi identitas aljabar, komutatif, atau lainnya. Artinya, Anda tidak boleh berasumsi bahwa eg
1 + 2
sama dengan2 + 1
atau1 + (2 + 3)
sama dengan itu(1 + 2) + 3
.Anda dapat berasumsi bahwa angka dalam input tidak melebihi 2 31 - 1 = 2147483647.
Aturan-aturan ini dimaksudkan untuk memastikan bahwa output yang benar didefinisikan secara unik oleh input.
Contoh:
Berikut adalah beberapa ekspresi input yang valid dan output yang sesuai, yang disajikan dalam formulir "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 + * -"
(Setidaknya, saya harap semua ini benar; Saya melakukan pertobatan dengan tangan, sehingga kesalahan mungkin merayap masuk.)
Supaya jelas, input berikut semuanya tidak valid; itu tidak peduli apa solusi Anda tidak jika diberikan mereka (meskipun, tentu saja, misalnya kembali pesan kesalahan lebih bagus daripada, katakanlah, mengkonsumsi jumlah tak terbatas memori):
""
"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 +
berarti `1 + 2 + 3 + 4`.