Во время Loop Error - PullRequest
       2

Во время Loop Error

0 голосов
/ 17 февраля 2011

У меня есть задание объединить два отсортированных вектора в третий отсортированный вектор.Я уверен, что решение этой проблемы довольно простое, но мой мозг в настоящий момент занят и может использовать вашу помощь.

В основном векторы A и B имеют размер 3. Они будут содержать целые числа, такие как1, 2, 3 и 4, 5, 6 соответственно.Я не могу правильно понять синтаксис моего цикла while.Я попытался сделать это циклом do / while, поставить круглые скобки вокруг случаев и некоторые другие вещи.Кажется, он просто не читает часть после &&.

Первый цикл for просто заставляет вектор R иметь правильный размер.А второй цикл for просто отображает значения вектора R.Результат должен распечатываться с 1-6, но я вижу только 1-3.

Любая помощь будет признательна!

void::combine(vector<int> A, vector<int> B, vector<int> R) {
int ia = 0, ib = 0, ir = 0;

for (int i = 0; i < A.size() + B.size(); i++) {
    R.push_back(0);
}

while (ia != A.size() && ib != B.size()) {
        if (A[ia] < B[ib]) {
             R[ir] = A[ia];
             ia += 1;
        }
        else {
            R[ir] = B[ib];
            ib += 1;
        }
        ir += 1;
}

for (int i = 0; i < R.size(); i++) {
    cout << "L3[" << i << "] = " << R[i] << endl;
}

}

Ответы [ 7 ]

1 голос
/ 17 февраля 2011

Я не знаю, что вы пытаетесь сделать в цикле while. Но если вы просто заполняете вектор R элементами A и B, не учитывая порядок их добавления, то вы можете использовать функцию insert, например:

void::combine(const vector<int> &A, const vector<int> &B, vector<int>& R)
{
    R.insert(R.end(), A.begin(), A.end());
    R.insert(R.end(), B.begin(), B.end());
}

И если вы хотите заказать вектор R, то вы можете добавить следующую строку в вышеуказанную функцию:

 sort( R.begin(), R.end()); //sorts in increasing order.

Вы должны #include<algorithm>, если вы это сделаете. Если вы хотите отсортировать в порядке убывания, сделайте следующее:

bool compare( int a, int b ) { return a > b; }
sort( R.begin(), R.end(), compare); //sorts in decreasing order.
1 голос
/ 17 февраля 2011

Вероятно, вам следует вообще избегать цикла:

void combine(vector<int> const& A, vector<int> const& B, vector<int> & R) {
   R.resize( A.size() + B.size() );
   std::copy( A.begin(), A.end(), R.begin() );
   std::copy( B.begin(), B.end(), R.begin()+A.size() );
   std::sort( R.begin(), R.end() );
   for ( int i = 0; i < R.size(); ++i )
   {
    cout << "L3[" << i << "] = " << R[i] << endl;
   }
}

Это неоптимально, так как вы сначала копируете, а затем заказываете, но для небольшого размера это никак не повлияет.

По фактическим проблемам с вашим кодом: старайтесь избегать передачи по значению, используйте resize вместо нескольких push_back(), чтобы исправить размер (обратите внимание, что если аргумент R для вашей функции был непустым вектором тогда окончательный размер будет больше, чем вы хотите). Попробуйте использовать возвращаемое значение вместо ссылочного аргумента --easier для чтения. Вы зациклились, пока первый из счетчиков не достиг конца, но остальные элементы остались в другом контейнере без копирования.

Ручная реализация с использованием итераторов также будет проще:

typedef std::vector<int> vector_t;
vector_t combine( vector_t const & a, vector_t const & b ) {
   vector_t r( a.size() + b.size() ); // [*]
   vector_t::const_iterator ita = a.begin(), enda = a.end();
   vector_t::const_iterator itb = b.begin(), endb = b.end();
   vector_t::iterator itr = r.begin();

   while ( ita != enda && itb != endb ) {
      if ( *ita < *itb )
         *itr++ = *ita++;
      else 
         *itr++ = *itb++;
   }
   if ( ita != enda ) 
      std::copy( ita, enda, itr );
   else 
      std::copy( itb, endb, itr );

   return r;
}
1 голос
/ 17 февраля 2011

