milo112 [ Legionista ]
Programowanie w C
Witam, jestem pocztukjącym, dopiero uczę sie programowania w tym języku i mam taki problem, mam napisać program w C który w podanym ciągu znaków ma podać ile jest w tym ciągu liczb, czyli cyfr nieprzerwanych (np. 123 a23 2 ab ) tutaj powinien wypisać w tym ciągu sa 2 liczby, wiem jak napisać program który zliczy wszystkie znaki w tym ciągu ale nie wiem jak zrobić żeby liczył same liczby :( Prosiłbym o pomoc !!! Będę naprawde wdzięczny jeżeli ktoś pomoże !!
beo314 [ Konsul ]
mam nadzieję, że dobrze zrozumiałem...
Wszystko możesz dosyć łatwo załatwić, korzystając z paru dodatkowych zmiennych, tzw flag. Flagi włączasz bądź wyłączasz, jeżeli spełniony zostanie określony warunek (znaczy boolean wystarczy)
152 13j 2 jjk3 33 3j
sprawdzasz string od lewej (zakładam, że masz napisany kod przeszukujący, sprawdzający rodzaj znaku itd)
liczba, liczba, liczba, spacja (jeżeli trafiasz na spację, sprawdzasz flagę czy_była_litera, jeżeli =0, ilość_liczb=ilość_liczb+1 no i reset flagi), liczba, liczba, litera (czy_była_litera=1), spacja (sprawdzasz flagę czy_była_litera, jeżeli =1, ilość_liczb pozostaje bez zmian) no i tak do końca
milo112 [ Legionista ]
wielkie dzieki za pomoc :) ale wlasnie ma problem z kodem weryfikującym rodzja znaku nie wiem jak napisać ten kod żeby rozróżniał czy dany znak to litera czy liczba ??
surox [ Centurion ]
Trzymaj:
string ciag = "123 b1 av 3"; //przykładowy ciąg
int liczb = 0; //ilosc liczb w ciągu
int cyfra = 0; //0- to nie jest cyfra(liczba), 1 - to jest cyfra(liczba)
int dlugosc = ciag.length();
for (int i=0; i<dlugosc; i++)
if (ciag >= '0' && ciag <= '9' && cyfra != -1)
cyfra = 1;
else
if (ciag != ' ')
cyfra = -1;
if (ciag == ' ' || i == dlugosc - 1)
if (cyfra == 1)
liczb++;
cyfra = 0;
cout << "Ilość liczb: " << liczb;
GSi [ Pretorianin ]
A ja mógłbym poprosić o pomoc w napisaniu programu który wypisuje wyrazy ciągu Fibbonaciego rekurencyjnie i nierekurencyjnie?. Też jestem początkujący.
Wiem, że ten ciąg to taki w którym 2 pierwsze wyrazy są rowne 1 a następne są sumą dwóch poprzednich. Mam problemy z napisaniem kodu:/ Używam kompilatora Borlanda.
surox [ Centurion ]
GSi -> algorytm rekurencyjny ściągnij ze strony algorytm.cad.pl (link poniżej). Wypisuje on konkretny wyraz ciągu, więc łatwo można go przerobić, jeśli potrzebujesz wypisać wszystkie wyrazy.
GSi [ Pretorianin ]
surox -> dzieki! zaraz poprobuje.
milo112 [ Legionista ]
surox -> Wielkie dzieki !!! :)
GSi [ Pretorianin ]
Przerobiłem to tak:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int fib(n)
if ((n==1)||(n==2))
return 1;
else
return fib(n-1)+fib(n-2);
void main(void)
int n,i;
printf("n= ");
scanf("%d",&i);
for (n=1;n<i+1;n++)
printf("\n %d-ty wyraz ciagu Fibonacciego: %d\n",n,fib(n));
getch();
return;
Program działa tylko, że od 24 wyrazu sie psuje, wypisuje liczbe ujemna. Gdzieś trzeba zmienić na typ long int? W którym miejscu?
Jak można wypisać ten ciąg nierekurencyjnie?
GSi [ Pretorianin ]
Ok już sobie poradziłem tak jest dobrze:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
long int fib(n)
if ((n==1)||(n==2))
return 1;
else
return fib(n-1)+fib(n-2);
void main(void)
int n,i;
printf("n= ");
scanf("%d",&i);
for (n=1;n<i+1;n++)
printf("\n %d-ty wyraz ciagu Fibonacciego: %ld\n",n,fib(n));
getch();
return;
Prosze o pomoc w napisaniu tego programu iteracyjnie.
surox [ Centurion ]
Najłatwiej będzie zapamiętywać ostatni i przed ostatni wyraz ciągu i na ich podstawie obliczać bieżący:
int w1 = 0; //w1 - wyraz ostatni
int w2 = 1; //w2 - wyraz przed ostatni
int w, n;
printf("n= ");
scanf("%d",&n);
if (n >= 2)
for (int i=1; i<=n; i++)
w = w1 + w2;
printf("\n %d-ty wyraz ciagu Fibonacciego: %d\n",i,w);
w2 = w1;
w1 = w;
getch();
GSi [ Pretorianin ]
surox --> wielkie dzieki:)
Mam tylko pytanie: dlaczego przyjąłeś na początku ostatni wyraz 0 a przedostatni 1?
surox [ Centurion ]
sorry, źle napisałem komentarze. Miało być:
int w1 = 0; //w1 - wyraz przedostatni
int w2 = 1; //w2 - wyraz ostatni
czyli:
Liczymy od trzeciego wyrazu, więc wyraz ostatni (w2) na samym początku obliczeń jest wyrazem drugim, więc z definicji ciągu Fib. wynosi 1.
Podobnie jest z wyrazem przedostatnim (w1), skoro liczymy od trzeciego wyrazu, to wyraz przed ostatni na początku obliczeń jest wyrazem pierwszym, a z definicji ciągu F. wynosi 0 :)
surox [ Centurion ]
Eh, jednak było dobrze, tylko powinny być odwrotne wartości:
int w1 = 1; //w1 - wyraz ostatni
int w2 = 0; //w2 - wyraz przedostatni
wyraz ostatni - w rozumieniu wyraz ostatnio obliczony,
wyraz przedostatni - w rozumieniu wyraz obliczony przed ostatnim obliczeniem :))
GSi [ Pretorianin ]
Ok wielkie dzieki za pomoc:)
surox [ Centurion ]
Eh, sorry, dobrze było, tylko źle podałem wartości. Ma być:
int w1 = 1; //w1 - wyraz ostatni
int w2 = 0; //w2 - wyraz przedostatni
w1 - wyraz ostatni, więc na początku wyraz drugi (liczymy od wyrazu trzeciego)
w2 - wyraz przedostatni, więc na początku wyraz pierwszy
ostatni - w rozumieniu ostatnio obliczony
przedostatni - w rozumieniu obliczony przed ostatnim obliczeniem :))
milo112 [ Legionista ]
surox -> Usiłowałem to dzisiaj napisać wszystko byłoby dobrze gdyby nie wywalał błedu dotyczącego int dlugosc = ciag.length(); i wywala błąd :
" request for member `length' in `ciag', which is of non-aggregate type `char' "
Nie wiem dlaczego wywala taki błąd :(
Program wygląda tak :
#include <stdio.h>
#include <conio.h>
int licz ( char ciag )
int liczb = 0; //ilosc liczb w ciągu
int cyfra = 0; //0- to nie jest cyfra(liczba), 1 - to jest cyfra(liczba)
int dlugosc = ciag.length();
for (int i=0; i<dlugosc; i++)
if (ciag >= '0' && ciag <= '9' && cyfra != -1)
cyfra = 1;
else
if (ciag != ' ')
cyfra = -1;
if (ciag == ' ' || i == dlugosc - 1)
if (cyfra == 1)
liczb++;
cyfra = 0;
int main()
char string[256];
printf( "Podaj lancuch: " );
scanf( "%[^\n]", string );
printf( "W tym ciągu jest %d liczb\n", licz ( string ));
getch();
return 0;
Czy mógłbyś żucić na to okiem i powiedziec w czym tkwi mój błąd ??
Byłbym wdzieczny i zobowiązany !!!
surox [ Centurion ]
Na początku dodaj dyrektywę #include <string>
Parametr "ciag" w funkcji "licz" powinien być typu string, a nie char. Typ char przechowuje tylko jeden znak.
milo112 [ Legionista ]
surox -> A mógłbyś spojżeć na to zrobiłęm to zupełnie inaczej troche uprościłem bo teraz ma w ciągu rozpoznawać liczby na tej zasadzie np. 12fs3ss333 -> wypisuje że są 3 liczby, działa na takiej zasadzie że gdy następny znak jest literą to zwieksza liczbę a jeżeli nie to przesuwa się do następnego znaku ,moim zdaniem powinni działać kompiluje sie ale nie podaje prwidłowego wyniku ??
Oto program :
#include <stdio.h>
#include <conio.h>
int licz ( char *ciag )
int liczb = 0;
while (*ciag != 0 )
if (*ciag >= '0' && *ciag <= '9')
if (*ciag+1 >= '0' && *ciag+1 <= '9')
++ciag;
else
liczb += 1;
++ciag;
else
++ciag;
return liczb;
int main()
char string[256];
printf( "Podaj lancuch: " );
scanf( "%[^\n]", string );
printf( "W tym ciagu jest %d liczb\n", licz ( string ));
getch();
return 0;
A tak wogle to wielkie dzieki za pomoc, troche mi glupio ze tak cie ciagle męcze !!
surox [ Centurion ]
while (*ciag != 0 )
...
Nie za bardzo rozumiem. Jesli wystapi 0, to ma przerwac sprawdzanie reszty ciagu?
milo112 [ Legionista ]
surox -> napisz do mnie na gg moj nr 960896 to napisze ci o co chodzi
surox [ Centurion ]
Nie mam gg.
Ale pewnie chodzi Ci o znak konca ciagu? to jest '\0'
milo112 [ Legionista ]
noo o to bo na koncu kazdego ciagu jest 0 i wtedy ma zkończyć to działanie
surox [ Centurion ]
Ten algorytm jest strasznie niedopracowany.
Po pierwsze, gdy bieżący i następny znak jest cyfrą, przeskakuje o dwa pola. Musisz uzyc klamer dla
liczb += 1;
++ciag;
Po drugie, napisałeś, że "gdy następny znak jest literą to zwieksza liczbę a jeżeli nie to przesuwa się do następnego znaku". A co, jeśli całe wyrażenie zakończy się cyfrą (np. 45f3)? Algorytm go nie policzy, bo po "trójce" nie ma litery.
surox [ Centurion ]
Ten algorytm jest strasznie niedopracowany.
Po pierwsze, gdy bieżący i następny znak jest cyfrą, przeskakuje o dwa pola. Musisz uzyc klamer dla
liczb += 1;
++ciag;
Po drugie, napisałeś, że "gdy następny znak jest literą to zwieksza liczbę a jeżeli nie to przesuwa się do następnego znaku". A co, jeśli całe wyrażenie zakończy się cyfrą (np. 45f3)? Algorytm go nie policzy, bo po "trójce" nie ma litery.
milo112 [ Legionista ]
Hmmm no w sumie masz racje, a co byś w tym wypadku proponował ?
milo112 [ Legionista ]
Myśle że możnaby było w takim razie porównywać z liczbą poprzednia a nie z nastepną i jeżeli zank jest literą a poprzedni cyfrą to zwiekszamy liczb o jeden. Co o tym sądzisz
surox [ Centurion ]
Nie, w sumie dobrze jest. Bo jesli nastepny znak nie jest cyfrą, to zwieksza "liczbe", a przeciez znak konca ciagu (\0) cyfrą nie jest , więc wszystko gra :)
Musisz zmienic *ciag+1 na *(ciag+1)
surox [ Centurion ]
Czyli pętla while powinna wyglądać tak:
while (*ciag != '\0')
if (*ciag >= '0' && *ciag <= '9')
if (*(ciag+1) >= '0' && *(ciag+1) <= '9')
++ciag;
else
liczb += 1;
++ciag;
else
++ciag;
milo112 [ Legionista ]
No wkoncu działa :))) tylko jeszcze zastanawiam sie dlaczego włąnie zlicza ostatnią liczbę ?? Może wiesz dlaczego ?
milo112 [ Legionista ]
A znalazłem twojego posta odnośnie tego że ostatni znak rzeczywiście nie jest liczba, czyli już wszystko rozumiem :)) Wielkie Dzieki !!! Jesteś cool gościem ;)