Циклический сдвиг С++

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Mozy, 28 Oct 2009.

  1. Mozy

    Mozy Member

    Joined:
    15 Mar 2009
    Messages:
    52
    Likes Received:
    34
    Reputations:
    6
    Всем доброго времени суток
    потребовалось реализовать шаблон функции циклического сдвига в любую сторону двухмерного квадратного массива.

    Code:
    Работающие шаблоны приведены ниже
    
     
    #1 Mozy, 28 Oct 2009
    Last edited: 17 Nov 2009
  2. Chrek625

    Chrek625 Elder - Старейшина

    Joined:
    6 Jun 2006
    Messages:
    143
    Likes Received:
    13
    Reputations:
    -7
    По моему мнению так не бывает чтобы ничего не работало...
    Что именно не работает скажите для начала?
    И код полностью выложите а не фрагмент.
     
  3. Lee_fx

    Lee_fx Elder - Старейшина

    Joined:
    27 Sep 2008
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    Code:
    #include <algorithm>
    
    template < typename T >
    void _rotate(T *arr, int size, int step, bool right) {
    	if(right)
    	for(int i=0; i<size; ++i) rotate(arr[i], arr[i]+size-step, arr[i]+size);
    	else
    	for(int i=0; i<size; ++i) rotate(arr[i], arr[i]+step, arr[i]+size);
    }
    
    ...
    
    _rotate(matrix, 5, 2, 0); // Сдвинуть на 2 влево
    _rotate(matrix, 5, 1, 1); // Сдвинуть на 1 вправо
     
    1 person likes this.
  4. Mozy

    Mozy Member

    Joined:
    15 Mar 2009
    Messages:
    52
    Likes Received:
    34
    Reputations:
    6
    Чувак спасибо
    Классно, наконец я увидел реализацию с разворотами
    Только проблема в том ,что это для одномерного массива,
    а мне бы для двухмерного квадратного
     
  5. Lee_fx

    Lee_fx Elder - Старейшина

    Joined:
    27 Sep 2008
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    это как раз для двумерного [n][n]
    Пр.
    int matrix[5][5] = {
    1,2,3,4,5,
    6,7,8,9,1,
    1,2,3,4,5,
    6,7,8,9,1,
    6,9,7,2,6
    };
     
  6. Mozy

    Mozy Member

    Joined:
    15 Mar 2009
    Messages:
    52
    Likes Received:
    34
    Reputations:
    6
    а вверх вниз ?
     
  7. Lee_fx

    Lee_fx Elder - Старейшина

    Joined:
    27 Sep 2008
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    В таком случае stl похоже не поможет.
    Повелосипедить чуток - создать пустую копию и забить как надо =)
     
  8. Mozy

    Mozy Member

    Joined:
    15 Mar 2009
    Messages:
    52
    Likes Received:
    34
    Reputations:
    6
    Итак
    шаблон функции я реализовал
    Code:
    #include <vector>
    #include <algorithm>
    
    
    enum Direction//перечисление сторон
    {
    Right = 0,
    Left,
    Up,
    Down
    };
    
    template <typename T>
    inline void shlrud(T **array, int size, int step, Direction dir)
    {
    vector<T> _v;//объявление вектора
    for (int i =0; i < size; i++)
    {
        int j;
        _v.clear();//очищаем вектор
        for (j = 0; j < size; j++)
        {
            switch (dir)
            {
                case Right:
                case Left:
                _v.push_back(array[i][j]);//забиваем в вектор строчку массива
                break;
                case Down:
                case Up:
                _v.push_back(array[j][i]);//забиваем в вектор строчку массива
                break;
            }
        }
            switch (dir)
            {
                case Right:
                case Down:
                rotate(_v.begin(),//делаем циклический сдвиг 
                    _v.end()-step,//методом разворотов
                    _v.end());
    			break;
                case Left:
                case Up:
                rotate(_v.begin(),//делаем циклический сдвиг 
                    _v.begin()+step,//методом разворотов
                    _v.end());
    			break;
            }
        for (j = 0; j < size; j++)
        {
            switch (dir)
            {
                case Right:
                case Left:
                array[i][j] = _v[j];//возвращаем обработанную строчку в массив
                break;
                case Down:
                case Up:
                array[j][i] = _v[j];//возвращаем обработанную строчку в массив
                break;
            }
        }
    }
    
    }
    

    Пользуйтесь на здоровье


    Но проблема в другом:
    Оказывается надо было написать без использования STL.
     
    #8 Mozy, 13 Nov 2009
    Last edited: 17 Nov 2009
  9. Mozy

    Mozy Member

    Joined:
    15 Mar 2009
    Messages:
    52
    Likes Received:
    34
    Reputations:
    6
    Вот ещё один вариант написал
    (самописный, без испоьзования stl)
    Code:
    template <typename T>
    void Reverse(T **Massive,int size, int StartElem, int FinishElem,int direction)
    { 	
    int i,j;
    T t;
    
    	switch(direction){
    
    		/*Горизонтально*/
    		case 1:
    		case -1:
    		for(j=0;j<size;j++){
    			for (i=0;i<=(FinishElem-StartElem)/2;i++) 
    			{
                      t=Massive[j][StartElem+i]; 	 
                      Massive[j][StartElem+i]=Massive[j][FinishElem-i]; 		       
                      Massive[j][FinishElem-i]=t; 	
    			} 
    		}
    		break;
    
    		/*Вертикально*/
    		case 2:
    		case -2:
    		for(j=0;j<size;j++){
    			for (i=0;i<=(FinishElem-StartElem)/2;i++) 
    			{
                      t=Massive[StartElem+i][j]; 	 
                      Massive[StartElem+i][j]=Massive[FinishElem-i][j]; 		       
                      Massive[FinishElem-i][j]=t; 	
    			} 
    		}
    		break;
    	}
    }
    
    template <typename T>
    void cyclicShift(T **Massive, int size, int k,int direction)
    { 	
    	switch(direction){
    
    		case 1:
    		case 2:
            Reverse(Massive,size,0,	size-1,	direction); //разворачиваем массив   
            Reverse(Massive,size,0,	k-1,	direction); //разворачиваем первые к элементов
    		Reverse(Massive,size,k,	size-1,	direction); //разворачиваем последние n-k эллементов
    		break;
    
    		case -1:
    		case -2:
            Reverse(Massive,size,0,	k-1,	direction); //разворачиваем первые к элементов
    		Reverse(Massive,size,k,	size-1,	direction); //разворачиваем последние n-k эллементов
    		Reverse(Massive,size,0,	size-1,	direction); //разворачиваем массив  
    		break;
    	}
    }
    
    
    Всем спасибо за проявленное внимание