นี่คือโค้ดหลอกที่ควรแปลงเป็นภาษาใด ๆ :
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)
def closest (num, arr):
curr = arr[0]
foreach val in arr:
if abs (num - val) < abs (num - curr):
curr = val
return curr
มันเพียงแค่คำนวณความแตกต่างที่แน่นอนระหว่างตัวเลขที่กำหนดและองค์ประกอบอาเรย์แต่ละรายการและให้คุณได้หนึ่งในจำนวนที่แตกต่างกันเล็กน้อย
สำหรับค่าตัวอย่าง:
number = 112 112 112 112 112 112 112 112 112 112
array = 2 42 82 122 162 202 242 282 322 362
diff = 110 70 30 10 50 90 130 170 210 250
|
+-- one with minimal absolute difference.
เพื่อเป็นการพิสูจน์แนวความคิดนี่เป็นรหัส Python ที่ฉันใช้ในการแสดงสิ่งนี้:
def closest (num, arr):
curr = arr[0]
for index in range (len (arr)):
if abs (num - arr[index]) < abs (num - curr):
curr = arr[index]
return curr
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)
และถ้าคุณต้องการมันจริงๆใน Javascript ให้ดูไฟล์ HTML ที่สมบูรณ์ด้านล่างซึ่งแสดงให้เห็นถึงการทำงานของฟังก์ชัน:
<html>
<head></head>
<body>
<script language="javascript">
function closest (num, arr) {
var curr = arr[0];
var diff = Math.abs (num - curr);
for (var val = 0; val < arr.length; val++) {
var newdiff = Math.abs (num - arr[val]);
if (newdiff < diff) {
diff = newdiff;
curr = arr[val];
}
}
return curr;
}
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
number = 112;
alert (closest (number, array));
</script>
</body>
</html>
ตอนนี้โปรดทราบว่าอาจมีขอบเขตสำหรับการปรับปรุงประสิทธิภาพหากตัวอย่างเช่นรายการข้อมูลของคุณถูกจัดเรียง (ซึ่งอาจอนุมานได้จากข้อมูลตัวอย่าง แต่คุณไม่ได้ระบุอย่างชัดเจน) ตัวอย่างเช่นคุณสามารถใช้การค้นหาแบบไบนารีเพื่อค้นหารายการที่ใกล้เคียงที่สุด
คุณควรจำไว้ว่าหากคุณไม่จำเป็นต้องทำหลาย ๆครั้งต่อวินาทีการปรับปรุงประสิทธิภาพจะไม่สามารถสังเกตเห็นได้เว้นแต่ว่าชุดข้อมูลของคุณมีขนาดใหญ่กว่ามาก
หากคุณไม่ต้องการที่จะลองมันเป็นอย่างนั้น (และสามารถรับประกันอาร์เรย์จะถูกจัดเรียงในลำดับ) นี้เป็นจุดเริ่มต้นที่ดี
<html>
<head></head>
<body>
<script language="javascript">
function closest (num, arr) {
var mid;
var lo = 0;
var hi = arr.length - 1;
while (hi - lo > 1) {
mid = Math.floor ((lo + hi) / 2);
if (arr[mid] < num) {
lo = mid;
} else {
hi = mid;
}
}
if (num - arr[lo] <= arr[hi] - num) {
return arr[lo];
}
return arr[hi];
}
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
number = 112;
alert (closest (number, array));
</script>
</body>
</html>
โดยทั่วไปจะใช้การถ่ายคร่อมและตรวจสอบค่ากลางเพื่อลดพื้นที่โซลูชันลงครึ่งหนึ่งสำหรับการทำซ้ำแต่ละครั้งซึ่งเป็นO(log N)
อัลกอริทึมแบบคลาสสิกในขณะที่การค้นหาตามลำดับด้านบนคือO(N)
:
0 1 2 3 4 5 6 7 8 9 <- indexes
2 42 82 122 162 202 242 282 322 362 <- values
L M H L=0, H=9, M=4, 162 higher, H<-M
L M H L=0, H=4, M=2, 82 lower/equal, L<-M
L M H L=2, H=4, M=3, 122 higher, H<-M
L H L=2, H=3, difference of 1 so exit
^
|
H (122-112=10) is closer than L (112-82=30) so choose H
ตามที่ระบุไว้ว่าไม่ควรสร้างความแตกต่างอย่างมากสำหรับชุดข้อมูลขนาดเล็กหรือสิ่งที่ไม่จำเป็นต้องรวดเร็วอย่างไม่น่าเชื่อ แต่เป็นตัวเลือกที่คุณอาจต้องการพิจารณา
x
ไปผ่านอาร์เรย์หนึ่งต่อหนึ่งเปรียบเทียบi
กับหมายเลขปัจจุบันในอาร์เรย์ถ้าความแตกต่างระหว่างมันและi
เล็กกว่าค่าปัจจุบันx
ตั้งx
เป็นหมายเลขอาร์เรย์ปัจจุบัน เมื่อเสร็จแล้วx
มีจำนวนที่ใกล้เคียงที่สุดi
จากอาร์เรย์