Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

เคล็ดลับ C++ สำหรับการเขียนโปรแกรมแข่งขัน (C++11)


ที่นี่เราจะดูเคล็ดลับการเขียนโปรแกรม C++ ที่ดีบางอย่างที่ช่วยเราในด้านต่างๆ เช่น ถ้าอยากเข้าร่วมการแข่งขันเขียนโปรแกรม (competitive programming) เคล็ดลับเหล่านี้จะช่วยลดเวลาเขียนโค้ด มาดูตัวอย่างทีละอย่าง

  • ตรวจสอบเลขคี่คู่โดยไม่ใช้ % operator ทริกนี้ง่าย เราสามารถทำ bitwise AND กับตัวเลขและ 1 ได้ หากผลลัพธ์ไม่เป็นศูนย์ แสดงว่าเป็นคี่ มิฉะนั้นเป็นคู่ ตรรกะง่ายมาก เลขคี่ทุกตัวมี 1 ที่ LSB (Least Significant Bit) ดังนั้นหลัง AND กับ 1 จะ mask ตัวอักษรอื่นๆ ทั้งหมดยกเว้น LSB เราจึงได้ผลลัพธ์ที่ต้องการง่ายๆ

if ((n & 1) != 0) {
    // this is odd
} else {
    // This is even
}
  • คูณและหารเร็วด้วย shift operator หากต้องการคูณตัวเลขด้วย 2^n ให้ shift เบนซ้าย n ครั้ง ทำนองเดียวกัน หากต้องการหารด้วย 2^n ให้ shift เบนขวา n ครั้ง

x = 40; y = x << 2; // x จะคูณด้วย 4, ดังนั้น y = 160
cout << x;
x = 40; y = x >> 2; // x จะหารด้วย 4, ดังนั้น y = 10
cout << x;
  • สลับสองตัวเลขโดยไม่ใช้ตัวแปรที่สาม ทำได้ด้วย + และ - แต่เราสามารถทำได้ด้วย bitwise XOR ด้วย สามารถตรวจสอบด้วยตัวเลขด้วยตนเองได้

// swap x and y
x ^= y;
y ^= x;
x ^= y;
  • สร้าง strlen() เองเมื่อห้ามใช้ฟังก์ชันมาตรฐาน บางครั้งมีข้อจำกัดไม่ให้ใช้ strlen() ในโค้ด ในกรณีนั้นเราสร้างเอง แต่ถ้ากรณีแค่เข้าถึงตัวอักษร เราจริงๆ ไม่ต้องทำ เราสามารถตรวจสอบว่าตัวอักษรตำแหน่ง i เป็น valid (non-zero) หรือไม่ ถ้า non-zero เราสามารถวนลูปต่อไป มิฉะนั้นหยุด

for(int i = 0; s[i]; i++) {
    cout << s[i];
}
  • ใช้ emplace_back() แทน push_back() บ่อยครั้งเราใช้ push_back() ใน STL เพื่อเพิ่มองค์ประกอบใหม่ในคอนเทนเนอร์ เช่น vector โดยไม่ใช้นั้น เราสามารถใช้ emplace_back() ได้ ฟังก์ชันนี้เร็วกว่ามาก มันไม่จัดสรรหน่วยความจำที่อื่น มันต่อท้ายหน่วยความจำที่จัดสรรไว้ในคอนเทนเนอร์โดยตรง

  • C++ มีฟังก์ชัน GCD ในตัว (built-in) เราสามารถใช้ในกรณีต่างๆ ไวยากรณ์ดังนี้

__gcd(x, y) // หา GCD ของ x และ y
  • ขนาดสูงสุดของอาร์เรย์ใน main function ประมาณ 10^6 แต่ถ้าประกาศอาร์เรย์แบบ global สามารถประกาศขนาดได้ถึง 10^7

  • คำนวณ most significant digit (หลักสำคัญที่สุด) ด้วย log ดูตรรกะด้านล่าง

n = 4578;
double k = log10(n);
k = k - floor(k);
int x = pow(10, k); // x คือ most significant digit
  • คำนวณจำนวนหลักโดยตรงด้วย log ไม่ต้องใช้ลูป

n = 4578;
int digit_count = floor(log10(n)) + 1
  • ตรวจสอบว่าเป็นกำลังของ 2 หรือไม่โดยตรง

x = 1024;
bool check = x && (!(x & (x - 1))); // ถ้า true แสดงว่าเป็นกำลังของ 2
  • ใน C++ มี inbuilt algorithms ตรวจสอบเงื่อนไขต่างๆ

all_of(left, left + n, isPositive()); // ตรวจสอบว่าทุกตัวเป็นบวกหรือไม่
any_of(left, left + n, isPositive()); // ตรวจสอบว่ามีอย่างน้อยหนึ่งตัวเป็นบวกหรือไม่
none_of(left, left + n, isPositive()); // ตรวจสอบว่าไม่มีตัวไหนเป็นบวก
  • Copy function คัดลอกองค์ประกอบจากคอนเทนเนอร์หนึ่งไปอีกอัน

int src[5] = {10, 20, 30, 40, 50};
int des[5];
copy_n(src, 5, dest);
  • มีอัลกอริทึมชื่อ iota() สร้างช่วงค่าที่เพิ่มขึ้นตามลำดับ กำหนดค่าเริ่มต้นให้ *first แล้วใช้ค่าด้วย post increment operator

int arr[5] = {0};
char str[5] = {0};
iota(arr, arr + 5, 15); // จะสร้าง {15, 16, 17, 18, 19}
iota(str, str + 5, 'A'); // จะสร้าง {'A', 'B', 'C', 'D', 'E'}
  • กำหนดค่าในรูปแบบ Binary เราสามารถใช้ prefix 0b กับเลขฐานสองเพื่อบอกว่าเลขนี้ให้ในรูปแบบ binary

int x = 0b1101; // แล้ว x จะเก็บค่า 13
  • ใน C++ ใช้คีย์เวิร์ดแทนโอเปอเรเตอร์เงื่อนไขได้ เช่นคีย์เวิร์ด 'and' ใช้แทน '&&'

x = 10;
if(x < 10 and x > 5)
    cout << "True" << endl;
else
    cout << "False" << endl; // This will return True