Presentation is loading. Please wait.

Presentation is loading. Please wait.

Bitli amallar. Ikkilik perebor. Rekursiv perebor.

Similar presentations


Presentation on theme: "Bitli amallar. Ikkilik perebor. Rekursiv perebor."— Presentation transcript:

1 Bitli amallar. Ikkilik perebor. Rekursiv perebor.
Tayyorladi: Azat Yusupov. Tatu Urganch filiali 1-kurslar tayyorgarligi, 7-dars,

2 Reja: Ikkilik sanoq sistemasi. Bitli amallar. Ikkilik perebor.
Uchlik perebor. Rekursiv ikkilik perebor.

3 Ikkilik sanoq sistemasi
Kompyuterda bajariladigan barcha arifmetik amallar ikkilik sanoq sistemasida bajariladi. Sonlar avval ikkilik sanoq sistemasiga o’tiriladi va har bir biti bo’yicha amal bajariladi. Bit sonning ikkilik sanoq sistemasidagi bitti razryadini ifodalaydi. U 0 yoki 1 ga teng bo’lishi mumkin. C++ da int tipidagi sonlarni ifodalash va ular ustida amallar 32 razriyad bo’yicha bajariladi. Masalan soni ikkilik sanoq sistemasida ga teng.

4 32 razryadga to’ldirsak:
Razryad nomerlari 0 dan 30 gacha oxiridan boshlab nomerlana- di. Masalan qizil rangli bit 6-bit hisoblanadi. Sonni ikkilik sanoq sistemasiga o’tirish. Sonni to u nol bo’lmagunga qadar ikkiga bo’lgandagi qoldiqni olib boramiz va uni teskari tartibda biror satrga qo’shib boramiz. int main() { int n; cin>>n; string s = ""; while (n > 0) { s = (char)(n % 2+48)+s; n /= 2; } cout<<s; return 0;

5 Topshiriq: dastur kodida kichik hato bor
Topshiriq: dastur kodida kichik hato bor. Uni toping, aks holda 608-masalada WA#8 olasiz. 2 likdan 10 likga o’tish uchun ikkinin darajalari bo’yicha qo’shib chiqamiz. Har bir bit o’z nomeridagi 2 ning darajasiga ko’paytiriladi. Masalan = 1*26+0*25+0*24+1*23+1*22+0*21+1*20=77. string s; cin>>s; int result = 0, pow_two = 1; for (int i = s.length()-1; i >= 0; i--) { result += (s[i]-48) * pow_two; pow_two *= 2; } cout<<result;

6 Bitli amallar Kompyuter ikkilik sanoq tizimida bitlar bilan ishlagan uchun bitli amallar tez bajatiladi. Bitli amallar unar va binar amallar bo’lishi mumkin. Unar amal bir son ustida bajarilsa, binar amal ikki son ustida bajariladi. Unar amallar. 1) Ikkining darajasiga bo’lish yoki o’ngga siljitish amali. x >> t; Bu amalda x sonini 2t ga bo’lish bajariladi. Ikkilik sanoq sitemasida bu oxiridagi t dona bitni olib tashlashni bildiradi.

7 Masalan 26 sonini 22 ga bo’lish uchun 26 ikkilikda 11010 ga teng
Masalan 26 sonini 22 ga bo’lish uchun 26 ikkilikda ga teng. Oxirgi 2 bitni o’chirsak 110->6. x=x>>t yoki qisqa yozishda x >>= t; 2) 2 ning darajasiga ko’paytirish yoki chapga siljitish amali.Ikkining darajasiga ko’paytirish uchun ikkilik sanoq sistemasida sonning daraja qancha bo’lsa shuncha nol qo’shamiz. Masalan 25 ikkilikda uni 23 ga ko’paytirsak =200. Yozilishi: x<<t. X=X<<t; X <<= t; 2n=1<<n;

8 Binar amallar 1) & (and) amali. Birinchi sonning har bir biti ikkinchi sonning mos biti bilan taqqoslanadi. Natijaviy bit qiymati ikkita bit ham 1 ga teng bo’lganda 1 ga teng bo’ladi. 1 & 1 = 1, 0 & 0 = 0, 1 & 0 = 0, 0 & 1 = 0; Masalan: 45078 = & 78574 = 12294 = Yozilishi: (45078 & );

