دکتر زینگ

الگوریـــتـم

۲ مطلب با کلمه‌ی کلیدی «عملگرهای بیتی» ثبت شده است

442 - Matrix Chain Multiplication

دسته  : ad hoc


توضیح سوال: ابتدای ورودی لیستی از ماتریس ها که شامل نام و اندازه ی ماتریس ها می باشد داده می شود. اسم ماتریس حروف بزرگ می باشد که از ۲۶ تا ماتریس بیشتر نمی تواند باشد. بعد از آن لیستی شامل پرانتز ها و  اسامی ماتریس ها داده می شود که شما می بایست تعداد عملیاتی که برای محاسبه ی این عبارت انجام می شود را به عنوان خروجی چاپ کنید این نکته هم نباید فراموش شود که ممکن است عبارت قانون ضرب ها را رعایت نکند که در این صورت باید error چاپ شود.

در سوال بر اساس Extended Backus–Naur Form قوانینی که بر اجرای آنها تاکید شده است داده شده که بدین شرح است.


SecondPart = Line { Line } <EOF>
Line       = Expression <CR>
Expression = Matrix | "(" Expression Expression ")"
Matrix     = "A" | "B" | "C" | ... | "X" | "Y" | "Z"
براساس Extended Backus–Naur Form :
 
=            defining-symbol تعریف
{ ... }                      repetition تکرار
|                    alternation ترتیب
 


نکات خوبی از این قوانین میشه استخراج کرد برای مثال از قسمت Expression که به صورت بازگشتی تعریف شده میشه فهمید که داخلی ترین پرانتز فقط شامل دو ماتریس است نه کمتر و نه بیشتر.

.

توضیح راه حل: اگر شما بتوانید از پس نمونه ورودی های این سوال بر بیایید به راحتی Accepte این سوال رو خواهید گرفت. برای اطمینان summation یا به عبارت دیگر خروجی را long long بگیرید. 

کاری که می بایست انجام دهید این است که شروع به وارد کردن عبارت در داخل stack کنید. زمانی که به '(' رسیدید باید به پردازش دو عنصر آخر که حتما دو ماتریس است بپردازید و بعد سومین عنصر آخر stack که ')' به همراه دو ماتریس از stack خارج کنید و ماتریس حاصلشان را داخل stack قرار دهید.

با استفاده از یک vector از نوع pair می توانید به ماتریس های  لیست اول ورودی و ماتریس های جدیدی که در عبارت بوجود می آید دسترسی پیدا کنید.

 پیشنهاد من این است که نوع stack از نوع int  باشد که در این صورت ماتریس ها را با ایندکس vector و ')' را منفی یک قرار دهید.

۰ نظر موافقین ۰ مخالفین ۰
امیرحسین رجبی

عملگرهای بیتی (بخش اول)

مقدماتی :

 یکی از مباحثی که همیشه به عنوان حاشیه در کلاس های آموزشی برنامه نویسی آموزش داده میشود عملیات بیتیست (bitwise operation )  که به نظر من یکی از مهم ترین مفاهیمی است که می تواند یک برنامه نویس حرفه ای را از یک برنامه نویس معمولی متمایز سازد.

خلاصه ای از این عملگرها را در زیر می بینید : 

01001000 &     01001000 |     01110010 ^         
10111000 =     10111000 =     10101010     01110010 !
--------      --------    --------     --------  
00001000        11111000        11011000      10001101  
 01110010 >>     01110010 <<
--------      --------
00111001        11100100

متوسط :

چند هم ارز با استفاده از عملگر های بیتی:

  1. x % 2 :                                                  x&1
  2. pow( 2 , k ) :                                        1<<k
  3. x % pow(2 , k )   :                                x & ( (1<<k) - 1 )
  4. x* 2k  :                                                 x<<k 
  5. x / 2k :                                                  x>>k

 در بعضی از سوالات می توان با استفاده از این عملگرها فرایند مارک کردن یا به طور کلی فرایندهایی که شامل ۲ حالت ۰ و ۱  با وسعتی کمتر از۳۱  میباشد را بهینه کرد. برای این کار نیاز است که به تک تک بیت های متغیر دسترسی داشته باشیم و عملیات دلخواه را روی بیت انجام دهیم که در زیر به سه تا از مهمترین آنها اشاره کردم.


To “set” a bit :               a |= (1 << n);                                                             قرار دادن ۱

To “clear” a bit:            b &= ~(1 << n);                                                         قرار دادن ۰

To “toggle” a bit:          c ^= (1 << n);                         جایگزین کردن یک با صفر  ـ یا بالعکس


 پیشرفته:

ماسک کردن:‌

فرض کنید که می خواهیم باقیمانده ی یک عدد بزرگ  (برای مثال  ۱۲۳۴۵۶۷۸۹۰۱۲۳۴۵۶۷۸۹۰۱۲۳۴۵۶۷۸۹۰) به ۱۰۰۰۰۰ را بدست آوریم. چیزی که اینجا مشهود است نیازما تنها به چند رقم سمت راست است. ‍پس می توانیم برای overflow نکردن همواره چند رقم اول را نگه داریم. این عمل را من ماسک کردن می نامم.

   هدف از تعریف کردن ماسک این است که در بعضی از سوالات تقریبا Big number که در ادامه ی سورس متغیر با عملیات بیتی سر و کار دارد ابتدا می توانیم ماسک را بدین صورت تعریف کنیم.

#define MASK 0xFF. . .FFFF  (به مقدار لازم )

این عبارت برابر عدد ۱ . . .۱۱۱۱ می باشد.


سپس در طول برنامه (جاهایی که با افزایش متغیر همراه هستیم) از عبارت زیر استفاده می کنیم :

x &= MASK;


این عمل از overflow شدن متغیر جلوگیری می کند.


۰ نظر موافقین ۰ مخالفین ۰
امیرحسین رجبی