Iloczyn liczb znajdujacych sie w pozostalych komorkach

0

Witam, mam problem w zadaniu, do konca nie rozumiem jak funkcje product_left i product_right maja dzialac :

Napisz program, który pobierze od użytkownika tablicę liczb typu long long (nie więcej niż 10 elementów) i dla każdej komórki tablicy obliczy i wyświetli iloczyn wszystkich liczb znajdujących się w pozostałych komórkach.

W tym celu napisz funkcje obliczającą ,dla każdej komórki tablicy wejściowej input, iloczyn liczb znajdujących się na lewo od niej (product_left) oraz iloczyn liczb znajdujących się na prawo od niej (product_right).

int product_left(const long long *input, int input_size, long long *output, int output_size);
int product_right(const long long *input, int input_size, long long *output, int output_size);

output - wskaźnika na tablicę wyjściową, do której mają zostać zapisane iloczyny (pierwsza (w przypadku funkcji product_left) lub ostatnia (w przypadku funkcji product_right) komórka tablicy ma posiadać wartość 1),

--- Tutaj pojawia sie problem, ponieważ rozmiary tablic powinny byc rowne i nie rozumiem tego ze komorka tablicy w funkcji product right ma ma posiadac wartosc 1.

Czyli to ma byc tak ze na output[0] zapisuje iloczyn liczb po LEWO, a na output[1] zapisuje iloczyn liczb na prawo? Takto czemu rozmiary maja byc rowne. Nie rozumiem tego totalnie,

Moglbym zrobic tak, ze zapisuje iloczyn liczb po lewo do output[0] potem iloczyn liczb po prawo do output[1], potem liczę iloczyn iloczynow i dodaje go do innej tablicy i wywoluje tyle razy te funkcje, dopoki nie wypelni sie tablica i wyswietlic.

Przykladowa interakcja z programem - Sukces :

Podaj liczby: 3 1 -2 4 5 -8 -6 8 -10 -6 -9 -1⏎
-921600 -2764800 1382400 -691200 -552960 345600 460800 -345600 276480 460800 ⏎
2

Najlepiej będzie wytłumaczyć na przykładzie:

tablica wejściowa -> [ 2 , 5 , 7 ,-1 , 4 , 2 ]
product_left --> [ 1 , 2 , 2⋅5 , 2⋅5⋅7 , 2⋅5⋅7⋅(-1) , 2⋅5⋅7⋅(-1)⋅4 ]
product_right --> [ 5⋅7⋅(-1)⋅4⋅2 , 7⋅(-1)⋅4⋅2 , (-1)⋅4⋅2 , 4⋅2 , 2 , 1 ]

Jak widać dla operacji product_left tablica wyjściowa zawsze będzie zawierała jedynkę w pierwszej komórce , a dla product_right jedynka będzie zawsze w ostatniej komórce.

Dzieje się tak dlatego, że tablica wyjściowa musi posiadać taką samą liczbę elementów co wejściowa, a w operacji product_left nie jest zdefiniowany iloczyn dla pierwszego elementu tablicy wyjściowej ( nie ma nic na lewo do pomnożenia ), więc trzeba tutaj wstawić jakąś wartość domyślną. ( analogicznie jest dla product_right )

0

Dziala, ale mam jakis problem bo SIGSEGV sie wlacza, niestety musialem zrobic 4 tablice, moglbym je zminimalizowac do 3 tablic, ale juz tak jest przejrzysciej, nie wiem jak to zmienic. Wie ktos czemu ten SIGSEGV?

#include <stdio.h>
#include <stdlib.h>
#include "vector_utils.h"

int read_vector_ll(long long* tab, int size, int stop_value)
{
    if(tab == NULL || size <= 0 ) return -1;
    int sizeD = 0;
    long long int temp = 0;

    while (sizeD < size)
    {
        int read = scanf("%lld", &temp);
        if ((read <= 0)) return -1;
        if (read != 1 || temp == stop_value) break;
        *(tab + sizeD) = temp;
        ++sizeD;
    }
    return sizeD;
}

