Musobaqa masalalarini ishlashdagi ko'p uchraydigan xatolar

Rasm manbasi: sitepoint.com

"The error of the past is wisdom of the future" - Dale Turner.
"O'tmishdagi xato - kelajakda donolik bo'ladi"

I qism. 2-dars

Oldingi postimizda dasturlash musobaqalarida (contestlar) eng ko'p ishlatiladigan dasturlash tillari haqida gaplashgan edik. Bugun algoritmik masalalarni yechib, uni online test tizimlariga tekshirgani jo'natganda ko'p uchrab turadigan xatolar haqida gaplashmoqchimiz. Bu xatolarning ba'zilari, asosan, boshlovchi dasturchilar tomonidan yo'l qo'yilsa, ba'zilari hatto professional dasturchilar yechimlarida ham uchrab turadi.

a. Ortiqcha chiquvchi (output) ma'lumotlar yoki uning to'g'ri bo'lmasligi

Online test tizimlarida testlar input/output ko'rinishida taqdim etiladi.

Input/Output misoli

Yuqoridagi misolda w sonini kiritishda, "w: " yoki "w sonini kiriting ", "Enter the w: " kabi iboralarni ekranga chiqarish xatolikka olib keladi va yechim to'g'ri bo'lgan taqdirda ham sizning javobingiz qabul qilinmaydi. Shuning uchun hech qanday ortiqcha shartlarsiz shunchaki songa to'g'ri tip tanlang va uni o'qib oling (C++ da cin yoki scanf bilan, Javada Scanner yoki BufferedReader bilan).

Ha aytgancha, w uchun berilgan chegara uning uchun to'g'ri tip (int, long long, __int64, string, double) tanlash uchun. Bunda kiritishda hech qanday ortiqcha shart qo'shish kerak emas.

Bundan tashqari, chiquvchi javob aynan berilgan misoldan ozgina farq qilishi (nuqta, vergul, ikki nuqtalar ham shular qatorida) ham sizning yechimingiz xato (wrong answer) deb topilishiga olib keladi. Bunda kichik-katta harflar ham juda muhim. Yuqoridagi misolda javobni "Yes" shaklida chiqarish ham xato hisoblanadi. Eng yaxshisi javobni berilgan misoldan nusxalab (CTRL + C) qilib chiquvchi javobga qo'ying.

b. Hisob-kitoblar tipga mos kelmay qolishi.

Quyidagi misolga e'tibor bering:

Chiquvchi javob: 1410065408 bo'ladi. Kutilgandek 10 000 000 000 emas.

Chunki ikki int tipidagi son bir-biriga ko'paytirilgan paytda hosil bo'luvchi javob ham int bo'ladi va u long longga o'zlashtirilayotgan paytda ham int bo'lib turadi. Shuning uchun ikki int ko'paytmasi (ba'zan yig'indisi ham) int chegarasiga (2^31-1 yoki soddaroq holda 10^9) sig'may qolishi mumkin. Bu xatoni ko'paytmaga 1LL ni ko'paytirish orqali hal qilish mumkin:

Chiquvchi javob: 10000000000

Huddi shuningdek:

Chiquvchi javob: 6. Kutilganidek 6.75 emas.

Bu xato ham yuqoridagi bilan deyarli bir xil. Ikkita butun son bo'linmasi butun son bo'ladi. Shuning uchun ham c ga 6 o'zlashtiriladi. Bu xatoni ham yuqoridagi kabi oldini olish mumkin.

Bunda 1.0* sonni double aylantirib beradi. Bundan tashqari ifodani o'zlashtirilayotgan tipga cast yo'li bilan ham almashtirish mumkin.

Ammo, bu yo'l sal ko'proq kod yozishni talab qiladi.)

c. Son kiritilgandan keyingi kiritilgan bitta satr yo'q bo'lib ketishi

Quyidagi kodga e'tibor qarating:

Kiruvchi ma'lumot:

4

abc

bca

cba

acb

Chiquvchi ma'lumot:

0

3 abc

3 bca

3 cba

E'tibor bergan bo'lsangiz, birinchi kiritilgan satr bo'sh va shuning hisobiga oxirgi kiritilgan satr qolib ketyapti. Buning sababi biz 4 sonini kiritib Enter bosgan paytimiz kiruvchi ma'lumot "4 " ko'rinishida bo'ladi va 4 soni n ga o'zlashtirilib, " " yangi satr belgisi keyingi birinchi satrga o'zlashtirilib qoladi. Bunday xato Javada ham uchraydi.

