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

[C++ ] Wskaźnik wskazuje źle, jednocześnie dobrze.

Object Storage Arubacloud
0 głosów
133 wizyt
pytanie zadane 22 stycznia 2019 w C i C++ przez Hiskiel Pasjonat (22,830 p.)
#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <cctype>
#include <cstdlib>

float mean_avg(std::uint32_t*, std::uint32_t*, std::size_t size);
std::size_t count_numbers(std::string &in){
    return std::count(in.begin(), in.end(), ' ');
}
std::uint32_t* split(std::string&, char);

int main(){
    std::string numbers="";
    std::string input="";
    std::size_t counter=20;
    std::cout<<"Wprowadz liczby oddzielajac oddzielajac je enterem, lub konczac enterem.\n";
    do{
        std::getline(std::cin, input, '\n');
        if(input.empty()) break;
        if(std::count_if(input.begin(), input.end(), ::isdigit) != input.length()){
            std::cerr<<"Nieprawidlowe wejscie. Mozesz wprowadzac tylko liczby.\n";
            continue;
        }
        numbers+=input+=" ";
        --counter;
    }while(counter);

    std::uint32_t* array = split(numbers, ' ');
    if(array==nullptr){
        std::cerr<<"Nie mozna utworzyc tablicy\n";
        return 57665;
    }
    std::size_t tab_size = count_numbers(numbers);

    std::uint32_t max = array[0];
    std::uint32_t min = array[0];

    for(std::size_t i=0;i<tab_size;++i){
        if(array[i]>max) max = array[i];
        if(array[i]<min) min = array[i];
    }

    std::uint32_t *min_pos = std::find(array, array+tab_size, min);
    std::uint32_t *max_pos = std::find(array, array+tab_size, max);

    std::cout<<mean_avg(min_pos, max_pos, labs(max_pos-min_pos));


    delete[] array;
}

std::uint32_t* split(std::string &in, char delimiter){
    if(in.empty()) return nullptr;

    std::uint32_t *tab = new std::uint32_t[count_numbers(in)];

    std::istringstream string_in(in);
    std::size_t index = 0;
    for(std::string token; std::getline(string_in, token, delimiter);){
        std::uint32_t num;
        try{
            num = std::stoi(token);
        }catch(std::out_of_range&){
            return nullptr;
        }
        tab[index] = num;
        ++index;
    }

    return tab;
}
float mean_avg(std::uint32_t *beg, std::uint32_t *end, std::size_t size){
    if(beg==nullptr||end==nullptr) return 0;
    if(beg==end) return *beg;

    float retval = 0;
    while(beg!=end){
        retval += (*beg);
        beg++;
    }
    std::cout<<"--------------------------------\n";
    std::cout<<retval<<"   "<<size<<'\n';
    std::cout<<retval/size<<'\n';
    std::cout<<"--------------------------------\n";


    return retval/size;
}

Nie piszę tego dla siebie. Zadanie brzmi: "

Napisz program, który oblicza średnią arytmetyczną elementów leżących pomiędzy
elementem minimalnym i maksymalnym w tablicy liczb całkowitych. Przyjmij, że
maksymalny rozmiar tablicy to 20. Zadanie należy rozwiązać w oparciu o wskaźniki.
Przykład 1: dla tablicy: 2 5 6 2 3 2 2 0 1 0
min = 0, jego indeks = 7
max = 6, jego indeks = 2
średnia arytmetyczna elementów: 6 2 3 2 2 0 jest równa 15/6 = 2.5."

 

I niby wszystko jest dobrze, max_pos i min_pos wskazują dobrze, etc., ale nie liczy mi 10, ostatniego elementu tablicy, chyba, że dodam jeden, ale nie rozumiem co to dodawanie jedynki mi daje (tzn. rozumiem, że dodaję +4 do adresu, ale nie wiem czemu muszę to zrobić).

Gdyby ktoś byłby w stanie mi pomóc byłby bardzo wdzięczny..

Z góry dziękuję i pozdrawiam.

1 odpowiedź

+1 głos
odpowiedź 22 stycznia 2019 przez criss Mędrzec (172,590 p.)
wybrane 22 stycznia 2019 przez Hiskiel
 
Najlepsza

ale nie liczy mi 10, ostatniego elementu tablicy

Rozumiem, że zamiast  "2 5 6 2 3 2 2 0 1 0" miało być "2 5 6 2 3 2 2 0 10" ?

Nie wiem o jakie +1 ci chodzi. Wstawiłeś 100 linii kodu i oczekujesz, że będę wiedział gdzie wstawiasz +1. Anyway miało przecież liczyć średnią elementów pomiędzy, a 10 ewidentnie nie jest pomiędzy, więc dlaczego miałoby ci liczyć. I tutaj też musisz doprecyzować co to znaczy "nie liczy mi 10" bo nie wiem czy chodzi o wyliczanie średniej czy o coś innego z tych stu linii. Swoją drogą móglbyś to zamknąć w kilku liniach gdybyś nie przyjmował inputu do stringa.

komentarz 22 stycznia 2019 przez Hiskiel Pasjonat (22,830 p.)

Mądry ja..

Racja.. Nie muszę tego wczytywać do stringa.. Przepiszę to jutro blush. Dzięki za uwagę..

