nadpisywanie wartości w tablicy, problem z zadaniem

0

Cześć, nie mogę sobie poradzić z zadaniem. Mam napisać program ,który liczy ilość poszczególnych cyfr w wpisanej liczbie. Np. wpisuję 12345 , program pokazuje 0:0 , 1:1 , 2:1 , 3:1 , 4:1 , 5:1 , 6:0 , 7:0 , 8:0 , 9:0
Problem w tym ,że mój program działa tylko do dziesięciocyfrowej liczby.

#include<iostream>
using namespace std;
int main()
{
int a,i,suma[11]={};
cin>>i;
    while(i>0)
    {
        a=i%10;
        if(a==0)
            suma[0]=suma[0]+1;
        if(a==1)
            suma[1]=suma[1]+1;
        if(a==2)
            suma[2]=suma[2]+1;
        if(a==3)
            suma[3]=suma[3]+1;
        if(a==4)
            suma[4]=suma[4]+1;
        if(a==5)
            suma[5]=suma[5]+1;
        if(a==6)
            suma[6]=suma[6]+1;
        if(a==7)
            suma[7]=suma[7]+1;
        if(a==8)
            suma[8]=suma[8]+1;
        if(a==9)
            suma[9]=suma[9]+1;
        i=i/10;
    }
cout<<"0: "<<suma[0]<<endl;
cout<<"1: "<<suma[1]<<endl;
cout<<"2: "<<suma[2]<<endl;
cout<<"3: "<<suma[3]<<endl;
cout<<"4: "<<suma[4]<<endl;
cout<<"5: "<<suma[5]<<endl;
cout<<"6: "<<suma[6]<<endl;
cout<<"7: "<<suma[7]<<endl;
cout<<"8: "<<suma[8]<<endl;
cout<<"9: "<<suma[9]<<endl;
}
2

Zmienna a zawierająca dane wejściowe jest typu int, więc nie jest przystosowana do przechowywania bardzo dużych liczb. Spróbuj zamiast tego zinterpretować dane z cin jako ciąg znaków. Dzięki temu będziesz mógł przeiterować po wszystkich cyfrach bez potrzeby dzielenia czy liczenia modulo, a dodatkowo umożliwi to podanie dowolnej ilości cyfr.

Dodatkowo, można spróbować uprościć tę drabinkę ifów. Zauważ, że jeśli cyfra jest zerem, to odnosisz się do zerowego indeksu tablicy, jedynką to do pierwszego, itd. Zamiast pisać 10 razy taki if

if(a==cyfra)
    suma[cyfra]=suma[cyfra]+1;

można napisać po prostu raz

suma[a]=suma[a]+1;

Oczywiście jeśli potraktujesz liczbę wejściową jako ciąg znaków, to nie będziesz mógł bezpośrednio użyć znaku cyfry jako indeksu tablicy bez dodatkowych kalkulacji, ale to też da się łatwo rozwiązać ;)

2

Topornie, z zamianą liczby na string:

void freq(int n) {
	auto str = std::to_string(n);
	char  digits[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
	for (auto v: digits) {
		int freq = 0;
		for (size_t i = 0; i < str.length(); ++i) {
			if (v == str[i])
				++freq;
		}
		cout << v <<": " << freq << "\n";
	}
}
2

To samo ale po ludzku:

#include <iostream>
using namespace std;

int main()
{
	int v,count[10]={};
	for(cin>>v;v>0;v/=10) ++count[v%10];
	for(int i=0;i<10;++i) cout<<i<<": "<<count[i]<<endl;
	return 0;
}
0

v/=10 co to znaczy?
++count[v%10] to to samo co count[v%10]=count[v%10]+1 ?

1

a/=b a*=b a+=b a-=b a%=b a&=b a|=b a^=b a<<=b a>>=b
to samo co a=a(odpowiedni operator )b
++x to samo co x=x+1 oraz x+=1

0

Ale twój program Dragon też działa tylko dla liczb składających się z max. 10 cyfr

2
#include <iostream>
using namespace std;

int main()
{
	size_t count[10]={};
	char ch;
	for(cin>>ch;('0'<=ch)&&(ch<='9');) ++count[ch-'0'];
	for(int i=0;i<10;++i) cout<<i<<": "<<count[i]<<endl;
	return 0;
}
1

algorytm na zliczanie poszczególnych cyfr w danej liczbie jest banalny ;) wystarczy tu znajomość podstaw matematyki. Na razie ci podpowiem, czy wiesz czym są jedności, dziesiątki, setki, tysiące etc... ? Jak to zrozumiesz, to napiszesz pętlę ;) mam taki algorytm podzielę się nim jeśli zechcesz. Czy wolisz sam zrobić ?