Buni oldini olishning eng oddiy usuli cin >> n dan keyin bitta ortiqcha getline qo'yish va uning qiymati shunchaki qolib ketaveradi. (Javada scan.nextInt() keyin bitta ortiqcha scan.nextLine() qo'yish). Yoki C++ da cin.ignore() ni ishlatish:

d. double va floatni taqqoslashdagi xatolik

Eng yaxshisi yana misol keltiramiz:

Yuqoridagi kod ko'p hollarda to'g'ri ishlaydi va "Yes" chiqaradi. Lekin, kompyuterlar haqiqiy sonlar bilan ishlashda ba'zida 1e-07 aniqlikda xato qilish ehtimoli bor va bu tez tez uchrab turadi. Bunday xatoni esa kod ichidan aniqlash juda qiyin.

Bu kichkinagina xato nafaqat olimpiadalarda, balki qiymat yuqori aniqligi muhim bo'lgan bank, koinot, kimyo sohalarida katta muammolar keltirib chiqarishi mumkin. Uni quyidagi usulda oldini olish mumkin (bank, koinot, kimyo sohalarida emas albatta)

Eng sodda usul:

Bunda mashina hisob-kitobida yuz berishi mumkin bo'lgan juda kichik xatolar e'tiborga olinmay o'tib ketiladi.

e. Runtime dagi xatolar (RE)

Dastur to'g'ri kompilyatsiya bo'lgan taqdirda ham uning ishlash vaqtida ham xatolik, yoki aniqroq aytadigan bo'lsak chetlashish (exception) yuz berishi mumkin. Bunda online hakamlar Runtime Error (RE) ni ko'rsatadi. Bular ichidagi dasturlash musobaqalarida eng ko'p uchrab turadiganlari:

  1. Segmentation Fault. Bu xato kompyuter xotirasiga noto'g'ri murojaat bo'lganda yuzaga keladi, asosan, massivning chegarasidan tashqaridagi elementiga murojaat qilinganda yoki vector ni instalyatsiya qilmay turib uning elementi chaqirilganda yuz berishi mumkin. Bu asosan sikl orasida yuz berish ehtimoli yuqori.
  2. 0 ga bo'linganda yoki modul olinganda sodir bo'ladigan arifmetik xato. Bunday xatolik ham asosan sikl minusdan plusga oraliqda iteratsiya bo'lgan paytda yuz berishi mumkin.
  3. 10^8 hajmdan ortiq massiv e'lon qilish.

Runtime xatolarini aniqlashning eng yaxshi yo'li, bu Debugging qilish. Buning uchun ishlayotgan tilingizga mos yaxshi IDE bo'lishi maqsadga muvofiq (Visual Studio, Intellij Idea, PyCharm va h.k.)

f. Vaqt limitidan o'tib ketish (TL)

Agar yechimingiz uchun Time Limit Exceeded (TL) natijasi chiqsa, demak tuzgan algoritmingizni ishlashi uchun berilgan vaqtdan ko'proq vaqt ketyapti yoki ba'zan algoritm umuman xato bo'lishi ham mumkin. Demak, yechimingizni optimallashtirish yoki boshqa turdagi algoritmdan foydalanish talab qilinadi.

Bunda, asosan, chegaraviy eng katta qiymat berish orqali tekshirib ko'rish kerak bo'ladi.

Algoritm murakkabligini baholash (Complexity of algorithm) haqida keyingi postimizda gaplashamiz va dastur ishlashi vaqtini qanday qilib aniqlash mumkinligini ham ko'rib o'tamiz.

g. Xato javob (WA)

Eng so'nggi bo'lib, eng ko'p uchraydigan xato: Wrong Answer (WA). Agar dasturingiz boshlang'ich testlardanoq qaytadigan bo'lsa, demak undagi xato kattaroq bo'lishi ehtimoli yuqori. Agarda uzoqroq testlarning biridan o'tolmay qolsa, umumiy yechimingiz katta ehtimol bilan to'g'ri, faqat u kritik nuqtalar uchun xato javob chiqaryapti. Bular uchun alohida shartlar bilan masalani ko'rib chiqish talab qilinishi mumkin. Dasturchi o'z kodidagi bunday xatolarni tez aniqlay olishi haqiqiy san'atga aylanishi mumkin.

Bunday xatolardan qochishni birdaniga o'rganish qiyin. Bunday tajriba asta-sekin masaladan-masalaga to'planib boradi.

Eng muhimi xato qilishdan qo'rqmaslik, xatolar - eng yaxshi ustozingizga aylanishi o'zingizga bo'g'liq.

Maqolani foydali deb hisoblasangiz, uni do'stlaringizga ham ulashing.

Manba: Algorithm Uzbekistan (@AlgorithmUz) telegram va YouTube kanali.