• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Poprawa kodu

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
0 głosów
131 wizyt
pytanie zadane 18 czerwca 2017 w C i C++ przez iWantCode Bywalec (2,170 p.)

Jak przerobić ten kod z zadania aby używał wskaźników i czy w tym wypadku przyśpieszą program? Zadanie było takie aby macierz 10x10 uzupełnić 0 oprócz jednej przekątnej, którą uzupełniamy losowymi liczbami od 1-9 i podajemy potem sumę wszystkich liczb w tej macierzy.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{

    srand(time(NULL));
    short int macierz[10][10];
    for(int j = 0; j <= 9; j++)
    {
        for(int i = 0; i <= 9; i++)
        {
            if(i==j) macierz[j][i] = ((rand() % 9) + 1);
            else macierz[j][i] = 0;
        }
    }

    for(int j = 0; j <= 9; j++)
    {
        for(int i = 0; i <= 9; i++)
        {
            cout << macierz[j][i];
        }
        cout<<endl;
    }

    {
        int suma=0;
        for(int i = 0; i <= 9; i++)
            {
                suma+= macierz[i][i];
            }
        cout <<"    " <<suma ;
    }

    return 0;
}

 

komentarz 18 czerwca 2017 przez unknown Nałogowiec (39,620 p.)

czy w tym wypadku przyśpieszą program?

Musiałbyś używać kompilatora sprzed ponad 20 lat żeby użycie wskaźników przyśpieszyło program. 

komentarz 18 czerwca 2017 przez Buby Pasjonat (19,590 p.)

Zakładam, że wykładowcy chodziło o zastosowanie wskaźnika jak wartownika - pocztaj o wyszukiwaniu liniowym z wartownikiem - możesz w ten sposób zmienjszyć czynnik stały przy przeliczniku liniowym operacji. Z resztą zaraz to zaprezentuje w poście poniżej. Oczywiście, różnica w wydajności jest minimalna, ponieważ gdy wielkość danych dąży do nieskończoności, oba algorytmy będą miały złożoność liniową. smiley

1 odpowiedź

0 głosów
odpowiedź 18 czerwca 2017 przez Buby Pasjonat (19,590 p.)

Hej smiley Jak już wspomniał unknown, w komentarzu powyżej, zastosowanie wskaźników w tym kodzie raczej nie spowoduje widocznego przyśpieszenia programu. Co prawda, można troszkę upiększyć Twój kod, żeby działał "lepiej", jeśli mogę to tak określić - zauważ, że w pętli, która wypełnia liczbami Twoją macierz, za każdym razem wykonujesz operację sprawdzenia, czy i == j.

Przy założeniu, że operacja porównania jest tak samo kosztowna, jak operacja przypisania, kiedy wyeliminujemy if'a, który znajduje się w tej pętli, zyskamy 10*10 = 100 operacji, kosztem 10 dodatkowych przypisań, wynikających z tego, że zapiszemy 0 na przekątnej. Ciągle jednak zaoszczędzimy 90 operacji, co jest jakimś, choć niezauważalnym zyskiem. Poprawiony kod z komentarzami poniżej:

#include <iostream>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
int main()
{
 
    srand(time(NULL));
    short int macierz[10][10];
    for(int j = 0; j <= 9; j++)
    {
        for(int i = 0; i <= 9; i++)
        {
            macierz[j][i] = 0; //tutaj nie wykonujemy ifow
        }
    }
 
    for(int j = 0; j <= 9; j++)
    {
        for(int i = 0; i <= 9; i++)
        {
            cout << macierz[j][i];
        }
        cout<<endl;
    }
 
    {
        int suma=0;
        for(int i = 0; i <= 9; i++)
            {
                macierz[i][i] = ((rand() % 9) + 1); //losowanie
                suma+= macierz[i][i];
            }
        cout <<"    " <<suma ;
    }
 
    return 0;
}

 

A teraz w ramach ciekawoski, pokażę, jak taką wielowymiarową tablicę można przejść przy pomocy zwykłych wskaźników. Zauważmy, że tablica wielowymiarowa w języku C++ jest zapisana, jak zwykła tablica, kolejnością wymiarów, tj. T[3][3] => T[9], gdzie wymiary są zapisane kolejno. Ciekawy artykuł na ten temat można znaleźć tutaj.

Korzystając z tej wiedzy, możemy inkrementować wskaźnik, dopóki nie znajdzie się za ostatnim elementem. Takie rozwiązanie nie zwiększa wydajności - liczba operacji jest taka sama. Ponadto kod staje się zawiły i nie polecam stosować takich rozwiązań - pokazuję go tylko jako ciekawostkę.

#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
    int arr[10][10];
    int* first = &arr[0][0]; //adres pierwszego elementu
    int* last = &arr[10][10]; //adres za ostatnim elementem

    std::srand(std::time(NULL));
    while (first != last) {
        *first++ = 0;
    }

    int sum = 0;
    for (size_t i = 0; i < 10; ++i) {
        arr[i][i] = (rand() % 9) + 1;
        sum += arr[i][i];
    }

    std::cout << "Suma wynosi: " << sum << std::endl;
    std::cout << "\nZawartosc tablicy: " << std::endl;
    for (size_t i = 0; i < 10; ++i) {
        for (size_t j = 0; j < 10; ++j) {
            std::cout << arr[i][j] << "  ";
        }
        std::cout << std::endl;
    }
    return 0;
}

Pozdrawiam! smiley

Podobne pytania

0 głosów
1 odpowiedź 134 wizyt
pytanie zadane 28 maja 2017 w C i C++ przez Barteck125 Obywatel (1,120 p.)
0 głosów
1 odpowiedź 156 wizyt
0 głosów
1 odpowiedź 158 wizyt
pytanie zadane 22 kwietnia 2021 w Python przez Patryk Wiśniewski Nowicjusz (140 p.)

90,900 zapytań

139,572 odpowiedzi

313,905 komentarzy

60,373 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...