9 2) | (or) amali. Birinchi sonning har bir biti ikkinchi sonning har bir biti bilan taqqoslanadi. Kamida bitta bitning qiymati 1 ga teng bo’lsa natijaviy bit 1 ga teng bo’ladi. 0 | 0 =0; 0 | 1 = 1; 1 | 0 = 1; 1 | 1 =1; Masalan: 45078 = | 78574 = = Yozilishi: (45078 | );

10 2) ^ (xor) amali(ikkining moduli bo’yicha qo’shish)
2) ^ (xor) amali(ikkining moduli bo’yicha qo’shish). Birinchi sonning har bir biti ikkinchi sonning har bir biti bilan taqqoslanadi.Agar ikkita bitning qiymatlari har xil bo’lsa 1 ga, bir xil bo’lsa 0 ga teng bo’ladi. 0 | 0 =0; 0 ^ 1 = 1; 1 ^ 0 = 1; 1 ^ 1 =0; Masalan: 45078 = ^ 78574 = 99064 = Yozilishi: (45078 ^ );

11 Sonning i-bitining qiymatini aniqlash
Sonning i-bitining qiymatini aniqlash uchun unin 2i bilan & amlini hisoblaymiz. Masalan = ning 3-bitini aniqlash uchun & = bitini aniqlash uchun & =

12 i-bitini o’zgartirish.0 bo’lsa 1 ga, 1 bo’lsa 0 ga.
If ((mask & (1 << i)) != 0) i-bit birga teng; else i-bit nolga teng; i-bitini o’zgartirish.0 bo’lsa 1 ga, 1 bo’lsa 0 ga. i-bitini o’zgartirish uchun (1 << i) bilan ^ (xor) amali bajaramiz; 3-bitini aniqlash uchun ^ = 4-bitini o’zgartirganda ^ =

13 i-bitini 1 ga aylantirish
i-bitini 1 ga aylantirish.(0 bo’lsa 1 ga aylantirish, 1 bo’lsa oz’ratirishsiz qoldirish). (mask | (1 << i)). Ikkilik perebor. Ikkilik pereborda eng ko’p qo’llaniladigan pereborlardan biri xisoblanadi. Bizga n ta buyum berilgan. Ulardan har birining og’irlin W[i] massiv ko’rinishida berilgan. Undan shunday buyumlarni olish kerakki, ularning og’irliklari yig’indisi berilgan S soniga teng bo’lsin(1≤n≤20). Masalan n=6, buyumlar og’irliklari 4, 7, 2, 5, 3, 2 bo’lsa, va S=7 o’g’rilikni quyidagicha usullarda olishimiz mumkin; 7, 4+3, 2+5, 5+2, jami 5 ta usul.

14 Bizda n ta buyum bor. Biz ulardan tanlash amalga oshirganimzida har bir buyum uchun ikkita variant bor, tanlangan to’plamga tegishliligi yoki tegishli emasligi. n ta razriyadli ikkilik sanoq sistemasida 0 dan 2n-1 gacha bo’lgan sonlarni ikkilikdagi kodida mumkin bo’lgan barcha kombinatsiyalar ko’riladi. Masalan n=3 bo’lsa 0 dan 23-1 gacha sonlarning ikkilik kodlari:

