Problem z tablica jednowymiarowa.

0

Napisz funkcję, która jako argument dostaje tablicę liczb całkowitych oraz jej
rozmiar. Zakładamy, że w tablicy na pewno tylko jedna komórka ma wartość 0 i
nie jest ona ani na początku ani na końcu tablicy. Funkcja ma wyświetlić na
standardowym wyjściu dwie średnie arytmetyczne liczb przed komórką z 0 i po.
W programie głównym należy stworzyć wskaźnik na tablicę oraz wczytać rozmiar
tablicy od użytkownika. Należy stworzyć oddzielną funkcję do zalokowania
pamięci oraz wypełnienia tablicy danymi.

Nie wiem do końca jak się poruszać po tablicy do tego zera i później jak przejść za to zero.

2

Zero jest gdzieś w środku. Idź dalej tak długo aż napotkasz zero. Potem przeskocz element (zero). Potem idź tak długo aż dojdziesz do końca tablicy.

4

Nie wiem czy dobrze zrozumiałem - nie wiesz jak napisać pętlę z ifem w środku, ewentualnie dwie pętle? W takim razie lepiej zajrzeć do podstawowego kursu programowania.

2

Najpierw sobie rozwiąż prostszy problem i wypisz sumę liczb przed i po zerze. Po tablicy idziesz forem, iterując od 0 do długości tablicy-1. Po drodze sumujesz te elementy w jakiejś zmiennej. Jak trafiasz na 0 to wypisujesz, zerujesz sumę i idziesz dalej. Potem to rozszerz o dzielenie przez ilość elementów (będziesz musiał do tego zapamiętać pozycję zera).

A tak w ogóle

#include <array>
#include <algorithm>
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>

int main() {
    using namespace boost::accumulators;

    std::array arr = {1, 2, 3, 1, 0, 2, 3, 4};
    auto it = std::find(arr.begin(), arr.end(), 0);
    accumulator_set<double, features<tag::mean>> accumulator;
    accumulator = std::for_each(arr.begin(), it, accumulator);
    std::cout << mean(accumulator) << std::endl;
    accumulator = {};
    accumulator = std::for_each(it+1, arr.end(), accumulator);
    std::cout << mean(accumulator) << std::endl;
}
0
kq napisał(a):

Zero jest gdzieś w środku. Idź dalej tak długo aż napotkasz zero. Potem przeskocz element (zero). Potem idź tak długo aż dojdziesz do końca tablicy.
Oto co udało mi się wymyśleć czy to może w jakiś sposób działać ze poruszam się z jednej strony a potem z drugiej ?

2

@Maciek48:

  1. Wstawiaj kod w formie tekstu.
  2. Miała być tablica liczb całkowitych, a masz float i sumę jako int.
  3. Sprawdź warunek drugiej pętli.
  4. Średnia jako int to nie najlepszy pomysł
  5. Poczytaj o słowie kluczowym continue.
0
leto napisał(a):

@Maciek48:

  1. Wstawiaj kod w formie tekstu.
  2. Miała być tablica liczb całkowitych, a masz float i sumę jako int.
  3. Sprawdź warunek drugiej pętli.
  4. Średnia jako int to nie najlepszy pomysł
  5. Co robi licznik ?
  6. Poczytaj o słowie kluczowym continue.

Poprawilem warunek nie wiem juz czy dobrze a licznik daje mi mianownik przy liczeniu srednia tzn tak pomyslalem ze bedzie wsumie git ale no pewny tego nie jestem.

void funkcja4(int a, int T[])
{
    int suma1 = 0;
    int suma2 = 0;
    int licznik1=0;int licznik2=0;
    double srednia1, srednia2;
    for(int i = 0; i < a; i++)
    {
        if(T[i] != 0)
        {
            suma1 = suma1 + T[i];
            licznik1++;
            
        }
    }
    for(int i = a; i > 0 ; i--)
    {
        if(T[i] != 0 )
        {
            suma2 = suma2 + T[i];
            licznik2++;
        }
    }
    srednia1 = suma1/licznik1;
    srednia2 = suma2/licznik2;
    cout << "Srednia przed zerem jest rowna: " << srednia1 << " ,a po zerze jest rowna " << srednia2 << endl;
};
2

@Maciek48:
Problemy są dwa:

  1. W drugiej pętli zaczyna iterację od rozmiaru tablicy, ale zapominasz, że w programowaniu zwykle indeksujemy od zera.
    To znaczy, że ostatni element tablicy jest na pozycji rozmiar - 1.
  2. Po drugie suma i licznik są typu int i przed przypisaniem do zmiennej double występuje niejawna konwersja na int, żeby uniknąć tego problemu możesz napisać tak: srednia2 = double(suma2) / double(licznik2);
0

