[C++] HackerRank : Sets-STL

Aiya Aiyara
3 min readJan 2, 2024

--

Easy : C++ (Basic)

Photo by Luis Monse on Unsplash

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 มารับงานต่อก็ทำงานได้ง่าย

--

--