1

Twój problem należy do problemów "szczególnych"

więc tak, założenia
chcesz wpisać liczbę która składa się np ze 100 cyfr i chcesz je zliczyć

ograniczenia
podczas wpisywania cyfr z klawiatury komputer ma ograniczoną pojemność i rozwiązanie trzeba przedstawić w dość nietypowy sposób:

następujące typy takie mają ograniczenia

  1. short -> (-32 768) - (-32 767)
  2. unsigned short -> (0) - (4 294 967 295)
  3. int -> (-2 147 483 648) - (2 147 483 647)
  4. unsigned long long -> (0) - (18 446 744 073 709 551 615)

Oznacza to tyle, że w najlepszym przypadku jeżeli użyjesz typu unsigned long long to możesz za jednym razem pobrać 20 znaków i nie da rady więcej, ponieważ nie ma takiego typu liczbowego który pobierze więcej. Więc jak używałeś typu int mogłeś zliczyć max 10 znaków i to cała przyczyna czemu więcej nie możesz.

Rozwiązanie jest i na to. Tutaj przychodzi z pomocą łańcuch znaków np char * lub string wybrałem ten drugi bo jest łatwiejszy w implementacji.

Napisałem algorytm który pobierze dowolną ilość znaków i zwróci ile ich jest. Jest on prosty. Dodałem tam też pętlę która zamienia znaki ASCII na liczbę - możesz na nich wykonywać działania. Niestety są one oddzielnymi cyframi. Gdybyś chciał z nich zrobić liczbę np 8 cyfrową, to da radę to zrobić ale maksymalnie będzie to liczba 20 cyfrowa i więcej nie będzie.

Oto rozwiązanie twojego problemu

#include <iostream>
#include <string>

int main(void)
{
    std::string StrLiczba;

    std::cin >> StrLiczba;

    unsigned int rozmiar, zPom;

    rozmiar = static_cast<unsigned int>(StrLiczba.size());

    unsigned int *ILiczba = new unsigned int [rozmiar];

    for(unsigned int i=0, j=0; i<rozmiar; i++, j++){
        zPom = static_cast<unsigned int>(StrLiczba[i]);

        if(zPom == 48) ILiczba[j] = 0; //![0]
        if(zPom == 49) ILiczba[j] = 1; //![1]
        if(zPom == 50) ILiczba[j] = 2; //![2]
        if(zPom == 51) ILiczba[j] = 3; //![3]
        if(zPom == 52) ILiczba[j] = 4; //![4]
        if(zPom == 53) ILiczba[j] = 5; //![5]
        if(zPom == 54) ILiczba[j] = 6; //![6]
        if(zPom == 55) ILiczba[j] = 7; //![7]
        if(zPom == 56) ILiczba[j] = 8; //![8]
        if(zPom == 57) ILiczba[j] = 9; //![9]
    }

    std::cout << "liczba " << StrLiczba << " sklada sie z " << StrLiczba.size() << " cyfr";

    std::cout << std::endl;

    delete [] ILiczba;

    return 0;
}

jeżeli już tak bardzo ci zależy na typowo liczbowym rozwiązaniu to niestety ale ograniczenie jest tylko do 20 liczb

#include <iostream>

int main(void)
{
    unsigned long long rozm=0, liczba;

    std::cin >> liczba;

    for(unsigned long long i=liczba, j=1; i>0; i=(i/10), j++)
    {
        rozm=j;
    }

    std::cout << "liczba " << liczba << " sklada sie z " << rozm << " liczb" << std::endl;

    return 0;
}

0

wielkie dzięki za wyjaśnienie

1
zkubinski napisał(a):

Oznacza to tyle, że w najlepszym przypadku jeżeli użyjesz typu unsigned long long to możesz za jednym razem pobrać 20 znaków i nie da rady więcej, ponieważ nie ma takiego typu liczbowego który pobierze więcej. Więc jak używałeś typu int mogłeś zliczyć max 10 znaków i to cała przyczyna czemu więcej nie możesz.

