bit 0 1

مجموعه بیتی (bitset) در ++C

در ++C ما گزینه های مختلفی برای نگه داری داده ها داریم. مانند کلاس های stack ، set ، map ، bitset ، vector . فقط کافی است نوع داده خود را مشخص کنید و سپس آن یکی را که مناسب کار شما است انتخاب کنید و یا حتی در صورت لزوم با استفاده از قابلیت ارث بری آن را گسترش بدهید؛ شاید هم بخواهید نوع داده انتزاعی خود را برای نگه داری داده های تان به وجود بیاورید. در هر حال به شما پیشنهاد می کنم مطالب قبلی ما را در درباره داده ساختار ها بخوانید و مطالب آینده را پیگیری کنید!

در این مطلب سعی شده است که کلاس bitset و ویژگی ها و استفاده هایش بررسی شود و چند مثال از آن ها را ببینیم.

bit 0 1

مجموعه بیتی برای نگه داری بیت هاست (۰ و ۱). شاید در همین ابتدا به من بگویید من که می دانم چطور یک آرایه اعداد صحیح یا کاراکتر تعریف کنم و تعدادی صفر و یک را در آن جا دهم! اما باید بدانید که کلاس bitset  برای استفاده از کمترین مقدار حافظه بهینه سازی شده است و در واقع روش کار آن به این صورت است که آرایه ای از نوع داده boolean را که فقط یک بایت حافظه برای ذخیره سازی هر عنصر نیاز دارد، ایجاد می کند. فرض کنیم می خواهیم آرایه ای چهار عضوی از بیت ها را ذخیره کنیم؛ با آرایه ای از اعداد صحیح ما (۸*۴)*۴ بیت ، با آرایه ای از کاراکتر ها ۸*۴ بیت و با کلاس bitset هم ۸*۴ بیت برای ذخیره سازی آرایه مان نیاز داریم! اما این همه اش نیست! مزیت دیگر استفاده ار مجموعه بیتی، method های تعریف شده در این کلاس است که کار با اعداد دودویی را بسیار راحت می کند. برای مثال تبدیل اعداد دهدهی به دودویی و برعکس، ایجاد مقدار هش شده از عدد دودویی، چاپ یکباره کل آرایه روی خروجی، به دست آوردن تعداد یک های موجود در آرایه و … تنها با یک فراخوانی انجام می شود!

[box type=”info”] برای استفاده از مجموعه بیتی در برنامه ++C تان لازم است که سرفایل  <bitset> را وارد کرده باشید و توجه کنید که نام کلاس bitset در فضای نام  std قرار دارد.[/box]

کار را با تعریف یک مجموعه بیتی آغاز می کنیم! برای تعریف، لازم است که تعداد بیت هایی که می خواهیم این شئ در خود نگه دارد را داشته باشیم (که اینجا برای مثال، ۸ بیت در نظر گرفته شده است).

حالا بیایید روش های مقدار دهی را ببینیم. ابتدا مفدار دهی با استفاده از تابع سازنده:

(در تمام حالت های زیر مجموعه بیتی تعریف شده را با مقدار دودویی ۱۱۱۱۱۱۱۱ معادل ۲۵۵ دهدهی، مقدار دهی کرده ایم.)

همانطور که می بینید در چهار حالت از تابع سازنده برای مقداردهی استفاده کرده ایم؛ مقداردهی با عدد دهدهی، با عدد شانزده شانردهی، با رشته زبان سی پلاس پلاس، با رشته زبان سی و با یک محموعه بیتی هم اندازه که مقدار دهی شده، انجام شده است. هنگام مقداردهی این مجموعه با اعداد غیر دودویی، معادل دودویی آن به اندازه تعریف شده برای مجموعه، از بیت کم ارزش به بعد در آن ذخیره می شود(پس بهتر است مطمئن باشید اندازه ای که تعریف کردید بیشتر یا مساوی اندازه بیت های مقدار داده شده در مبنای دو است).

حالا مقدار دهی بعد از تعریف کردن یک شئ از مجموعه بیتی:

عملگر = که در سی پلاس پلاس کار انتساب را انجام می دهد برای انتساب اعداد دهدهی،اعداد شانزده شانزدهی و مجموعه بیتی به یک مجموعه بیتی سربارگذاری (overload) شده است. بنابراین شما می توانید یک عدد دهدهی یا شانزده شانزدهی را به صورت مستقیم به یک مجموعه بیتی منتسب کنید و مقدار دودویی آن عدد در مجموعه بیتی جای می گیرد. اما درباره انتساب یک مجموعه بیتی به یک مجموعه بیتی شما می توانید یک شئ از قبل تعریف شده یا یک شئ موقت را در سمت راست عملگر انتساب قرار دهید البته باید توجه کنید که آن شئ اندازه ای برابر با با شئ سمت چپ داشته باشد وگرنه از کامپایلر خطا دریافت می کنید. تغییر مقدار یک مجموعه بیتی مشابه حالت های مقدار دهی بعد از تعریف انجام می شود.

[box type=”warning”] توجه کنید که رشته هایی که قرار است مجموعه بیتی را مقداردهی کنند فقط می توانند حاوی مقادیر ۰ و ۱ باشند.[/box]

