ไม่จำเป็นต้องเริ่มต้นให้เล็กที่สุด / ใหญ่ที่สุดเท่าที่จะเป็นไปได้เพื่อค้นหาสิ่งที่เล็กที่สุด / ใหญ่ที่สุดในอาร์เรย์:
double largest = smallest = array[0];
for (int i=1; i<array_size; i++) {
if (array[i] < smallest)
smallest = array[i];
if (array[i] > largest0
largest= array[i];
}
หรือหากคุณทำมากกว่าหนึ่งครั้ง:
#include <utility>
template <class iter>
std::pair<typename iter::value_type, typename iter::value_type> find_extrema(iter begin, iter end) {
std::pair<typename iter::value_type, typename iter::value_type> ret;
ret.first = ret.second = *begin;
while (++begin != end) {
if (*begin < ret.first)
ret.first = *begin;
if (*begin > ret.second)
ret.second = *begin;
}
return ret;
}
ข้อเสียของการให้โค้ดตัวอย่าง - ฉันเห็นว่ามีคนอื่นแนะนำแนวคิดเดียวกันนี้แล้ว
โปรดทราบว่าแม้ว่ามาตรฐานจะมี min_element และ max_element แต่การใช้สิ่งเหล่านี้จะต้องมีการสแกนข้อมูลสองครั้งซึ่งอาจเป็นปัญหาได้หากอาร์เรย์มีขนาดใหญ่เลย มาตรฐานล่าสุดได้แก้ไขปัญหานี้โดยการเพิ่ม a std::minmax_element
ซึ่งทำเช่นเดียวกับfind_extrema
ข้างต้น (ค้นหาทั้งองค์ประกอบต่ำสุดและสูงสุดในคอลเลกชันในรอบเดียว)
แก้ไข: แก้ไขปัญหาในการค้นหาค่าที่ไม่ใช่ศูนย์ที่เล็กที่สุดในอาร์เรย์ที่ไม่ได้ลงนาม: สังเกตว่าค่าที่ไม่ได้ลงชื่อ "ล้อมรอบ" เมื่อถึงจุดสูงสุด ในการหาค่าที่ไม่ใช่ศูนย์ที่เล็กที่สุดเราสามารถลบค่าหนึ่งออกจากแต่ละค่าเพื่อเปรียบเทียบได้ ค่าศูนย์ใด ๆ จะ "ล้อมรอบ" เป็นค่าที่มากที่สุดเท่าที่จะเป็นไปได้สำหรับประเภทนั้น แต่ความสัมพันธ์ระหว่างค่าอื่น ๆ จะยังคงอยู่ หลังจากที่เราทำเสร็จแล้วเราจะเพิ่มกลับเข้าไปในค่าที่พบ
unsigned int min_nonzero(std::vector<unsigned int> const &values) {
if (vector.size() == 0)
return 0;
unsigned int temp = values[0]-1;
for (int i=1; i<values.size(); i++)
if (values[i]-1 < temp)
temp = values[i]-1;
return temp+1;
}
โปรดทราบว่าสิ่งนี้ยังคงใช้องค์ประกอบแรกสำหรับค่าเริ่มต้น แต่เรายังไม่ต้องการรหัส "กรณีพิเศษ" ใด ๆ เนื่องจากจะรวมเป็นค่าที่มากที่สุดเท่าที่จะเป็นไปได้ค่าใด ๆ ที่ไม่ใช่ศูนย์จะเปรียบเทียบว่ามีค่าน้อยกว่า ผลลัพธ์จะเป็นค่าที่ไม่ใช่ศูนย์ที่เล็กที่สุดหรือ 0 ก็ต่อเมื่อเวกเตอร์ไม่มีค่าที่ไม่ใช่ศูนย์