Как сдвинуть элементы массива с побитовым операндом регистра сдвига?

У меня есть массив 2d, содержащий числа, в которых я хотел бы переместить все элементы на один и иметь последнее значение в каждой строке, перенесенное на первый элемент. Например, строка, содержащая 1, 2, 3, будет преобразована в 3, 1, 2.

До сих пор мне не удавалось использовать оператор сдвига в ячейках памяти массива, который я хочу изменить. Я думал, что смогу поместить все значения в новый массив, затем поменять местами первое и последнее значения, расположенные по этим адресам, а затем сдвинуть последние 8 значений. Неудачно.

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

int const ROWS = 4;
int const COLS = 9;

 int numberTable[ROWS][COLS] = {
    {1, 2, 3, 4, 5, 6, 7, 8, 9},
    {7, 2, 8, 4, 5, 4, 7, 3, 1},
    {9, 9, 7, 4, 9, 9, 8, 7, 6},
    {6, 3, 7, 4, 5, 4, 5, 7, 9}
};

int shiftTable[ROWS][COLS];


unsigned int num1 = 0;
unsigned int num2 = 0;
unsigned int num3 = 0;
unsigned int num4 = 0;
unsigned int newNum1 = 0;
unsigned int newNum2 = 0;
unsigned int newNum3 = 0;
unsigned int newNum4 = 0;

unsigned concatenate(unsigned, unsigned);

int _tmain(int argc, _TCHAR* argv[])
{

    int *ptrTable;
    ptrTable = &numberTable[0][0];

    for (int i = 0; i <= 8; i++){

        newNum1 = numberTable[0][i];
        newNum2 = numberTable[1][i];
        newNum3 = numberTable[2][i];
        newNum4 = numberTable[3][i];
        num1 = concatenate(num1, newNum1);
        for (int j = 0; j < 4; j++){
            numberTable[0][i] >>= 1;
            cout << "Before table shift: "<<ptrTable << endl;
            *ptrTable >>= 1;
            cout << "After Table Shift: "<<ptrTable << endl;

        }
    }
    num1 = concatenate(num1, newNum1);
    unsigned int *num1ptr;
    num1ptr = &num1;
    cout << *num1ptr << endl;
    *num1ptr >>= 1;
    cout << *num1ptr<< endl;
    num1 >>= 1;
    cout << num1;

    getchar();
    return 0;
}


unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while (y >= pow)
        pow *= 10;
    return x * pow + y;
}

person nattylightfortheladies    schedule 28.10.2015    source источник
comment
это не то, что делает оператор сдвига >>.   -  person GreatAndPowerfulOz    schedule 28.10.2015
comment
Математически я понимаю, что он делает, но мне трудно перевести это в код. Если бы это был бит-вектор, я бы знал, что происходит. Мне еще предстоит найти какие-либо ресурсы о том, как операнд обрабатывает массивы. Я знаю, что думаю об этом совершенно неправильно, но я не знаю, с чего начать.   -  person nattylightfortheladies    schedule 28.10.2015
comment
вы можете перегрузить оператор для работы с классом, имеющим массивы, но встроенный оператор работает не с массивами, а с более простыми элементами. Если вы хотите «сдвинуть» всю строку двумерного массива, вам нужно написать функцию, которая сделает это самостоятельно.   -  person GreatAndPowerfulOz    schedule 28.10.2015
comment
Интересно. Я предполагал, что это будет похоже на добавление 4 к адресу местоположения, но теперь я понимаю, что это также не работает математически.   -  person nattylightfortheladies    schedule 28.10.2015


Ответы (1)


Оператор C++ Shift ведет себя не так, как вы думаете. На самом деле вы должны использовать std::rotate из стандартной библиотеки алгоритмов для поворота массива . Чтобы дать представление о том, как это работает

Образец кода

#include <iostream>
#include <algorithm>
#include <array>
#include <iterator>
int const ROWS = 4;
int const COLS = 9;


int main() {
    int numberTable[ROWS][COLS] = {
        {1, 2, 3, 4, 5, 6, 7, 8, 9},
        {7, 2, 8, 4, 5, 4, 7, 3, 1},
        {9, 9, 7, 4, 9, 9, 8, 7, 6},
        {6, 3, 7, 4, 5, 4, 5, 7, 9}
    };
//  std::array<std::array<int, COLS>, ROWS> numberTable = {{
//      {1, 2, 3, 4, 5, 6, 7, 8, 9},
//      {7, 2, 8, 4, 5, 4, 7, 3, 1},
//      {9, 9, 7, 4, 9, 9, 8, 7, 6},
//      {6, 3, 7, 4, 5, 4, 5, 7, 9}
//  }};
    // Left Rotation
    for(auto& row: numberTable) {
         std::rotate(std::begin(row),std::begin(row) + 1, std::end(row));
    }
    for(auto& row: numberTable) {
        std::copy(std::begin(row), 
                  std::end(row), 
                  std::ostream_iterator<int>(std::cout,",") 
                 ); 
        std::cout << std::endl;
    }

    return 0;
}

Пример вывода

2,3,4,5,6,7,8,9,1,
2,8,4,5,4,7,3,1,7,
9,7,4,9,9,8,7,6,9,
3,7,4,5,4,5,7,9,6,
person Abhijit    schedule 28.10.2015