[box type=”info”] اگر شما مجموعه بیتی را مقداردهی نکنید، در ابتدا تمام بیت هایی که شما تعدادشان را مشخص کرده اید برابر صفر خواهند بود. در ضمن اگر تعداد بیت های معادل دودویی یک مقدار ( و یا اندازه رشته ای ) که به مجموعه بیتی انتساب داده اید از اندازه واقعی آن مجموعه کمتر باشد، بیت های پایینی به درستی مقدار می گیرند و بیت های بالایی هم ۰ خواهند شد.[/box]

عملگر های بیتی هم برای مجموعه های بیتی سربارگذاری شده است؛ که این می تواند بسیار پر استفاده باشد.

عملگر [] آخرین عملگر مورد بحثی است که برای کلاس  bitset سربارگذاری شده است. عملکرد آن هم مثل کاری است که در آرایه ها انجام می دهد؛ یعنی دسترسی به یک عضو از مجموعه!

 

فعلاً مطلب را با بررسی چند method از کلاس  bitset و یک نکته تمام می کنیم اما امیدوارم با کمک نظرات و سوال های شما، در روز های آینده مثال و توضیح های بیشتری به این مطلب مفید اضافه کنیم.

()bitset::count یک عدد صحیح به عنوان تعداد بیت های سِت شده (برابر با ۱) را بر می گرداند.

()bitset::size یک عدد ضحیح به عنوان اندازه مجموعه بیتی را که در هنگام تعریف آن را مشخص کرده اید، بر می گرداند.

(bitset::test(i یک مقدار boolean به عنوان ارزش عنصر شماره i را بر می گرداند (  true اگر ۱ باشد و   false اگر ۰ باشد).

()bitset::any یک مقدار boolean بر می گرداند که اگر  true باشد یعنی حداقل یک بیتِ سِت شده (برابر با ۱) در مجموعه وجود دارد و اگر  false باشد یعنی تمام بیت ها ۰ هستند.

()bitset::none عملکردی متضاد با  ()any دارد. در صورتی که مقدار خروجی آن   true باشد یعنی هیچ کدام از بیت های مجموعه ۱ نیستند و اگر  false باشد یعنی حداقل یک بیتِ ست شده وجود دارد.

()bitset::all این method در ۱۱++C اضافه شده است و با فراخوانی آن، بررسی می کند که آیا تمام بیت های مجموعه سِت شده اند یا نه و به ترتیب مقادیر  true و false می تواند خروجی این فراخوانی باشد.

در کامپایلری که ۱۱++C را پشتیبانی می کند به راحتی با دستور ()bitsArray.to_string و یا در ۹۸++C با دستور

می توانید یک رشته تحویل بگیرید که حاوی بیت های مجموعه بیتی مثالی ما یعنی bitsArray است. بیت ها هم به همان ترتیبی در رشته قرار می گیرند که در یک جریان خروجی با عملگر  >> ، قرار می گیرند.

()bitset::to_ulong یک مقدار unsigned long int (عدد صحیح بزرگ بدون علامت) بر می گرداند. اگر مقدار دهدهی معادل مجموعه بیتی از ظرفیت  unsigned long int بیشتر باشد، یک Exception رخ می دهد.

()bitset::to_ullong در ۱۱++C اضافه شده است و یک مقدار unsigned long long int (عدد صحیح بسیار بزرگ بدون علامت) بر می گرداند.

 

نکته پایانی:

همانطور که دیدید کلاس  bitset ، پویا نیست؛ به این معنی که اندازه شئ ای که می خواهید بسازید را باید در هنگام تعریف به صورت مشخص بدانید تا حافظه لازم برای آن در شروع اجرای برنامه تخصیص داده شود و در ادامه هم نمی تواند تغییر کند. اگر به یک مجموعه بیتی پویا نیاز دارید باید بگویم متاسفانه در کتابخانه استاندارد ++C آن را نداریم اما به لطف کتابخانه های Boost برای ++C می توانید مجموعه بیتی پویا داشته باشید! به اینجا سری بزنید!

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

۵ دیدگاه

  • سلام
    مجموعه بیتی برای هر کدام از عناصر، یک بایت اختصاص میده؟ یعنی یک بایت به ازای یک بیت؟!
    یا وقتی مینویسم bitset با اندازه ی ۸ آیا میزان حافظه ی مصرفی یک بایته یا ۸ بایت؟!

    • فرهاد دلیرانی

      سوال خیلی خوبی کردی!

      در بیت ست وقتی می نویسیم

      ۳۲ بایت می شود! ولی می خواهید آن را به صورتی درآورید که سی و دو بیت بگیرد؟

      از تابع

      toint32

      مجموعه ی بیت ست استفاده کن – سی و دو بیت را کتار هم می گذارد و عدد صحیح معادلش را می دهد اینگونه هر بیت دقیقا سی و دو بیت مصرف می کند

      مثالا
      ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۱۰
      وقتی به عدد صحیح تبدیل شود می شود عدد
      ۲
      – یک عدد صحیح اندازه اش سی و دو بیت است و ما هم سی و دو بیت لازم داشتیم پس مشکل حل شد

  • Pingback: محاسبه ی باقی مانده ی توان یک عدد – Modular Exponentiation | برنامه نویسی و الگوریتم

  • منون از پست مفیدتون.
    برای اینکه هی ننویسیم bitset::count مثلا باید namespace معرفی کنیم؟؟؟
    و یه سوال اینکه bitset برای استفاده اش باید چی رو به برنامه include کنیم؟
    <<<>>>
    خیلی.ممنون! 🙂
    ^_^

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *