Przesunięcie elementów macierzy

Odpowiedz Nowy wątek
Brunatny Programista
2017-11-01 16:44
Brunatny Programista
0

W kolejnym zadaniu muszę napisać program, który w tablicy prostokątnej przesunie cyklicznie wszystkie wiersze o indeksach parzystych w prawo o jeden element. Zadeklarowałem tablicę a[10][20] i próbowałem zrobić to tak:

for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 20; j++) {
        if (i % 2 == 0) {
            int t = a[i][19];
            for (j = 19; j > 0; j--)
                swap(a[i][j], a[i][j - 1]);
            t = a[i][0];
        }
    }
}

Chciałem wykorzystać przesunięcie elementów tablicy jednowymiarowej, ale chyba nie da się tego tak prosto załatwić. Ktoś doradzi?

edytowany 2x, ostatnio: kq, 2017-11-01 16:48
Poprawiłem formatowanie, bo jedna spacja jest prawie tak samo czytelna jak zero spacji. - kq 2017-11-01 16:49

Pozostało 580 znaków

kq
2017-11-01 17:17
kq
Moderator C/C++

Rejestracja: 7 lat temu

Ostatnio: 1 godzina temu

Lokalizacja: Szczecin

0
for (int j = 0; j < 20; j++) {
    if (i % 2 == 0) {

Jeśli kompilator się nie zorientuje to niepotrzebnie wykonasz 20x to samo porównanie dla każdego rzędu.

int t = a[i][19];
for (j = 19; j > 0; j--)
    swap(a[i][j], a[i][j - 1]);
t = a[i][0];

Zapamiętujesz najbardziej prawy element do t. Przesuwasz go na maksa w lewo. Zapamiętujesz go znów do t. To jest ok, chociaż nadmiarowe. Ale przesunięcie o 1 wykonujesz 20x, więc wracasz do punktu wyjścia. Zamiast tego, możesz po prostu napisać:

for(int i = 0; i < 10; ++i) {
    auto& row = a[i];
    if(i % 2 == 0)
        rotate(begin(row), end(row)-1, end(row));
}

https://wandbox.org/permlink/wEukh1w76akiM8Qm


edytowany 1x, ostatnio: kq, 2017-11-01 17:43

Pozostało 580 znaków

Brunatny Programista
2017-11-01 17:22
Brunatny Programista
0

@kq Bardzo chętnie bym tak napisał, tylko nie mam pojęcia, co to wszystko znaczy.

Pozostało 580 znaków

Brunatny Programista
2017-11-01 17:23
Brunatny Programista
0

@kq Najlepiej, żeby kod był jak najprostszy. Ważne tylko, by robił to, co powinien.

Pozostało 580 znaków

kq
2017-11-01 17:26
kq
Moderator C/C++

Rejestracja: 7 lat temu

Ostatnio: 1 godzina temu

Lokalizacja: Szczecin

0

Zgadzam się. Przedstawiłem dokładnie taki kod, iteracja po zewnętrznej tablicy, a gdy indeks jest parzysty - rotacja, czyli cykliczne przesunięcie elementów. Wszystko zwięźle, prosto i czytelnie napisane.

Może miałeś na myśli słowo "prymitywny", t.j. wykonany wyłącznie za pomocą prymitywnych konstrukcji? Jeśli tak, to

for(int i = 0; i < 10; ++i) {
    if (i % 2 == 0) {
        for (int j = 0; j < 20; j++) {
            swap(a[i][j], a[i][j - 1]);
        }
    }
}

Ale taki kod nie jest ani prostszy do napisania, ani do czytania, ani do optymalizacji dla kompilatora.


edytowany 1x, ostatnio: kq, 2017-11-01 17:28

Pozostało 580 znaków

Brunatny Programista
2017-11-01 17:52
Brunatny Programista
0

@kq Skoro tak to ująłeś to tak, chodzi mi o prymitywny kod. Jednak on nie zadziałał. Przesunięcie wychodzi w lewo. I coś dziwnego się dzieje się na końcach wierszy.

Pozostało 580 znaków

kq
2017-11-01 17:54
kq
Moderator C/C++

Rejestracja: 7 lat temu

Ostatnio: 1 godzina temu

Lokalizacja: Szczecin

0

Phew, przepraszam, nie tę pętlę co trzeba wywaliłem.

for(int i = 0; i < 10; ++i) {
    if (i % 2 == 0) {
        for (int j = 19; j > 0; j--) {
            swap(a[i][j], a[i][j - 1]);
        }
    }
}

Pozostało 580 znaków

Brunatny Programista
2017-11-01 18:00
Brunatny Programista
0

@kq Jesteś moim bohaterem! Dziękuję ci bardzo.

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0