int product_left(const long long *input, int input_size, long long *output, int output_size)
{
    if(input == NULL || input_size <= 0 || output_size <= 0 || output == NULL || output_size != input_size) return 1;


    long long temp = 1;

    for(int i = 0; i < input_size; i++)
    {
        temp *= *(input + i);
        *(output + i + 1) = temp;
    }
    *(output + 0) = 1;
    return 0;
}

int product_right(const long long *input, int input_size, long long *output, int output_size)
{
    if(input == NULL || input_size <= 0 || output_size <= 0 || output == NULL || output_size != input_size) return 1;

    long long temp = 1, tab = 0;

    for(int i = input_size - 1; i >= 0; i--)
    {
        tab = *(input + i);
        temp *= tab;
        *(output + i - 1) = temp;
    }
    *(output + input_size - 1) = 1;
    return 0;
}

void display_vector_ll(const long long* tab, int size)
{
    for(int i=0; i<size; i++)
    {
        printf("%lld ", *(tab+i));
    }
}

#include <stdio.h>
#include <stdlib.h>
#include "vector_utils.h"

int main()
{
    long long tab1[10], tab2[10], tab3[10], tab4[10];
    long long *vec1 = tab1, *vec2 = tab2, *vec3 = tab3, *vec4 = tab4;

    printf("Podaj liczby: ");
    int size = read_vector_ll(vec1, 10, -1);
    if(size == -1)
    {
        printf("Incorrect input");
        exit(1);
    }
    if(size == 0)
    {
        printf("Not enough data available");
        exit(3);
    }

    int read = product_left(vec1, size, vec2, size);
    if(read == 1)
    {
        printf("Incorrect input");
        exit(1);
    }

    int read2 = product_right(vec1, size, vec3, size);
    if(read2 == 1)
    {
        printf("Incorrect input");
        exit(1);
    }

    for(int i = 0; i < size; i++)
    {
        *(vec4 + i) = *(vec2 + i) * *(vec3 + i);
    }

    display_vector_ll(vec4, size);

    return 0;
}



screenshot-20190826200327.png

screenshot-20190826194219.png

0

Pętla w product_right, wychodzisz poza a w zasadzie przed tablicę.

for(int i = input_size - 1; i >= 0; i--)
    {
        tab = *(input + i);
        temp *= tab;
        *(output + i - 1) = temp;    // <- w ostatniej iteracji i = 0, czyli *(output + 0 - 1), czyli output[-1]
    }
0

Ciag dalszy dramy, wkleilem sobie czesc testu ktorego mi nie przechodzi i jest cos dziwnego, poniewaz po wywolaniu funkcji product_left zmienia mi tablice CONST ktora jest uzywana do testu, ale ja jej nigdzie nie uzywam! przez co sie wywala, nie mam bladego pojecia o co tutaj chodzi. Ktos mi moze to wytlumaczyc?

0
#ifndef VECTOR_UTILS_H
#define VECTOR_UTILS_H


int read_vector_ll(long long* tab, int size, int stop_value);
int product_left(const long long *input, int input_size, long long *output, int output_size);
int product_right(const long long *input, int input_size, long long *output, int output_size);
void display_vector_ll(const long long* tab, int size);


#endif // VECTOR_UTILS_H

#include <stdio.h>
#include <stdlib.h>
#include "vector_utils.h"

int read_vector_ll(long long* tab, int size, int stop_value)
{
    if(tab == NULL || size <= 0 ) return -1;
    int sizeD = 0;
    long long int temp = 0;

    while (sizeD < size)
    {
        int read = scanf("%lld", &temp);
        if ((read <= 0)) return -1;
        if (read != 1 || temp == stop_value) break;
        *(tab + sizeD) = temp;
        ++sizeD;
    }
    return sizeD;
}

int product_left(const long long *input, int input_size, long long *output, int output_size)
{
    if(input == NULL || input_size <= 0 || output_size <= 0 || output == NULL || output_size != input_size || input_size == 1) return 1;


    long long temp = 1;

    for(int i = 0; i < input_size; i++)
    {
        temp *= *(input + i);
        *(output + i + 1) = temp;
    }
    *(output + 0) = 1;
    return 0;
}

