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

C++ problem z tablicą

Object Storage Arubacloud
0 głosów
981 wizyt
pytanie zadane 18 kwietnia 2017 w C i C++ przez Norbert123 Początkujący (290 p.)

Witam, potrzebuję pomocy w zadaniu o następującej treści:

"Napisz program, który losuje 20 liczb naturalnych z przedziału od 0 do 100. Program ma za zadanie przypisać liczby podzielne przez 3 do tablicy o nazwie trójki, a niepodzielne przez 3 do tablicy o nazwie bylejakie."

#include <iostream>
#include<cstdlib>
#include<time.h>
using namespace std;


int main() 
{
	int tab[100];

int trojki[20];
int bylejakie[20];
srand(time(NULL));

	for(int i=0;i<100;i++)
	{
		tab[i]=0+rand()%(100+1) ;
			cout<<tab[i]<<" ";
	}
cout<<endl;
cout<<endl;

	for(int i=0;i<20;i++)
	{
		if(tab[i]%3==0)
		{
			trojki[i]=tab[i];
		
		}
		cout<<trojki[i]<<" ";
	}

cout<<endl;
cout<<endl;
	for(int i=0;i<20;i++)
	{	
			if(tab[i]%3!=0)
			{
				bylejakie[i]=tab[i]*1;		
			}
		cout<<bylejakie[i]<<" ";
	}
	return 0;
}

Tyle zrobiłem, jednak przy tablicach z liczbami podzielnymi i niepodzielnymi przez 3 wychodzą mi absurdalne liczby. Także proszę o pomoc :)

5 odpowiedzi

+1 głos
odpowiedź 18 kwietnia 2017 przez 10kw10 Pasjonat (22,880 p.)
Wedlug mnie, mozna to zrobic w jednej petli, gdy jest podzielna zapisujesz do tablicy w przeciwnym wypadku zapisujesz do innej tablicy.
komentarz 18 kwietnia 2017 przez Norbert123 Początkujący (290 p.)

Zrobiłem coś takiego (wersja robocza) :

int tab[20];
int trojki[6];
int bylejakie[14];

		int main() 
		{
		int x;

		srand(time(NULL));
	
		for(int i=0;i<20;i++)
			{
				tab[i]=0+rand()%(100+1) ;
				cout<<tab[i]<<" ";
			}

	cout<<endl;
	cout<<endl;

			if(tab[]%3==0)
				{
					trojki[]=tab[];  cout<<"Podzielne przez 3"<<endl;
				}else bylejakie[]=tab[]; cout<<"Niepodzielne przez 3"<<endl;	
	return 0;

Losuje 20 liczb z przedziału od 0 do 100 tylko że mam problem z drugą częścią zadania, nie wiem jak zrobić to twoim sposobem.

komentarz 18 kwietnia 2017 przez 10kw10 Pasjonat (22,880 p.)

Uzyj wektorów, tak chyba bedzie najlepiej ;)

http://en.cppreference.com/w/cpp/container/vector

+1 głos
odpowiedź 18 kwietnia 2017 przez Molester Bywalec (2,920 p.)

Nie wiem czy o coś takiego Ci chodziło? Nielegancko rozwiązałem to z 0, ale zrobiłem to na szybko. Zapewne jest lepszy sposób.

#include <iostream>
#include <cstdlib> 
const int ArSize=20;

int main(){
    
int trojki[ArSize];
int bylejakie[ArSize];

srand(time(NULL));

 
for (int i=0; i<ArSize; ++i){
  
    int random = rand()%(100+1);
    
    
    if (random%3==0){ 
    trojki[i] = random;
    std::cout << "Liczba  " << trojki[i] <<"  jest podzielna."  << std::endl;}
    
    else if (random%3!=0){
    bylejakie[i] = random;
    std::cout <<"Liczba  " << bylejakie[i] << "  jest niepodzielna." << std::endl;}

    else if (random ==0){ 
    bylejakie[i] ==random;
    std::cout << "Liczba  " << bylejakie[i] << "  jest niepodzielna." << std::endl;}
    
}


return 0;    
    
}

 

