براي کامپيوتر دو مدل از نمايش عبارات رياضي تعريف شده است: يکي (Postfix) و ديگري پيشوندي (Prefix). کامپيوتر عبارت ميانوندي (Infix) را گرفته و مدل پسوندي يا پيشوندي آن را بهدست ميآورد و نتيجه آن را محاسبه ميکند.
اما مدل پسوندي يا پيشوندي چه هستند؟
فرض کنيم عبارت ميانوندي ما A*B+C/D باشد. مدل معادل پسوندي آن بهصورت
خواهد بود و مدل پيشوندي آن بهصورت اين مدل از نمايش از تجزيه يک عبارت ميانوندي بهدست ميآيد که بر اساس تقدم عملگرها بهدست ميآيد. مثلا تقدم عملگر * از + و / جلوتر است پس زودتر محاسبه ميشود. و بين / و +، / تقدمي بيشتر دارد پس زودتر در عبارت ميآيد.
حال چگونه يک عبارت ميانوندي را به يک عبارت پسوندي تبديل کنيم؟
براي اين کار از ساختار دادهاي به نام پشته (Stack) استفاده ميکنيم. در مورد پشته پيش از اين صحبت کرديم، اما براي يادآوري:
پشته يک آرايه است که از ساختار LIFO
(Last Input First Output) پيروي ميکند، يعني اولين عنصر ورودي آخرين عنصر خروجي است. بهترين مثالي که ميتوان در مورد پشته زد اين است که فرض کنيد که چند کتاب داريد و آنها را ميخواهيد در يک کارتن قرار دهيد، کتابها را ميچينيد تا کارتن پر شود. براي دسترسي به اولين کتابي که درون کارتن قرار دادهايد نياز است که تمامي کتابها را در آورديد را در بياوريد و سپس به آن برسيد، پس اول همه را بيرون ميآوريم، سپس اولي را برميداريم. اما اگر خواستيم به آخرين کتاب دسترسي پيدا کنيم، بايد همان کتاب آخر را برداريم و براي دسترسي به آن نيازي به بيرون كشيدن کتاب ديگري نيست.
بسيار خب، همانطور که ميدانيد در زبانهاي برنامهنويسي، علايم و عملوندها داري تقدم نسبت به يکديگر هستند، مثلا عملگر () نسبت به * داراي تقدم است و همينطور * نسبت به + و ... براي مشاهده تقدم عملگرها در زبانهاي برنامهنويسي، نشاني زير را ببينيد:
http://en.wikipedia.org/wiki/Order_of_operations
پس اگر داشته باشيم a+b*c اول b در c ضرب ميشود و سپس حاصل با a جمع ميشود، حال اگر داشته باشيم که ابتدا b با c جمع ميشود و سپس حاصل در a ضرب ميشود همانطور که ميبينيد، همين تقدم عملگرها را ما در رياضي و هنگام محاسبه ذهني و دستي عبارت آن را لحاظ ميکنيم. پس چيز پيچيده وسختي نيست.
خب حال ما با استفاده از پشته و همين تقدم عملگرها يک عبارت ميانوندي را به عبارت پسوندي تبديل ميکنيم.
براي اين کار نياز به دو پشته داريم يکي که بهصورت موقت مورد استفاده قرار ميگيرد و يکي هم که نتيجه در آن قرار ميگيرد.
کاري که ما ميکنيم اين است کاراکتر به کاراكتر عبارت را ميخوانيم و اگر عدد بود، در پشته نتيجه (آن را result ميناميم) قرار ميدهيم و اگر عملوند بود در پشته موقت (آن را temp ميناميم) ذخيره ميکنيم.
پس از خواندن اولين کاراکتر مقدار result برابر 2 است و مقدار temp مقداري ندارد. پس از خواندن کاراکتر بعدي، مقدار result همان 2 ميماند و مقدار temp برابر + ميشود، در مرحله بعد مقدار result تغييري نميکند و کاراکتر ) در temp قرار ميگيرد، در مرحله بعد نيز مقدار result برابر است ولي مقدار temp بدون تغيير ميماند. اين کار به همين صورت انجام ميشود.
اگر بخواهيم براي آن قاعده کلي تعريف کنيم، به اين صورت است که ابتدا تمامي عملگرها در result قرار ميگيرند و تغييري نميکند، اما مقدار temp مدام تغيير ميکند، يعني پر و خالي ميشود و مقدار آن به result افزوده ميشود، شرط اضافه شدن آيتمي از temp به result برخورد به علامت ( يا تمام شدن کاراکترهاي عبارت رياضي است، هر وقت به يکي از اين دو عملوند رسيد، مقدار temp را در result قرار ميدهد (آيتمهاي درون temp از آن خارج ميشوند و داخل result قرار ميگيرند اين كار بهوسيله دو تابع در پشته بهنامهاي push و pop انجام ميشود، push بهمعناي وارد کردن و pop به معناي
خارجکردن است).
نکتهاي که بايد به آن دقت کنيد اين است زماني يک عملوند به temp اضافه شود که اولويت آن از اولويت آخرين عضو temp کمتر باشد، اگر بيشتر بود به result منتقل ميشود.
براي مثال بالا پس از پايان مراحل وقتي به کاراکتر ( رسيديم، مقدار result برابر abc است و مقدار temp برابر +/)+ است و بعد از اين مرحله آنقدر آيتم از temp خارج ميشود که تا به اولين) برسيم در نتيجه پس از اين مرحله مقدار result برابر /
abc2+ ميشود و چون کاراکترها به پايان رسيده، همه آيتمهاي موجود در temp به result اضافه ميشود، که عبارت حاصل برابر با /abc2+ خواهد شد.
امير بهاالدينسبطالشيخ