2013-09-25 3 views
-1

У меня есть шаблонная функция для .find для векторов в файле заголовка sorted_vector, который я получил для назначения. Я выполняю модульное тестирование на разных методах/конструкторах и т. Д., Используя библиотеку BOOST, чтобы убедиться, что нет ошибок и сделать код более надежным в случае появления ошибок. Я только что быстрый вопрос о различиях между этими двумя кодовыми блоками:В чем разница между этими двумя блоками кода?

template <typename T> 
typename sorted_vector<T>::iterator sorted_vector<T>::find(value_type const& value) const { 
    auto front = beg_; 
    auto back = end_; 

     for(;;) { 
      auto p = (back - front)/2 + front; 
      if(p == end_) 
       return p; 
      else if(*p == value) 
       return p; 
      else if(*p > value) 
       back = p; 
      else 
       front = p + 1; 
     } 
} 

И этот блок:

template <typename T> 
typename sorted_vector<T>::iterator sorted_vector<T>::find(value_type const& value) const { 
    auto front = beg_; 
    auto back = end_; 

    for(;;) { 
     auto p = (back - front)/2 + front; 
     if(p == back) 
      return end_; 
     else if(*p == value) 
      return p; 
     else if(*p > value) 
      back = p; 
     else 
      front = p + 1; 
    } 
} 

Мой вопрос относительно первого, если утверждение в бесконечность для. В первом блоке кода он возвращает среднее значение каждый раз, когда он выполняет итерацию через вектор, если он не может найти значение вместо конца? Или в чем основное отличие двух операторов if?

Спасибо.

EDIT для beg_ и end_ они конкретизируются следующим образом:

private beg_; 
private end_; 

и вот как они используются, как правило:

sorted_vector() : beg_(nullptr), end_(nullptr), cap_(nullptr) { } 
iterator begin() { return iterator(beg_); } 
iterator end() { return iterator(end_); } 
+1

Второй вариант немного лучше отформатирован. –

+0

У вас не может быть типа 'private'. –

ответ

6

Ну, кажется, что beg_ и end_ переменные-члены класса, которые обозначают начало и конец сохраненной последовательности [beg_, end_). Поскольку эти значения никогда не меняются, первая версия кода просто неверна: во время двоичного поиска значение p не будет иметь шансов стать равным end_ (кроме узкого набора конкретных случаев, например, когда ключ больше, чем любое из сохраненных значений). Я ожидаю, что первая версия застрянет в бесконечном цикле, если ключ отсутствует в массиве и не больше последнего значения в массиве.

Между тем, второй вариант реализован правильно (при условии, что нет других ошибок): он проверяет p против конца тока субсегмент [front, back) исходной последовательности, а не против конца оригинального последовательность.

В любом случае, действительно невозможно полностью проанализировать этот код, не зная, какие соглашения следует соблюдать. Что такое end_, например? Is является итератором для последнего элемента массива? Или это итератор для элемента, прошедшего последний элемент массива?

+0

Да, beg_ и end_ являются частными переменными. Так сказать, у меня есть вектор из 1001 ints от 1-1000, и я ищу значение. Какое значение приведет к тому, что оно не будет равно end_? beg_, end_ или посередине? Или любое произвольное значение может вызвать проблему? – Delete

+1

Правильно, первый из них просто глючит. Рассмотрим массив с одним элементом, этот элемент равен 0, ища «значение» 1. Это сделает 'back' равным' front' и loop forever. Или попробуйте найти «значение» -1; который будет увеличивать фронт и разыгрывать конец массива. (Этот код фактически работает тогда и только тогда, когда значение находится в массиве, и массив сортируется.) – Nemo

+1

@Aaron G: любое значение, которое отсутствует в массиве и в то же время не больше максимального значения в массив должен либо вызывать бесконечный цикл, либо, может быть, неопределенное поведение. Например, если вы ищете '5' в массиве' {1, 8, 20}, первая версия должна работать неправильно. – AnT

1

Существует разница. Вы совершенно правы в том, что он делает, но имейте в виду строку «back = p;».

Что произойдет после нескольких циклов, спина, скорее всего, изменится на большее значение. (Потому что, если р больше, чем значение, обратно устанавливается р)

+0

Я не вижу, как «обратно» может «перейти на большее значение». 'p' рассчитывается как средняя точка между' front' и 'back'. Итак, когда мы делаем 'back = p', мы всегда перемещаем' назад' * назад *, до значения * small *. И это единственное место, где «спина» может измениться, – AnT

+0

В этой строке показано, что p становится больше: auto p = (назад - вперед)/2 + спереди; – Garrett

+0

Больше, чем именно? Эта строка всегда будет создавать 'p', которая меньше *, чем' back'. – AnT

Смежные вопросы