1
komentarz 18 kwietnia 2017 przez Kurogami12 Bywalec (2,610 p.)
int c=0;
cout<<endl<<endl<<bylejakie:"<<endl;

while(bylejakie[c]!=0)
{
    cout<<bylejakie[c]<<" ";
    c++;
}
c=(c-20)*-1;
            
cout<<endl<<endl<<"liczby podzielne przez 3:"<<endl;
    
for(int i=0;i<c;i++)
        cout<<trojki[i]<<" ";

z kodem który Ci podałem powinno zadziałać bez problemu 

komentarz 18 kwietnia 2017 przez Norbert123 Początkujący (290 p.)

Dzięki wielkie, o to mi chodziło :)

Tylko jakby co zgubiłes cudzysłów:

cout<<endl<<endl<<bylejakie:"<<endl;

 

komentarz 18 kwietnia 2017 przez Molester Bywalec (2,920 p.)
Ale zmienne globalne nie są żadnym wymiernym wyjsciem z tego problemu, potem taka osoba będzie z nich cały czas korzystać nie zdając sobie sprawy że postępuje zle. Ale z czym ja chce dyskutować , w końcu działa i to wystarcza  ...
komentarz 18 kwietnia 2017 przez Norbert123 Początkujący (290 p.)
Chciałbym się odnieść, ale szczeże to nie wiem, o co chodzi z tymi zmiennymi globalnymi. To zadanie jest mi potrzebne do sprawdzianu i dlatego nie wymagam w tym przypadku takiej poprawności, tak jak powiedziałeś: "W końcu działa i to wystarcza" :) Jednak jeśli byś zechciał zrobić to zadanie tak, jak się to powinno zrobić, to nie miałbym nic przeciwko :) Na pewno się taka wiedza przyda na przyszłość.
komentarz 18 kwietnia 2017 przez Kurogami12 Bywalec (2,610 p.)
zmienne globalne to szczegół - w taki sposób można się pozbyć śmieci w programach które mają i tak 1 funkcje, więc to szczególnej różnicy w takich wypadkach nie robi. Jak napisałeś pod moim postem na dole są też inne sposoby na wyzerowanie tablicy, lepsze, ale po prostu akurat teraz o tym nie pomyślałem z prostego powodu - ostatnio tablice które deklarowałem były globalne, w prostych programach to się sprawdza, a w moim wypadku to jak z nich korzystałem to musiały być globalne
+1 głos
odpowiedź 19 kwietnia 2017 przez mokrowski Mędrzec (155,700 p.)
edycja 19 kwietnia 2017 przez mokrowski

Wersja trochę nowocześniejsza czyli c++14.

#include <iostream>
#include <random>
#include <string>
#include <algorithm>
#include <iterator>
#include <functional>
#include <vector>

template<typename RandomAccessContainer>
void showContainer(const RandomAccessContainer& values, const std::string& msg)
{
    using value_t = typename RandomAccessContainer::value_type;

    std::cout << msg << " [ ";
    std::copy(values.cbegin(), std::prev(values.cend()),
            std::ostream_iterator<value_t>(std::cout, ", "));
    std::cout << *values.crbegin() << " ]\n";
}

template<typename T>
auto makeRandomGenerator(T from, T to)
{
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<T> distribution(from, to);

    return std::bind(distribution, generator);
}

template<typename Generator, typename Container = std::vector<int>>
auto makeFilledContainer(size_t length, Generator generator)
{
    Container container(length);

    std::generate(container.begin(), container.end(), generator);

    return container;
}

template<typename Predicate, typename Container = std::vector<int>>
auto segregateContainer(const Container& container, Predicate predicate)
{
    Container yesContainer;
    Container noContainer;

    std::for_each(container.cbegin(), container.cend(),
        [&](auto value) {
            predicate(value) ?
                yesContainer.push_back(value) : noContainer.push_back(value);
    });

    return std::make_tuple(yesContainer, noContainer);
}

