Home > OS >  Find shift of cyclic permutation of two sequences
Find shift of cyclic permutation of two sequences

Time:04-10

I need to find shift of two cyclic permutations of sequences.

EXAMPLE:

3 5 1 2 4 3 5 7 8 1 2 5 9 4 7

5 7 8 1 2 5 9 4 7 3 5 1 2 4 3

Second sequence is cyclic permutaion of first with shift 6.

My algorithm:

  • if sequences are equal return 0 as shift
  • if they are not equal, sort them and then check if they have same elements
  • if they don't have same elements they are not cyclic permutation
  • if they have same elements, first element of first vector move to the end of vector and then make temp vector of first two elements of first vector, find that temp vector in second vector and shift is equal to b.size() - i 1;

For example I get following error

terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 15) >= this->size() (which is 15)

and if I try other sequences result is not correct.

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdlib>
int sequences_are_equal = 0;
bool sequences_have_same_elements(std::vector < int > a, std::vector < int > b) {
  sequences_are_equal = 0;
  if (a.size() != b.size())
    return false;
  for (int i = 0; i < a.size(); i  )
    if (a.at(i) == b.at(i))
      sequences_are_equal  ;
  if (sequences_are_equal == a.size()) return true;
  sort(a.begin(), a.end());
  sort(b.begin(), b.end());
  for (int i = 0; i < a.size(); i  )
    if (a.at(i) != b.at(i))
      return false;
  return true;
}

int CyclicPermutation(std::vector < int > a, std::vector < int > b) {
  int shift = -1;
  std::vector < int > temp(a.size(), 0);
  std::vector < int > help(a.size(), 0);
  if (sequences_have_same_elements(a, b)) {
    int x = a.at(0);
    a.erase(a.begin());
    a.push_back(x);
    temp.push_back(a.at(0));
    temp.push_back(a.at(1));
    for (int i = 0; i < b.size(); i  ) {
      help.push_back(b.at(i));
      help.push_back(b.at(i   1));
      if (temp == help) {
        shift = b.size() - i   1;
        break;
      }
      help.clear();
    }
  }
  if (sequences_are_equal == a.size()) return 0;
  return shift;
}

int main() {
  int x;
  std::vector < int > a, b;
  std::cout << "First sequence: ";
  while (std::cin >> x)
    a.push_back(x);
  std::cin.clear();
  std::cin.ignore(1000, '\n');
  std::cout << "Second sequence: ";
  while (std::cin >> x)
    b.push_back(x);
  if (CyclicPermutation(a, b) == -1)
    std::cout << "Second sequence is not cyclic permutaion of first.";
  else
    std::cout << "Second sequence is cyclic permutaion of first with shift " << CyclicPermutation(a, b) << ".";

  return 0;
}

Could you explain me where did I make mistake in my algorithm and code? How to modify this to work correct?

CodePudding user response:

Your design is wrong.

It seems that you simply want to rotate elements in a std::vector.

The exception is because of an out of bounds error: help.push_back(b.at(i 1));

There is a strange handling with "help" and "temp". You first create "help" and "temp" with n 0es in it. Then you push back stuff, but only 2 elements. So, if for example the original vector size is 4, then your vectors will be 0,0,0,0,x,y.

That is rather strange, or, I do not understand it.

What you should do:

  1. Check, if the size of the 2 vectors is equal
  2. Check, if the vectors are equal using the existing == operator
  3. Rotate the vectors elements for mx "size" times. Count the number of rotations
  4. Go back to 2

You can either use the existing function std::rotate(see enter image description here

You input routine is not good that. You should know, that ignore is a unformatted input function


Edit 2

Your input works, with the original function:

enter image description here


  • Related