Doprawdy? Dwa posty wyżej, nawet milion cyfr:
https://4programmers.net/Forum/C_i_C++/332120-nadpisywanie_wartosci_w_tablicy_problem_z_zadaniem?p=1628488#id1628488
Jak w kawale: - Czukcza nie chce być czytelnikiem, czukcza chce być pisarzem!

zkubinski napisał(a):
    unsigned int rozmiar, zPom;

O size_t pewnie nie słyszałeś?

zkubinski napisał(a):
    rozmiar = static_cast<unsigned int>(StrLiczba.size());

Po kiego to kastowanie?

zkubinski napisał(a):
    unsigned int *ILiczba = new unsigned int [rozmiar];

Wcale się nie zdziwię że o vector nie słyszałęś. Ba gdzie delete?

zkubinski napisał(a):
    for(unsigned int i=0, j=0; i<rozmiar; i++, j++)

size_t? Dwa synchroniczne iteratory? Na dodatek: http://forum.4programmers.net/1101404 A smrodek pozostaje.

zkubinski napisał(a):
    zPom = static_cast<unsigned int>(StrLiczba[i]);

Znowu bezsensowne kastowanie? Masz z tym jakiś problem?

zkubinski napisał(a):
        if(zPom == 48) ILiczba[j] = 0; //![0]
        if(zPom == 49) ILiczba[j] = 1; //![1]
        if(zPom == 50) ILiczba[j] = 2; //![2]
        if(zPom == 51) ILiczba[j] = 3; //![3]
        if(zPom == 52) ILiczba[j] = 4; //![4]
        if(zPom == 53) ILiczba[j] = 5; //![5]
        if(zPom == 54) ILiczba[j] = 6; //![6]
        if(zPom == 55) ILiczba[j] = 7; //![7]
        if(zPom == 56) ILiczba[j] = 8; //![8]
        if(zPom == 57) ILiczba[j] = 9; //![9]

Kaskada if'ów, nawet bez else? Zamiast ILiczba[j]=zPom-'0';?

Jestem w totalnym szoku, przy tak słabej wiedzy udzielać się na forum?

1

Jak w kawale: - Czukcza nie chce być czytelnikiem, czukcza chce być pisarzem!

widzę, że ktoś czegoś mi pozazdrościł i ten osobnik czuje się zagrożony :D tacy jak ty przez czucie się zagrożonym psują wszystkim atmosferę

Ta wiedza jest ogólnie dostępna, więc jeżeli napisałem coś źle to proszę o merytoryczne uzasadnienie, a nie jakieś podwórkowe drwiny.

Po kiego to kastowanie?

Nie znam takiego słowa, ja używam języka polskiego, a nie jakiegoś nieokreślonego slangu - jak już to powinieneś użyć słowa rzutowanie !!!

Wcale się nie zdziwię że o vector nie słyszałęś. Ba gdzie delete?

Chyba wzrok masz nie taki delete jest na samym dole - chyba się zagalopowałeś w zaślepiony nienawiścią by mi dopiec

A teraz, jeżeli jesteś taki piękny, mądry i wspaniały to czemu proponujesz rozwiązania które samo w sobie jest protezą ? Mówisz, że jesteś takim wspaniałym programistą ? to czemu:

  1. Twój kod liczy TYLKO 10 liczb ? - sugerujesz że użytkownik będzie dysponował twoim marnym kodem źródłowym i będzie sobie w kod wpisywał wielkość tablicy ? To poważne rozwiązanie ?
  2. Sugerujesz wczytywanie znak po znaku - to w co będzie zapisywał te znaki ? Proponujesz jakiś bufor ? :D no dobra, zapisze te dane do bufora ale teraz jak z tych znaków zrobić np 40 cyfrową liczbę ? Mam nadzieję, że chociaż znasz podstawy matematyki by taką dużą liczbę zrobić :) (dla uściślenia, ja wiem jak to zrobić)
  3. zadanie jest proste, masz wczytać dowolnie długą liczbę i obliczyć z ilu składa się cyfr - tak, wiem, nie wpadłeś na to, że można wykorzystać do tego klasę string ale osobną kwestią jest już to co zrobić z liczbami i to już dalej zależy od założeń

