Advertisement
Gistrec

Перестановки без повторений с диапазоном

Oct 13th, 2018
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.20 KB | None | 0 0
  1. #include <vector>
  2.  
  3. using std::vector;
  4.  
  5. // Таак, тут будет крутое описание.
  6. // Допустим у нас есть вектор их элементов
  7. // {first, second, third, forth, fifth, sixt, seventh, eight, nine, tan}
  8. // Тогда класс позволит получить все ветора,
  9. // где каждый элемент находится в пределах n позиций от начального положения
  10. //
  11. // Т.е. Пример: {1, 2, 3}, position = 1
  12. // Варианты: {1, 2, 3} {2, 1, 3} {1, 3, 2}
  13. // Все символы сдвинулись не более чем на одну позицию от своего начального положения
  14.  
  15. template <class Type>
  16. class BruteForce {
  17.     vector<Type> _start;
  18.  
  19.     // Текущее состояние. Будет указывать на
  20.     vector<Type> _state;
  21.  
  22.     // Дистанция, на которую можно сдвинуть каждый элемент
  23.     size_t _maxDistance;
  24.  
  25. public:
  26.     // Инициализируем начальное значение и текущее
  27.     BruteForce(vector<Type> start, size_t distance) :
  28.         _start(start), _state(start), _maxDistance(distance) {};
  29.  
  30.     vector<Type> get() {
  31.         return _state;
  32.     }
  33.  
  34.     bool checkPosition() {
  35.         // На старте символ _start[i] был на i-той позиции
  36.         // Ищем где он сейчас
  37.         for (int i = 0; i < _start.size(); i++) {
  38.             int pos = std::distance(_state.begin(), find(_state.begin(), _state.end(), _start[i]));
  39.             int distance = std::abs(i - pos);
  40.             if (distance > _maxDistance) return false;
  41.         }
  42.         return true;
  43.     }
  44.  
  45.     // Формула для генерации перестановок
  46.     // С проверкой на то, что каждый символ удален
  47.     // от начального положения не дальше, чем на _position
  48.     // @return false - если перестановки закончились
  49.     bool next() {
  50.         bool end;
  51.         bool result = false;
  52.  
  53.         while (result == false) {
  54.             end = nextStep();
  55.             if (end == false) break;
  56.  
  57.             result = checkPosition();
  58.         }
  59.         return result;
  60.         return true;
  61.     }
  62.    
  63.     // Legacy code. Отправить на переработку в ад.
  64.     bool nextStep() {
  65.         int j = _start.size() - 2;
  66.         while (j != -1 && _state[j] >= _state[j + 1]) j--;
  67.         if (j == -1)
  68.             return false; // больше перестановок нет
  69.         int k = _start.size() - 1;
  70.         while (_state[j] >= _state[k]) k--;
  71.         std::swap(_state[j], _state[k]);
  72.         int l = j + 1, r = _start.size() - 1; // сортируем оставшуюся часть последовательности
  73.         while (l < r)
  74.             std::swap(_state[l++], _state[r--]);
  75.         return true;
  76.     }
  77. };
  78.  
  79.  
  80.  
  81. // ПРИЕМР
  82. int main() {
  83.     std::vector<int> arr = { 1, 2, 3, 4 };
  84.  
  85.     BruteForce<int> bf(arr, 2);
  86.  
  87.     while (bf.next()) {
  88.         for (auto a : bf.get()) {
  89.             std::cout << a << " ";
  90.         }
  91.         std::cout << std::endl;
  92.     }
  93. }
  94.  
  95. /**
  96.  * На выходе получаем:
  97.  * 1 2 4 3
  98.  * 1 3 2 4
  99.  * 1 3 4 2
  100.  * 1 4 2 3
  101.  * 1 4 3 2
  102.  * 2 1 3 4
  103.  * 2 1 4 3
  104.  * 2 3 1 4
  105.  * 2 4 1 3
  106.  * 3 1 2 4
  107.  * 3 1 4 2
  108.  * 3 2 1 4
  109.  * 3 4 1 2
  110.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement