เมื่อฉันเห็นชื่อของคำถามที่ปิดนี้ฉันคิดว่ามันดูเหมือนการแข่งขันกอล์ฟที่น่าสนใจ ดังนั้นฉันขอเสนอเป็นเช่นนี้:
ท้าทาย:
เขียนโปรแกรมการแสดงออกหรือย่อยซึ่งได้รับการแสดงออกเกี่ยวกับคณิตศาสตร์ในสัญกรณ์มัดเช่น1 + 2
ผลลัพธ์ที่ได้แสดงออกเหมือนกันในสัญกรณ์ postfix1 2 +
คือ
(หมายเหตุ: ความท้าทายที่คล้ายกันถูกโพสต์เมื่อต้นเดือนมกราคม อย่างไรก็ตามฉันรู้สึกว่างานทั้งสองนั้นมีความแตกต่างกันพอสมควรเพื่อแสดงให้เห็นถึงความท้าทายที่แยกต่างหากนี้นอกจากนี้ฉันสังเกตเห็นหัวข้ออื่นหลังจากพิมพ์ทุกอย่างด้านล่าง ไม่เพียงทิ้งมันไป)
การป้อนข้อมูล:
การป้อนข้อมูลประกอบด้วยมัดที่ถูกต้องแสดงออกคณิตศาสตร์ซึ่งประกอบด้วยตัวเลข (จำนวนเต็มไม่เป็นลบแสดงเป็นลำดับหนึ่งหรือตัวเลขทศนิยมเพิ่มเติม) สมดุลวงเล็บเพื่อระบุ subexpression จัดกลุ่มและสี่มัดไบนารีผู้ประกอบการ +
, -
, และ*
/
สิ่งเหล่านี้อาจถูกแยกออก (และนิพจน์ทั้งหมดล้อมรอบ) ด้วยจำนวนช่องว่างโดยพลการซึ่งควรละเว้น 1
สำหรับผู้ที่ชื่นชอบไวยากรณ์อย่างเป็นทางการนี่เป็นไวยากรณ์ที่เหมือน BNF ง่าย ๆ ที่กำหนดอินพุตที่ถูกต้อง เพื่อความกระชับและชัดเจนไวยากรณ์จะไม่รวมช่องว่างเพิ่มเติมซึ่งอาจเกิดขึ้นระหว่างโทเค็นใด ๆ สอง (นอกเหนือจากตัวเลขภายในตัวเลข):
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กรณีเดียวที่มีช่องว่างอาจส่งผลกระทบต่อการแยกคือเมื่อพวกเขาแยกสองหมายเลขติดต่อกัน; อย่างไรก็ตามเนื่องจากตัวเลขสองตัวที่ไม่ได้คั่นด้วยตัวดำเนินการไม่สามารถเกิดขึ้นในนิพจน์มัดที่ถูกต้องกรณีนี้จะไม่เกิดขึ้นในอินพุตที่ถูกต้อง
เอาท์พุท:
เอาต์พุตควรเป็นนิพจน์ postfix ที่เทียบเท่ากับอินพุต การแสดงออกการส่งออกควรจะมีเพียงของตัวเลขและผู้ประกอบการที่มีอักขระช่องว่างเดียวระหว่างคู่ของสัญญาณที่อยู่ติดกันแต่ละเช่นเดียวกับในไวยากรณ์ต่อไปนี้ (ซึ่งไม่รวมถึงช่องว่าง) 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อีกครั้งเพื่อความเรียบง่ายการnumber
ผลิตในไวยากรณ์นี้ยอมรับตัวเลขด้วยเลขศูนย์นำหน้าแม้ว่าจะถูกห้ามในผลลัพธ์ตามกฎด้านล่าง
ผู้ประกอบการที่มีความสำคัญ:
ในกรณีที่ไม่มีวงเล็บจะใช้กฎที่สำคัญกว่าดังต่อไปนี้:
- ผู้ประกอบการ
*
และ/
มีความสำคัญสูงกว่าและ+
-
- ผู้ประกอบการ
*
และ/
มีความสำคัญเท่าเทียมกัน - ผู้ประกอบการ
+
และ-
มีความสำคัญเท่าเทียมกัน - ผู้ประกอบการทั้งหมดมีความสัมพันธ์ด้านซ้าย
ตัวอย่างเช่นสองนิพจน์ต่อไปนี้เทียบเท่า:
1 + 2 / 3 * 4 - 5 + 6 * 7
((1 + ((2 / 3) * 4)) - 5) + (6 * 7)
และควรให้ผลลัพธ์ต่อไปนี้:
1 2 3 / 4 * + 5 - 6 7 * +
(เหล่านี้เป็นกฎความสำคัญเช่นเดียวกับในภาษา C และในภาษาส่วนใหญ่ได้มาจากมัน. พวกเขาอาจจะมีลักษณะคล้ายกับกฎที่คุณได้รับการสอนในโรงเรียนประถมยกเว้นอาจจะเป็นเพราะความสำคัญของญาติ*
และ/
.)
กฎเบ็ดเตล็ด:
หากวิธีการแก้ปัญหาที่ได้รับคือการแสดงออกหรือรูทีนย่อยควรป้อนข้อมูลและการส่งออกกลับเป็นสตริงเดียว หากการแก้ปัญหาเป็นโปรแกรมที่สมบูรณ์ก็ควรอ่านบรรทัดที่มีการแสดงออกของ infix จากอินพุตมาตรฐานและพิมพ์บรรทัดที่มีรุ่น postfix ไปยังเอาต์พุตมาตรฐาน
ตัวเลขในอินพุตอาจรวมศูนย์นำหน้าด้วย ตัวเลขในเอาต์พุตต้องไม่มีศูนย์นำหน้า (ยกเว้นสำหรับหมายเลข 0 ซึ่งจะเป็นเอาต์พุต
0
)คุณไม่คาดว่าจะประเมินหรือปรับการแสดงออกในทางใดทางหนึ่ง โดยเฉพาะอย่างยิ่งคุณไม่ควรสันนิษฐานว่าผู้ปฏิบัติงานจำเป็นต้องมีความเกี่ยวข้องกับการเชื่อมโยงการสับเปลี่ยนหรืออัตลักษณ์เชิงพีชคณิตอื่น ๆ นั่นคือคุณไม่ควรคิดว่าเช่น
1 + 2
เท่ากับ2 + 1
หรือเท่ากับ1 + (2 + 3)
(1 + 2) + 3
คุณอาจคิดว่าตัวเลขในอินพุตไม่เกิน 2 31 - 1 = 2147483647
กฎเหล่านี้มีจุดประสงค์เพื่อให้แน่ใจว่าผลลัพธ์ที่ถูกต้องนั้นถูกกำหนดไว้อย่างไม่ซ้ำกันโดยอินพุต
ตัวอย่าง:
ต่อไปนี้เป็นนิพจน์อินพุตที่ถูกต้องและเอาต์พุตที่สอดคล้องกันซึ่งแสดงในรูปแบบ"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 + * -"
(อย่างน้อยฉันก็หวังว่าสิ่งเหล่านี้จะถูกต้องฉันทำเรื่องเปลี่ยนใจเลื่อมใสด้วยมือดังนั้นความผิดพลาดอาจพุ่งเข้ามา)
เพื่อให้ชัดเจนอินพุตต่อไปนี้ไม่ถูกต้องทั้งหมด มันไม่สำคัญว่าโซลูชันของคุณจะทำอย่างไรหากมอบให้ (แม้ว่าแน่นอนเช่นการส่งคืนข้อความแสดงข้อผิดพลาดจะดีกว่าพูดใช้หน่วยความจำไม่ จำกัด จำนวน):
""
"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 +
หมายถึง `1 + 2 + 3 + 4`