Johnson trotter置换算法代码

Johnson trotter permutation algorithm code in C++ language

本文关键字:算法 代码 trotter Johnson      更新时间:2023-10-16

我正试图在C++中实现Johnson trotter,但我被正常排列卡住了。我不想使用向量,也不想创建一个类来解决这个问题。

有人能帮助实现这个C++吗?

void swap(int x, int y)
{
    int temp = arr[x];
    arr[x] = arr[y];
    arr[y] = temp;
    return;
}
void print(int s)
{
    for (int i = 0; i<s; i++)
        cout << arr[i] << " ";
    cout << endl;
    return;
}
void permute(int k, int s)
{
    if (k == 0)
        print(s);
    else
    {
        for (int i = k - 1; i >= 0; i--)
        {
            swap(i, k - 1);
            permute(k - 1, s);
            swap(i, k - 1);
        }
    }
}
int num(int x)
{
    int j = 0;
    if (x == 0)
        j = 1;
    else
        j = x*(num(x - 1));
    return j;
}

我在这里对Trotter的算法有了清晰的理解:https://youtu.be/xsFKorZ95Yw.

我创建了一个矢量来表示数字的方向,-1表示左方向,1表示右方向。在这个实现中,我按升序对元素进行排序,并使用-1作为初始方向。

template <typename T>
std::vector<int> PreparePermutation(std::vector<T>& input) {
  std::sort(input.begin(), input.end());
  std::vector<int> directions(input.size(), -1);
  return directions;
}
template <typename T>
bool NextPermutation(std::vector<T>& input, std::vector<int>& directions) {
  // position of max mobile number
  int max_mobile_pos = -1;
  for (int i = 0; i < input.size(); ++i) {
    // i - 1 or i + 1 to get left or right element it points to
    int pointed_pos = i + directions[i];
    // an element is mobile if it is larger than the element it points to
    if (pointed_pos >= 0 && pointed_pos < input.size() &&
        input[i] > input[pointed_pos]) {
      // find largest mobile element
      if (max_mobile_pos < 0 || input[i] > input[max_mobile_pos]) {
        max_mobile_pos = i;
      }
    }
  }
  if (max_mobile_pos == -1) {
    return false;
  }
  auto max_mobile_pointed_pos = max_mobile_pos + directions[max_mobile_pos];
  std::swap(input[max_mobile_pos], input[max_mobile_pointed_pos]);
  std::swap(directions[max_mobile_pos], directions[max_mobile_pointed_pos]);
  max_mobile_pos = max_mobile_pointed_pos;
  for (int i = 0; i < input.size(); ++i) {
    // flip direction of elements larger than current max mobile
    if (input[i] > input[max_mobile_pos]) {
      directions[i] *= -1;
    }
  }
  return true;
}