Предполагая, что A содержит [1,2,3], а B содержит [4,5,6], как вы говорите, это не добавит ни одного элемента из вектора B к вектору R.

Это потому, что на 4-й итерации ia == 3, и поэтому конъюнктивное условие больше не выполняется ..

Попробуйте изменить его на while(ia != A.size() || ib != B.size())

0 голосов
/ 17 февраля 2011

Прежде всего, это пахнет как классическая сортировка слиянием или ее часть:
http://en.wikipedia.org/wiki/Merge_sort

Цель - изучить элементы первого вектора, к элементам вектора B и добавьте элементы к результирующему вектору R по порядку.

Таким образом, если A[i] <<code>B[j], добавьте A[i] к Rstd::vector нет необходимости загружать вектор результата нулями перед запуском.См. std::vector::push_back().

Ниже приведен непроверенный код:

void Sort_Vector(const std::vector& A, const std::vector& B, std::vector& result)
{
  unsigned int index_a = 0;  // Point to first element in first vector.
  unsigned int index_b = 0;  // Point to first element in second vector.
  result.clear();            // Clear all elements, so size == 0.

  while ((index_a < A.size()) && (index_b < B.size())
  {
     if (A[index_a] < B[index_b])
     {
         result.push_back(A[index_a]);
         ++index_a;
     }
     else // B[index_b] <= A[index_a]
     {
         result.push_back(B[index_b]);
         ++index;
     }
  }

  // Append any remaining elements to the result vector.
  // Only one of the two loops should be executed,
  //    the other will fail the comparison expression
  //    and not execute.
  for (; index_a < A.size(); ++index_a)
  {
     result.push_back(A[index_a]);
  }
  for (; index_b < B.size(); ++index_b)
  {
     result.push_back(B[index_b]);
  }
  return;
}

Обратите внимание на разницу между сигнатурой (параметрами) моей функции и вашей.Я передаю исходные векторы как постоянные данные, а вектор результата передается по ссылке , что позволяет моей функции изменять вектор результата вызывающей стороны.

Кроме того, я ленивый и использую метод std::vector::push_back().Я считаю, что это более читабельно, чем присвоение элемента в векторе результатов.Метод push_back подразумевает, что я добавляю вектор.Маршрут назначения может застать читателей врасплох, если они забудут, что вектор расширится, чтобы разрешить назначение.

0 голосов
/ 17 февраля 2011

например, с 123 и 456, что делается прямо сейчас.

  1. Инициализируйте R до {0,0,0,0,0,0}

  2. до всех значенийиз один вектор вставляется в R сравнить кандидатов и вставить меньший в R, получить следующего кандидата из списка победителей.

и это все - яЯ не знаю, в чем заключается цель функции, если вы напишите ее. Я / мы можем предоставить решение, в противном случае просто просмотрите 2-й пункт в приведенной выше форме.

0 голосов
/ 17 февраля 2011

Синтаксис в порядке (код не скомпилируется в противном случае), но условие вашего цикла - нет. Учитывая ваш пример A = { 1, 2, 3 } и B = { 4, 5, 6 }, цикл войдет в ветвь A[ia] < B[ib] три раза и увеличит значение ia до 3. Как только это произойдет, первая часть условия цикла, ia != A.size() не будет истинной и так цикл заканчивается.

Поскольку вы уже знаете, сколько элементов нужно разместить в векторе результатов, я рекомендую заменить цикл while на простой цикл for с таким же телом.

0 голосов
/ 17 февраля 2011

это из-за вашего && состояния. как только ia == A.size(), первая часть условия (ia != A.size()) всегда будет иметь значение false, а часть ib вашего цикла не будет выполняться.

чтобы исправить это, вы можете изменить условие на: (iA < A.size()) || (iB < B.size())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...