15 Har bir kombinatsiyada sonning ikkilik kodidagi mos belgisi 1 ga teng bo’lsa uni tegishli, 0 ga teng bo’lsa tegishli emas deb olamiz. int main() { int n; long long X; cin>>n>>X; int a[n]; for (int i = 0; i < n; i++) { cin>>a[i]; } int ans = 0; for (int mask = 0; mask < (1 << n); mask++) { long long sum = 0; if ((mask & (1 << i)) != 0) sum += a[i]; if (sum==X) ans++; cout<<ans;

16 Bu usulning ishlash vaqti O(2n n). Demak n≤20 uchun qo’llash mumkin
Bu usulning ishlash vaqti O(2n n). Demak n≤20 uchun qo’llash mumkin. Ikkilik pereborni qilishning boshqacha usuli bitli amallar ishlatmasdan, har bir sonni ikkilik sanoq tizimiga o’tkazamiz va har bir belgisini tekshirib chiqamiz:

17 char w[100]; string s; for (int mask = 0; mask < (1 << n); mask++) { long long sum = 0; itoa(mask, w, 2); s = string(w); while ((int)s.length() != n) s = "0"+s; for(int i = 0; i < n; i++) { if (s[i]=='1') sum += a[i]; } if (sum==X) ans++;

18 Yana bitta xosil qilish usuli
Har bir ikkilik ketma-ketlikni ularni leksikografik jihatdan o’sish tartibida ko’rib borish uchun har bir navbatdagi ketma- ketlikdan keyingi ketma-ketlikni topib borish kerak. Buning uchun oshirish mumkin bo’lgan eng kichik bitni topishimiz kerak, bu 0 ga teng bo’lgan eng kichik razryadli bit. Uning qiymatini 1 qilsak avvalgidan kattaroq son ketma-ketlik hosil bo’ladi, lekin eng kichigi bo’lishi uchun undan keyingi barchasini 0 ga aylantiramiz. Masalan dan keyingisi int bit[n]; for (int i = 0; i < n; i++) { bit[i] = 0; }

19 while (1) { long long sum = 0; for (int i = 0; i < n; i++) { if (bit[i]==1) sum += a[i]; } if (sum==X) ans++; int pos = -1; for (int i = n-1; i >= 0; i--) { if (bit[i]==0) { pos = i; break; if (pos==-1) bit[pos]++; for (int i = pos+1; i < n; i++) { bit[i] = 0;

20 Uchlik perebor. Uchlik sanoq sistemasida son 0,1 yoki 2 dan iborat bo’ladi. Masala: Xaridor X sumlik maxsulot sotib olmoqchi, unda n ta, har biridan ikkitadan bo’lgan qiymati a[1], a[2],…a[n] tangalar bor. U necha xil usulda berilagn X sumni xosil qilishi mumkin? Har bir tangadan olmasligi(0) yoki 1 ta olishi, yoki 2 ta olishi mumkin. Uchli sanoq sistemasidagi mumkin bo’lgan kombinat- siyalari soni 3n . Bu qiymatini pow() funksiyasisiz topish kerak. char c[100]; string s; int pow = 1; for (int i = 1; i <= n; i++) { pow *= 3; }

21 for (int mask = 0; mask < pow; mask++) {
long long sum = 0; itoa(mask, c, 3); s = string(c); while ((int)s.length() != n) s = "0"+s; for(int i = 0; i < n; i++) { sum += w[i] * (s[i]-48); } if (sum==X) ans++; cout<<ans;

22 Ikkilik rekursiv perebor.
Uchlik pereborni ham ikkilik perebordagi kami har safar keyingi ketma-ketlikni topib borish mumkin. Oshirish mumkin bo’lgan eng kichik (0 yoki 1)razriyadni topamiz, uni birga oshiramiz, undan keyingilarining barchasini 0 ga aylantiramiz. Ikkilik rekursiv perebor. Barcha ikkilik ketma ketliklarni rekursiv hosil qilish ham mumkin.

23 int a[100]; int n; void go(int pos) { if (pos==n) { for (int i = 0; i < n; i++) { cout<<a[i]; } cout<<"\n"; return; a[pos] = 0; go(pos+1); a[pos] = 1; int main() { cin>>n; go(0);

24 pos 1 1 1 1

25 0 bo’lsa chapga, 1 bo’lsa ongga tamon davom etadi.
Daraxt ko‘rinishida: 0 bo’lsa chapga, 1 bo’lsa ongga tamon davom etadi. a0 1 a1 1 1 a2 1 1 1 1 a3 1 1 1 1 1 1 1 1

26 Endi rekursiyasiz yechilgan ikkilik perebor masalasini rekursiv yechamiz. Bizda ikkita parametr kerak bo’ladi: birinchisi joriy pozitsiya, ikkinchisi hozirgi yig’indi. Joriy pozitisyaga 0 qo’yib keyingi holatga o’tishda hozirgi yig’indi o’zgarmaydi, 1 bo’lsa shu pozitsiyadagi songa ortadi. int ans = 0, n, X; int a[1000]; void go(int pos, long long s) { if (pos==n) { if (s==X) ans++; return; }

27 go(pos+1, s); go(pos+1, s+a[pos]); } int main() { cin>>n>>X; for (int i = 0; i < n; i++) { cin>>a[i]; go(0, 0); cout<<ans;

28 E’tiboringiz uchun raxmat.
Masalalar: algo.urgench-tuit.uz E’tiboringiz uchun raxmat. Savollar?


Download ppt "Bitli amallar. Ikkilik perebor. Rekursiv perebor."

Similar presentations


Ads by Google