int main()
{
    auto randomGenerator = makeRandomGenerator(0, 100);
    auto vec = makeFilledContainer(20, randomGenerator);
    decltype(vec) triples;
    decltype(vec) others;

    std::tie(triples, others) =  segregateContainer(vec,
            [](auto v) { return ! (v % 3); });
    showContainer(vec,     "Zawartość kontenera to:     ");
    showContainer(triples, "Liczby podzielne przez 3 to:");
    showContainer(others,  "Liczby inne to:             ");
}

Mały błąd w predykacie poprawiony.

1
komentarz 19 kwietnia 2017 przez mokrowski Mędrzec (155,700 p.)
edycja 19 kwietnia 2017 przez mokrowski

E tam. jest napisane!

Jak masz np. taką lambdę:

[](int z) -> bool {
    return z > 10;
}

.. to przyjmuje ona argument typu int i nazwie z oraz zwraca wartość typu bool jeśli z jest większe niż 10. W C++14 dodano auto(mat) polegający na tym że jeżeli kontekst jest jasny, funkcja sama określa typ.

Np:

#include <algorithm>

std::vector<int> vec;
// Jakieś tam wypełnienie wektora
// ...
auto howMany = std::count_if(vec.begin(), vec.end(), 
    [](auto z) {
        return z > 10; 
});

(Specjalnie inaczej sformatowałem kod). Wiadomo że w vec dane są typu int. Wiadomo także ze "przejście po vec" będzie zasilało lambdę typem int (o nazwie z). Za każdym razem jak lambda zwróci true, będzie inkrementowany licznik który po przejściu po całości kontenera zostanie przypisany do howMany. A jakiego typu będzie howMany? Ano takiego jak .. zwróci count_if(....) :-) (jak zerkniesz do dokumentacji to będzie to typ różnicy pomiędzy iteratorami dla danego kontenera) http://en.cppreference.com/w/cpp/algorithm/count

A co do kodu który napisałeś, nie będzie działać bo pominąłeś szablon. Jak zrobisz funkcję np.

template<typename Function>
void runner(Function f) {
    f();
}

To wykonanie przez:


void myFun() {
    std::cout << "Lalala\n";
}

// .... 

    runner(myFun);
    runner([]() { std::cout << "Ala ma kota\n";});

Zadziała i dla myFun i dla lambdy bo szablon runner sam dopasuje typ. 

To co ty napisałeś w Foo, wymaga niestety podania jawnego typu funkcji a będzie nim funkcja przyjmująca const int& a zwracająca bool.

komentarz 20 kwietnia 2017 przez 10kw10 Pasjonat (22,880 p.)
std::for_each(container.cbegin(), container.cend(),
        [&](auto value) {
            predicate(value) ? // <-- wywolanie funkcji lambda 
                yesContainer.push_back(value) : noContainer.push_back(value);
    });

Dobrze mysle ?

Nie prosciej jest to zrobic na ifie:

if(value%3)container.push_back(value);
else ...

 

komentarz 20 kwietnia 2017 przez mokrowski Mędrzec (155,700 p.)
Wywołanie funkcji jambda jest już tu: [&](auto value)

Nie będzie najprościej "zrobić na ifie" bo w tym miejscu for_each(...) wymaga funkcji a funkcja ta ma po stwierdzeniu że predykat daje prawdę, "wepchnąć" dane do jednej lub drugiej tablicy :-) Możesz oczywiście rozciągnąć operator ?:; na if'a z else jeśli jest to dla Ciebie wygodniejsze :-).

Ogólnie w algorytmach z biblioteki standardowej jest taki wzorzec stosowania:

algorytm(początek, koniec, jakaś_decyzja_funkcją_lub_lambdą);
komentarz 20 kwietnia 2017 przez 10kw10 Pasjonat (22,880 p.)

Bardziej chodziło mi o takie cos

for(auto value:container) 
{
if(value%3)noContainer.push_back(value);
else yesContainer.push_back(value);
}

A nie wazne :) 

komentarz 20 kwietnia 2017 przez mokrowski Mędrzec (155,700 p.)

