Написание функции, которая выполняет ту же работу, что и set_symmetric_difference

#c

#c

Вопрос:

Всем привет и извините, что отняли у вас время! Я выполняю онлайн-упражнения, и мне было поручено написать шаблонную функцию, которая выполняет ту же работу, set_symmetric_difference что и . Функция принимает пять параметров p1, p2, p3, p4 p5 . p1 and p2 это границы первого блока, p3 and p4 границы второго блока, p5 точки в начале целевого блока.

Примечание: Существует три разных типа параметров, потому что p1 и p2 могут быть указателями, в то время как p3 и p4 могут быть итераторами.

Функция должна найти симметричную разницу двух наборов, но с определенными условиями:

  1. Дубликаты не допускаются (т.е., Если в наборе симметричных различий уже есть элемент значения x , другой элемент с тем же значением копировать нельзя).
  2. Все элементы должны располагаться в том же порядке, что и исходные два блока
  3. Элементы первого блока должны быть скопированы перед элементами второго блока.
  4. Функция возвращает итератор / указатель, который указывает не на начало целевого блока, а на точку после последнего элемента в блоке.

Пока мне не повезло с исправлением этого. Мое решение работает для некоторых экземпляров, но для других оно не работает. Я абсолютно не представляю, как следовать правилам 1,2 и 3.

 #include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;

template <typename type1, typename type2, typename type3> 
type3 symmetric(type1 p1, type1 p2, type2 p3, type2 p4, type3 p5) {
   sort(p1,p2);
   sort(p3,p4);

   while(true) {
      if(p1 == p2) return copy(p3,p4,p5); 
      if(p3==p4) return copy(p1,p2,p5);
      if(*p1 < *p3) {
         *p5=*p1;
         p5  ;
         p1  ;
      }

      else if(*p3 < *p1) {
         *p5 = *p3;
         p3  ;
         p5  ;

      }
      else {
         p1  ;
         p3  ;
      }
   }
   return p5;
}

int main ()
{
   int block1[] = { 5, 2, 7, 4, 6, 1, 3, 2, 7, 4 };
   int block2[] = { 2, 9, 0, 6, 0, 4, 8, 3, 2, 5 };
   int destination[10];
   auto p = symmetric(block1, block1 10, block2, block2 10, destination);
   auto destination_begin = destination;
   while(destination_begin < p) cout << *destination_begin  ;
   return 0;
}
 

Для примера, который я упомянул, вывод должен быть 7 1 9 0 8 , но моя программа печатает 0 0 1 4 7 7 8 9 . Я понятия не имею, как это исправить. Извините за мое невежество, и я был бы рад, если бы кто-нибудь пришел на помощь! Спасибо миллион раз!

Комментарии:

1. Вы могли бы начать с реализации set_symettric_difference , а затем настроить ее в соответствии с вашими потребностями.

Ответ №1:

Прежде всего, ожидается, что ваш вывод будет отсортирован. Следовательно, это должно быть 0 1 7 8 9 , а не 7 1 9 0 8 .

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

Вот обновленная версия вашего опубликованного кода, которая работает для меня.

 #include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;

template <typename type> 
void print(type p1, type p2)
{
   while(p1 != p2) cout << *p1   << " ";
   cout << endl;
}

template <typename type> 
type skip_duplicates(type p)
{
   while ( *p == *(p 1) )   p;
   return   p;
}

template <typename type1, typename type2, typename type3> 
type3 symmetric(type1 p1, type1 p2, type2 p3, type2 p4, type3 p5) {
   sort(p1,p2);
   sort(p3,p4);

   print(p1, p2);
   print(p3, p4);

   while(true) {
      if(p1 == p2) return copy(p3,p4,p5); 
      if(p3 == p4) return copy(p1,p2,p5);
      if(*p1 < *p3) {
         *p5=*p1;
         p5  ;
         p1 = skip_duplicates(p1);
      }

      else if(*p3 < *p1) {
         *p5 = *p3;
         p3 = skip_duplicates(p3);
         p5  ;

      }
      else {
         p1 = skip_duplicates(p1);
         p3 = skip_duplicates(p3);
      }
   }
   return p5;
}

int main ()
{
   int block1[] = { 5, 2, 7, 4, 6, 1, 3, 2, 7, 4 };
   int block2[] = { 2, 9, 0, 6, 0, 4, 8, 3, 2, 5 };
   int destination[10];
   auto p = symmetric(block1, block1 10, block2, block2 10, destination);
   print(destination, p);
   return 0;
}
 

Комментарии:

1. Спасибо за вашу помощь! Может быть, вы знаете, как я мог бы изменить эту программу, чтобы не сортировать значения, чтобы получить результат, о котором я упоминал? Еще раз спасибо!

2. Для корректной работы @ff998 set_symmetric_difference требуются отсортированные последовательности. Даже если вы придумали способ сделать это без сортировки, алгоритмическая сложность, вероятно, будет хуже, чем просто сначала отсортировать последовательности.