@Maciek48:
Problemy są dwa:

  1. W drugiej pętli zaczyna iterację od rozmiaru tablicy, ale zapominasz, że w programowaniu zwykle indeksujemy od zera. To znaczy, że ostatni element tablicy jest na pozycji rozmiar - 1.
  2. Po drugie suma i licznik są typu int i przed przypisaniem do zmiennej double występuje niejawna konwersja na int, żeby uniknąć tego problemu możesz napisać tak: srednia2 = double(suma2) / double(licznik2);
    Edit:
    Jest jeszcze 3 poważny problem, Jeśli T[i] == 0 to pętla powinna się zatrzymać, wykorzystaj słowo kluczowe break.
0

zrobilem nastepujace zmiany zmienilem przy sredniej aby byl typ double tak jak napisales a rozmiar zmienilem i wyglada to nastepujaco

void funkcja4(int a, int T[])
{
    int suma1 = 0;
    int suma2 = 0;
    int licznik1=0;int licznik2=0;
    double srednia1, srednia2;
    for(int i = 0; i < a; i++)
    {
        if(T[i] != 0)
        {
            suma1 = suma1 + T[i];
            licznik1++;
            
        }
        /*if(T[i] == 0)
        {
            continue;
        }
        */
    }
    for(int i =( a-1); i > 0 ; i--)
    {
        if(T[i] != 0 )
        {
            suma2 = suma2 + T[i];
            licznik2++;
        }
    }
    srednia1 = (double)suma1/(double)licznik1;
    srednia2 = (double)suma2/(double)licznik2;
    cout << "Srednia przed zerem jest rowna: " << srednia1 << " ,a po zerze jest rowna " << srednia2 << endl;
};
0
Maciek48 napisał(a):

zrobilem nastepujace zmiany zmienilem przy sredniej aby byl typ double tak jak napisales a rozmiar zmienilem i wyglada to nastepujaco

void funkcja4(int a, int T[])
{
    int suma1 = 0;
    int suma2 = 0;
    int licznik1=0;int licznik2=0;
    double srednia1, srednia2;
    for(int i = 0; i < a; i++)
    {
        if(T[i] != 0)
        {
            suma1 = suma1 + T[i];
            licznik1++;
            
        }
        /*if(T[i] == 0)
        {
            continue;
        }
        */
    }
    for(int i =( a-1); i > 0 ; i--)
    {
        if(T[i] != 0 )
        {
            suma2 = suma2 + T[i];
            licznik2++;
        }
    }
    srednia1 = (double)suma1/(double)licznik1;
    srednia2 = (double)suma2/(double)licznik2;
    cout << "Srednia przed zerem jest rowna: " << srednia1 << " ,a po zerze jest rowna " << srednia2 << endl;
};
void funkcja4(int a, int T[])
{
    int suma1 = 0;
    int suma2 = 0;
    int licznik1=0;int licznik2=0;
    double srednia1, srednia2;
    for(int i = 0; i < a; i++)
    {
        if(T[i] != 0)
        {
            suma1 = suma1 + T[i];
            licznik1++;
            
        }
        if(T[i] == 0)
        {
            break;
        }
        
    }
    for(int i =( a-1); i > 0 ; i--)
    {
        if(T[i] != 0 )
        {
            suma2 = suma2 + T[i];
            licznik2++;
        }
        if(T[i] == 0)
        {
            break;
        }
    }
    srednia1 = (double)suma1/(double)licznik1;
    srednia2 = (double)suma2/(double)licznik2;
    cout << "Srednia przed zerem jest rowna: " << srednia1 << " ,a po zerze jest rowna " << srednia2 << endl;
};
0
void foo(int arr[], size_t n) {
    int sum1 = 0, sum2 = 0;
    int len1 = 0, len2 = 0;

    size_t i;
    for (i = 0; i < n && arr[i] != 0; i++) {
        sum1 += arr[i];
        len1++;
    }
    for (i = i + 1; i < n; i++) {
        sum2 += arr[i];
        len2++;
    }

   std::cout << (double)sum1/std::max(1, len1) << ", " 
             << (double)sum2/std::max(1, len2) << std::endl;
}
0

@Maciek48:
Jako ciekawostkę podam ci jeszcze moją wersję.

void foo(size_t n, int* tab)
{
	int sum{ 0 };
	size_t counter{ 0 };
	for (size_t i{ 0 }; i < n; ++i)
	{
		if (tab[i] == 0 )
		{
			std::cout << "Srednia przed zerem: " << double(sum) / double(i) << std::endl;
			sum = 0;
			counter = i + 1;
		}

		sum += tab[i];
	}
	std::cout << "Srednia po zerze: " << double(sum) / double(n - counter) << std::endl;
}
0
void foo(int arr[],size_t size)
{
    int sum[2]={0},len[2]={0};
    for(size_t p=0,i=0;i<size;p|=(!arr[i++])) sum[p]+=arr[i];
    for(size_t p=0;p<2;++p) cout<<(len[p]?(double)sum[p]/len[p]:0)<<endl;
}

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