Ważne.. Ale jeśli szukasz czegoś równoważnego to:

for(const auto value: container) 
{
    if(value%3) noContainer.push_back(value);
    else yesContainer.push_back(value);
}

Tam powinno być const. Już referencji nie było sensu stosować bo w kontenerze jest POD a nie "ciężka klasa".

A czy prościej? Zależy kto do czego się przyzwyczai. Ja chciałem pokazać "dla każdego" stąd for_each(...) :-)

0 głosów
odpowiedź 18 kwietnia 2017 przez Kurogami12 Bywalec (2,610 p.)
po pierwsze umieść deklaracje tablic poza funkcją main, jednak wątpie żeby efekt był porządany, twój program losuje Ci 100 liczb i sprawdza pierwsze 20 czy są podzielne przez 3 czy nie, poza tym tablica o nazwie tab jest zbędna, narazie umieść deklaracje tablic poza funkcją main a później spróbuj ten kod jakoś napisać tak, żeby był napisany dużo prościej, bo można tak zrobić, poeksperymentuj :)
komentarz 18 kwietnia 2017 przez draghan VIP (106,230 p.)

po pierwsze umieść deklaracje tablic poza funkcją main

Globalne zmienne nie są rozwiązaniem żadnego problemu. no

komentarz 18 kwietnia 2017 przez Kurogami12 Bywalec (2,610 p.)
jak zmienne są zadeklarowane globalnie to nie występują śmieci z kompilatora - będzie 0 zamiast randomowych liczb, a on chciał żeby mu się nie wyświetlały takie liczby z dupy - a on chciał zrobić coś z tymi liczbami
komentarz 18 kwietnia 2017 przez draghan VIP (106,230 p.)
Mamy XXI wiek, istnieją sposoby na inicjalizację lokalnych zmiennych. ;)
1
komentarz 18 kwietnia 2017 przez Molester Bywalec (2,920 p.)
@Kurogami12

Jak chcesz to napisz sobie  

float tablica [100] {};
(C++ 11)
wszystkie zadeklaruje Ci na zero, jednocześnie pozostając w pamięci automatycznej a nie w pamięci globalnej.
0 głosów
odpowiedź 23 kwietnia 2017 przez sko Użytkownik (500 p.)
Dziwne wartości brały się stąd, że: 
1) tablice trójka i bylejakie zawierały śmieci dlatego dobrze jest je wyzerować
2) nawet gdy warunek if w pętli nie był spełniony to i tak inkrementowała Ci się wartość "i" w trojki[i], bylejakie[i] i stąd te śmieci 

int main(int argc, char *argv[])
{
    int tab[100];

    int trojki[20] = {0};
    int bylejakie[20] = {0};
    srand(time(NULL));

    for(int i=0; i<100; i++)
    {
        tab[i]=0+rand()%(100+1) ;
        cout<<tab[i]<<" ";
    }
    cout<<endl<<endl;
    for(int i=0, j=0; i<100, j<20; i++)
    {
        if(!(tab[i]%3))
        {
            trojki[j]=tab[i];
            cout<<trojki[j]<<" ";
            j++;
        }

    }
    cout<<endl<<endl;
    for(int i=0, j=0; i<100, j<20; i++)
    {
        if(tab[i]%3)
        {
            bylejakie[j]=tab[i]*1;
            cout<<bylejakie[j]<<" ";
            j++;
        }

    }

    return 0;

 

Podobne pytania

+1 głos
1 odpowiedź 173 wizyt
pytanie zadane 8 stycznia 2016 w C i C++ przez thekibi27 Bywalec (2,110 p.)
0 głosów
2 odpowiedzi 181 wizyt
pytanie zadane 23 stycznia 2023 w C i C++ przez Dani Obywatel (1,450 p.)
+1 głos
2 odpowiedzi 156 wizyt
pytanie zadane 18 czerwca 2016 w C i C++ przez abes Nowicjusz (130 p.)

92,627 zapytań

141,490 odpowiedzi

319,856 komentarzy

62,009 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!

...