int product_right(const long long *input, int input_size, long long *output, int output_size)
{
    if(input == NULL || input_size <= 0 || output_size <= 0 || output == NULL || output_size != input_size || input_size == 1) return 1;

    long long temp = 1, tab = 0;

    for(int i = input_size - 1; i > 0; i--)
    {
        tab = *(input + i);
        temp *= tab;
        *(output + i - 1) = temp;
    }
    *(output + input_size - 1) = 1;
    return 0;
}

void display_vector_ll(const long long* tab, int size)
{
    for(int i=0; i<size; i++)
    {
        printf("%lld ", *(tab+i));
    }
}

#include <stdio.h>
#include <stdlib.h>
#include "vector_utils.h"

int main()
{
    long long tab1[100], tab2[100], tab3[100], tab4[100];
    long long *vec1 = tab1, *vec2 = tab2, *vec3 = tab3, *vec4 = tab4;

    printf("Podaj liczby: ");
    int size = read_vector_ll(vec1, 10, -1);



    long long input_array[] = {9LL, 4LL};
    const long long expected_array[] = {1LL, 9LL};
    long long output[2];

    printf("#####START#####");
    product_left(input_array, 2, output, 2);
    printf("#####END#####");


    if (!0)
    {
        int ok = 0;

        for (int i = 0; i < 2; ++i)
            ok += (output[i] != expected_array[i]);

        if (ok)
        {
            printf("Powinno być: [1, 9]\n");

            printf("\nTablica po wywołaniu funkcji product_left: ");

            for (int i = 0; i < 2; ++i)
                printf("%lld ", output[i]);

            printf("\n");


        }
    }




    if(size == -1)
    {
        printf("Incorrect input");
        exit(1);
    }
    if(size == 0)
    {
        printf("Not enough data available");
        exit(3);
    }

    int read = product_left(vec1, size, vec2, size);
    if(read == 1)
    {
        printf("Incorrect input");
        exit(1);
    }

    int read2 = product_right(vec1, size, vec3, size);
    if(read2 == 1)
    {
        printf("Incorrect input");
        exit(1);
    }

    for(int i = 0; i < size; i++)
    {
        *(vec4 + i) = *(vec2 + i) * *(vec3 + i);
    }

    display_vector_ll(vec4, size);

    return 0;


}





0

ktos cos?

0
    long long input_array[] = {9LL, 4LL};
    const long long expected_array[] = {1LL, 9LL};
    long long output[2];

Kompilator najprawdopodobniej umieścił te tablice obok siebie w pamięci.
Jeżeli w product_left() dochodzi do zmian w expected_array[] mimo że nie odwołujesz się do niej to znaczy że gdzieś piszesz poza pamięcią. W product_left() nie ma za dużo miejsc w których to może się dziać.
Dalej podpowiadać?

0
Delor napisał(a):
    long long input_array[] = {9LL, 4LL};
    const long long expected_array[] = {1LL, 9LL};
    long long output[2];

Kompilator najprawdopodobniej umieścił te tablice obok siebie w pamięci.
Jeżeli w product_left() dochodzi do zmian w expected_array[] mimo że nie odwołujesz się do niej to znaczy że gdzieś piszesz poza pamięcią. W product_left() nie ma za dużo miejsc w których to może się dziać.
Dalej podpowiadać?

Mysle ze chodzi o to : *(output + i + 1) = temp; ?
Wolalbym zebys mi powiedzial jak znajdywac takie rzeczy, poniewaz stoje w miejscu i nie moge isc dalej przez takie bledy.
Ale sprawdzalem valgrindem leaki i bylo wszystko ok. Siedze nad tym zadaniem od miesiaca i nie moge go zrobic, te testy w wiekszosci nic nie pomagaja, a wrecz przeciwnie myla.

0

Valgrind nic nie pokazał bo nie ma wycieku pamięci. Wychodzisz poza zakres tablicy.
Pomaga odpalenie debugera i sprawdzenie, krok po kroku, jakie wartości przyjmują zmienne w podejrzanym fragmencie kodu.
Te testy zrobiły bardzo dużo. Zawęziły obszar poszukiwań do konkretnej funkcji i powiedziały jakiego błędu w niej szukać.

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