2015-01-15 91 views
1

我想找出最好的方法來找到最接近的值ROUNDED DOWN,在整數列表中使用任何n之間的兩個其他數字存儲在列表中。在這種情況下,所有的整數將始終是無符號的,以防萬一。從給定的整數數組中找到最接近的整數值,向下舍入

的假設如下:

  • 列表總是在0
  • 啓動列表中總是排序ASC
  • 列表中的所有整數無符號(無需Math.Abs
  • 用於比較的數字總是無符號的

例如:

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 }; 
int myNumber = 9000; 
int theAnswer; // should be 8500 

for (int i = 0; i < numbers.Count; i++) { 
    if (i == numbers.Count - 1) { 
     theAnswer = numbers[i]; 
     break; 
    } else if (myNumber < numbers[i + 1]) { 
     theAnswer = numbers[i]; 
     break; 
    } 
} 

前面的代碼示例工作沒有任何瑕疵。

有沒有 更好 更有說服力的方法嗎?

+0

這個問題可能更適合於[代碼審查(http://codereview.stackexchange.com/) – 2015-01-15 17:32:57

+0

您更好的是什麼意思?性能?內存消耗? ...無論如何,嘗試二進制搜索。 – 2015-01-15 17:37:18

+0

如果你正在談論一小堆數字,那麼你在這裏有什麼是好的,我不會花更多的時間在它上面。如果您正在討論任意大小的數字列表,您可能需要執行更高效的搜索以查找myNumber之間的2個數字。 – 2015-01-15 17:37:45

回答

5

您可以使用List<T>.BinarySearch而不是按順序枚舉列表元素。

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 }; 
int myNumber = 9000; 

int r=numbers.BinarySearch(myNumber); 
int theAnswer=numbers[r>=0?r:~r-1]; 
+0

非常好的使用MSDN上提供的信息!感謝您強迫我學習按位恭維操作符並重新閱讀[BinarySearch文檔](http://msdn.microsoft.com/zh-cn/library/w4e7fxsh(v = vs80).aspx) – 2015-01-15 17:49:47

4

過濾器列表中獲得的所有值小於myNumber並返回最後一個:

theAnswer = numbers.Where(x => x <= myNumber).Last(); 
+1

'Last'將返回一個'int',並且'int'沒有'Select'方法。 – juharr 2015-01-15 17:36:38

+0

另外,就性能而言,如果沒有證據證明任何基於Linq的解決方案比OP的解決方案更好,我都不會接受。 – 2015-01-15 17:38:27

+1

這是爲什麼這樣下來投票呢?這正是我如何去做的。 +1 – hatcyl 2015-01-15 17:39:02

0

列表可以被索引。

從列表中間的索引處開始。如果你找到確切的數字,你是好的。如果數字小於目標數字,請在列表開頭的範圍中間搜索一個小於列表中間的範圍。如果該數字大於目標數字,則使用列表的另一半。繼續此二分搜索,直到找到完全匹配或者小於和大於目標數字的相鄰數字。

選擇兩者中的較小者。

0

請試試這個代碼:

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 }; 
int myNumber = 9000; 

int theAnswer = numbers[numbers.Count - 1]; 

if (theAnswer > myNumber) 
{ 
    int l = 0, h = numbers.Count - 1, m; 
    do 
    { 
     m = (int)((double)(myNumber - numbers[l])/(double)(numbers[h] - numbers[l]) * (h - l) + l); 
     if (numbers[m] > myNumber) h = m; else l = m; 
    } 
    while ((h - l) != 1); 
    theAnswer = numbers[l]; 
} 
+0

歡迎並感謝您的幫助!請保持描述你的答案,並提供一些額外的信息。 – hofmeister 2015-01-15 19:50:04

相關問題