sugerujesz mi używanie size_t zamiast unsigned int - pytanie do pana znawcy - jaka jest różnica między jednym, a drugim ?

Kaskada if'ów, nawet bez else?

tak po prawdzie
różnica między if, a else lub else if w przypadku utworzenia kilku warunków - tak naprawdę nie ma żadnej różnicy, ba nawet powiem więcej, nie ma to wpływu na szybkość lub na cokolwiek innego

myślę, że to ty masz słabą wiedzę, jesteś zwykłym klepaczem kodu który działa bez pomysłu. Udowodniłeś mi to przy moim poście Qt i SQL - Nie dodaje wierszy

jesteś tak prosty, że oczekujesz, iż komputer wskaże ci błąd gdzie on jest podczas gdy go wcale nie ma ? Skoro jesteś tak dobry za jakiego się uważasz, to dlaczego nie zaproponowałeś ŻADNEGO rozwiązania ? Nawet nie podjąłeś się prób analizy, tylko oczekiwałeś, że kompilator posypie błędami...

po drugie proponujesz protezy zamiast rozwiązań

Jestem w totalnym szoku, przy tak słabej wiedzy udzielać się na forum?

I na sam koniec. Na zagranicznych forach nikt się nie wywyższa, tylko ludzie dzielą się wiedzą i podają przykłady. Kształcą się wzajemnie i podnoszą swoją wiedzę zupełnie bezinteresownie. W polsce panuje przekonanie o swojej wyjątkowości i ty tą regułę potwierdzasz, uważasz, że wiesz ale nie powiesz o ile zakładając, że posiadasz użyteczną wiedzę ale póki co, to nie błysnąłeś niczym nadzwyczajnym, tylko twój kod jest dowodem na to, że po prostu kombinujesz, zamiast myśleć. Naprawdę nie chciałbym używać twoich programów, bo już miałem okazję używać oprogramowania programistów takich jak ty i było ono nieużywalne, bez przemyślenia, ładu i składu i co ciekawsze, miało powłączane wszystkie biblioteki jakie się dało byle działało. I ty robisz programy na zamówienie ? Ja nawet nie chciałbym ich za darmo.

1

@zkubinski: unsigned int może nie pomieścić rozmiaru tablicy, size_t może przechować dowolny adres, więc w szczególności może trzymać rozmiar tablicy. Różnica między if, a else if tutaj jest ściśle programistyczna. Jeśli jednak jakoś źle te warunki napiszesz, przez literówkę, to możesz w ten sposób się uchronić od długiej sesji debugującej.

W pozostałych kwestiach, jeśli byś uruchomił kod @_13th_Dragon, byś zobaczył, że nie masz racji, i kod obsługuje poprawnie liczby dowolnej długości.

1

no dobra, zjawiam się, skopiowałem ten jego "genialny" algorytm, przekleiłem do kompilatora i co się stało ? Skompilował mi się ale uwaga

NIE DZIAŁA !!!

Może mam zły komputer ? Albo źle wkleiłem - pewnie krzywo ? Skoro twierdzicie, że ten algorytm działa, to czemu u mnie nie działa ?

a tu poniżej zrzut z tego czegoś. Wpisywałem znaki i wcisnąłem klawisz enter i niestety żadnej reakcji ze strony komputera tylko uparcie wczytuje znaki...

Więc nie wiem jak wam to działa ? Co wy tam macie ?

I autor tego algorytmu niech ze mnie nie drwi, jak w poście powyżej, tylko jak poważny człowiek niech się teraz z niego rozliczy. W przeciwnym razie uznaję go za laika w temacie. Bo po prostu algorytm u mnie nie działa i tego nie mam zamiaru poprawiać. Niech autor udostępni działający algorytm, a nie protezę

0

Weź sobie zmień warunek pętli na
for(;cin>>ch&&('0'<=ch)&&(ch<='9');)

I weź nie bądź taki agresywny.

1

I weź nie bądź taki agresywny.

nie jestem agresywny, ja komuś grzecznie odpowiedziałem na posta, najlepiej jak potrafiłem, a ten pod nickiem dragon uczepił się mnie po prostu i zaczął ze mnie drwić. A że dał jakąś protezę i nie ma zamiaru się do tego ustosunkować, przeprosić, więc co ja zrobię ? W sumie, może lepiej dać sobie na luz i zignorować bzdury od niego i tyle.

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