Swoją drogą - racja, podałem za mało informacji..

Dla inputu {1,2,3,4,5,6,7,8,9,10}

Wylicza średnią bez ostatniego elementu tablicy.

Ale gdy przesyłając do mean_avg zwiększę max_pos o 1, to liczy się dobrze.

W każdym bądź razie, myślę, że problem uda mi się rozwiązać, kiedy przepiszę to normalnie.. Naprawdę, nie wiem co miałem na myśli wczytując to do stringa.

1
komentarz 22 stycznia 2019 przez criss Mędrzec (172,590 p.)

Pomijając obsługe inputu możesz to zmieścić w jakichś dwóch liniach za pomocą std::min_max_element oraz std::accumulate. A sam input też nie powinien zająć więcej niż jedna-dwie linie. Anyway..

    while(beg!=end){
        retval += (*beg);
        beg++;
    }

Więc dodawanie skończy się na  max_pos-1.

komentarz 22 stycznia 2019 przez Hiskiel Pasjonat (22,830 p.)
Oglądając te funkcje doszedłem do wniosku, że owszem, mogę to zrobić w paru liniach.. Heh.. Ale mam kolejne pytanie.

Jest wiele podstawowych algorytmów, które są zawarte w bibliotece standardowej. Jak ich szukać? Tzn. Czy np. Ty już na podstawie doświadczenia pamiętasz, że nie trzeba czegoś pisać, bo jest gotowiec, czy masz np. Listę headerów, w których są jakieś gotowe funkcje i przeglądasz, czy nie ma tego czego szukasz? A może jeszcze inaczej? Jak?
komentarz 22 stycznia 2019 przez Hiskiel Pasjonat (22,830 p.)
No właśnie - nie mogę dać kodu z minmax i i accumulate, ponieważ wszystko ma leżeć na wskaźnikach.
komentarz 22 stycznia 2019 przez criss Mędrzec (172,590 p.)

Generalnie funkcje są pogrupowane tematycznie w standardowych headerach. Troche pamiętam, ale zawsze warto spojrzeć. Najbardziej przydatne rzeczy "codziennego użytku" znajdziesz w <algorithm>, <numeric> oraz <utility>.

No właśnie - nie mogę dać kodu z minmax i i accumulate, ponieważ wszystko ma leżeć na wskaźnikach.

No jak to jest zadanie na jakieś zajęcia to może faktycznie lepiej nie :D Ale sam możesz sobie napisać takie funkcje, w zasadzie już je masz tylko nie jako osobne funkcje. Najwięcej ci psuje ten input jako string. 

komentarz 22 stycznia 2019 przez Hiskiel Pasjonat (22,830 p.)

No właśnie, już sobie przypomniałem czemu użyłem stringa.. Czy da się pobrać input tak, żeby:

-tablica miała rozmiar odpowiadający ilości danych
-tablica została utworzona przed lub po wczytaniu danych bez podawania ich ilości od użytkownika

? Chodzi o to, żeby user nie musiał podawać ilości danych, tylko mógł je od razu wpisywać.

komentarz 23 stycznia 2019 przez criss Mędrzec (172,590 p.)
Z std::vector nie możesz korzystać? W takim wypadku nie widze żadnego prostego rozwiązania. Nie wiem po co wtedy autor zadania podaje maksymalną wielkość inputu... Przy tak małej liczbie najoptymalniej byłoby właśnie zrobić sobie tablice 20 elementową i z głowy. Jeśli nie to, to albo zostań przy tym nieszczęsnym stringu, albo baw się w realokacje tablicy (żeby zwiększyć rozmiar podobnie jak to robi std::vector) podczas przyjmowania inputu. To drugie pewnie lepiej, ale na twoim miejscu już by mi się nie chciało :P

edit:
Albo... XD skoro możesz korzystać ze stringa, to możesz się wycwanić, że będziesz używał stringa jak coś w stylu vectora. Spróbuj czy kompilator pozwoli ci stworzyć std::basic_string<int> - wtedy masz już vector :D Jeśli nie, to tworzysz zwyklego stringa i na każdego nowego inta robisz sobie string.resize(string.size()+4) a potem memcpy w to miejsce wczytanego inta. Tylko to już dziwna sztuczka i bardziej na zasadzie plucia w twarz prowadzącemu niż jakiegoś sensu :D
komentarz 23 stycznia 2019 przez Hiskiel Pasjonat (22,830 p.)
Sorry, że zawracam głowę po północy, ale albo to normalne, że nie myślę, albo jestem jakimś idiotom - pomógłbyś z tym inputem? Za kija nie wiem jak cin'em wpisać te liczby do tablicy, tak, żeby byłby po spacji. Jeśli wczytywanie miałoby się odbywać klikając enter, to nie wiem jak je zatrzymać, jeśli chce się podać mniej niż 20..

Podobne pytania

0 głosów
1 odpowiedź 274 wizyt
pytanie zadane 21 stycznia 2016 w C i C++ przez Dominik Kulis Użytkownik (720 p.)
0 głosów
2 odpowiedzi 375 wizyt
0 głosów
0 odpowiedzi 97 wizyt
pytanie zadane 31 października 2021 w Sprzęt komputerowy przez CURV15H0N Nowicjusz (120 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...