[C++] HackerRank : Sets-STL
Easy : C++ (Basic)
Set คือ Vector (Dynamic Array) ที่ Element จะมีความเป็น Unique (เฉพาะตัว) และจะไม่ซ้ำกัน มาลองดูรูปแบบการใช้งานก่อน ให้ชื่อตัวแปรมีคำว่า mark นำหน้าชื่อตัวแปร
Declaration : การประกาศ
set<int> markSet;
Size : ตรวจสอบขนาด
int length = markSet.size();
Insert : ใส่ค่าเข้าไปใน Set
markSet.insert(x);
Erasing an element : ลบค่าที่อยู่ใน Set
markSet.erase(val);
Finding an element : หาค่าใน Set
set<int>::iterator itr = markSet.find(val);
ลองใช้งาน Set ใน VS Code กัน เริ่มจากการลองใส่ค่าซ้ำเข้าไปเพื่อดูว่า Element ใน Set เป็น Unique จริงไหม (อยากรู้ต้องลองต้อพิสูจน์ครับ)
จะเห็นว่าไม่สามารถใส่ค่าเดิมที่มีในนั้นได้ ถ้าใช้ให้ถูกกับงานคงจะสะดวกไม่น้อย ยกตัวอย่างเช่นการเก็บ Array ของเลขบัตรประชาชน ซึ่งมันไม่ควรซ้ำกันเป็นต้น
ต่อไปจะลองหาค่าออกมาดู ในภาษายุคก่อน C++ เช่น ภาษา C การหาค่าใน Dynamic Array นั้นต้อง Loop เพื่อเปรียบเทียบและค้นหาทีละ Element
มาในยุค C++ เบื้องหลังก็ทำเหมือนกัน แต่คนเขียน C++ เขียน Standard Function มาให้ Dev ใช้งานได้ง่ายขึ้น
ผมจะลองหา Value ที่มีค่าเท่ากับ 14 ดู ขอเปลี่ยน Element ใน Set เพื่อความเข้าใจที่ดีขึ้น
ผลลัพท์คือ เจอที่ index ที่ 4
อธิบายเพิ่มเติม
int searchValue = 14;
set<int>::iterator itr = markSet.find(searchValue);
// สร้าง Instance ชื่อ Itr เป็น Set Int ที่นำเข้า Class iterator มาใช้งาน
if (itr != markSet.end()) {
// ถ้า itr มีค่าไม่ตรงกับ Element สุดท้ายของ Set แสดงว่าเจอ ถ้าตรงก็ไม่เจอ
cout << "Found : " << distance(markSet.begin(), itr) << endl;
// distance คือหาระยะห่างจากตัวแรก 0 ถึง itr ซึ่งในกรณีนี้จะได้ 4
} else {
cout << "Not Found" << endl;
}
มาดูโจทย์กันดีกว่า
Input
8
1 9
1 6
1 10
1 4
3 6
3 14
2 6
3 6
Output
Yes
No
No
แถวแรกคือคำสั่ง (Query) แถวที่สองคือ Value
Query
1 : Add Element to Set (ใส่ Value เข้าไป)
2 : Delete an element from the Set. (ลบ Value ถ้าไม่มีไม่ต้องทำอะไร)
3 : Print "Yes" else print "No". (หา Value ถ้าเจอ Print Yes ถ้าไม่เจอ Print No)
ลองแก้โจทย์ทีละ Query
Input
1 9 // {9}
1 6 // {9, 6}
1 10 // {9, 6, 10}
1 4 // {9, 6, 10, 4}
3 6 // Yes
3 14 // No
2 6 // {9, 10, 4}
3 6 // No
Output
Yes
No
No
แสดงผลถูกต้อง
ต่อไปเขียน Code ดีกว่า เริ่มจากรับค่าด้วย CIN ก่อนดีกว่า อย่าเพิ่งทำอะไร
ผลลัพท์
สวยงาม แต่งานยังไม่เสร็จ ต่อไปจะเริ่มทำงานใน Loop
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#include <set>
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int numberOfQuery;
cin >> numberOfQuery;
set<int> markSet;
for (int i = 0; i < numberOfQuery; ++i){
int queryNumber, value;
cin >> queryNumber >> value;
//cout << queryNumber << " " << value << ", ";
if (queryNumber == 1) {
markSet.insert(value);
}
if (queryNumber == 2) {
markSet.erase(value);
}
if (queryNumber == 3) {
set<int>::iterator itr = markSet.find(value);
if (itr != markSet.end()) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
}
}
return 0;
}
ผลลัพท์
ใครเก่งแล้วจะใช้ Switch Case แทน If ก็ดี แต่ผมจะใช้ If เพราะมันใช้ได้และ Beginner มารับงานต่อก็ทำงานได้ง่าย
Source Code : https://github.com/MarkTBSS/19_Sets_STL