Forumul Scientia

IT şi electronică => Programare => Subiect creat de: justakid din Mai 21, 2011, 10:35:36 AM

Titlu: Sir strict monoton crescator/descrescator
Scris de: justakid din Mai 21, 2011, 10:35:36 AM
Buna, am si eu o problema... am rezolvat exercitiul, mi-a mers, am copiat in notepad codul...iar acum nu mai merge, si nu ma prind daca/ce am schimbat. x~(

12. Sa se realizeze un program in care folosind subprograme sa se citeasca n numere naturale si sa se afiseze doar acele nr care sunt sub forma unui sir strict monoton crescator sau descrescator.


#include<iostream>

using namespace std;

bool sir(unsigned int a)
{
unsigned int r,c[5],k=1,i;
bool sirsm=true;

while(a!=0)
{
c[k]=a%10;
a/=10;
k++;
}

if(c[1]<c[2])
for(i=2;i<=k-1;i++)
if(c[i]>=c[i+1])
{
sirsm=false;
break;
}
else
{
if(c[1]>c[2])
for(i=2;i<=k-1;i++)
if(c[i]<=c[i+1])
{
sirsm=false;
break;
}
else
sirsm=false;
}

if (sirsm==true)
return true;
else
return false;

sirsm=true;
}

int main()
{

unsigned int n,i,a[100];

cin>>n;

for(i=1;i<=n;i++)
cin>>a[i];

for(i=1;i<=n;i++)
{
if(sir(a[i])==true)
cout<<a[i]<<" ";
}

return 0;
}



Si varianta fara subprograme...


#include<math.h>
#include<iostream>

using namespace std;

int main()
{

unsigned int n,i,a[100],c[5],k=1,j,r;
bool sir=true;

cin>>n;

for(i=0;i<=n-1;i++)
cin>>a[i];

for(i=0;i<=n-1;i++)
{
r=a[i];
while(r!=0)
{
c[k]=r%10;
r/=10;
k++;
}
if(c[1]<c[2])
for(j=2;j<=k-1;j++)
if(c[j]>=c[j+1])
{
sir=false;
break;
}
else
{
if(c[1]>c[2])
for(j=2;j<=k-1;j++)
if(c[j]<=c[j+1])
{
sir=false;
break;
}
else
sir=false;
}
if(sir==true)
cout<<a[i]<<" ";
sir=true;
k=1;
}

return 0;
}


Later edit: utilizez MinGW.
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: Quantum din Mai 21, 2011, 03:30:52 PM
@justakid
Poti descrie algoritmul?
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: justakid din Mai 21, 2011, 04:08:24 PM
Heh?

De ce, crezi ca l-am copiat de undeva? Sau ar trebui sa ma prind eu care e greseala descriindu-l? Ca de prins incerc de peste 2 ore.

Ok.. Cuprinde un subrpogram care tre sa aiba ca rezultat adevarat sau fals, iar in el verific daca cifrele nr repr un sir strict monoton.
Intai extrag cifrele, memorandu-le intr-un vector c[k], unde k este initializat cu 1 si creste cu 1 dupa extragerea fiecarei cifre. Astfel la finalul whileului vectorul c o sa cuprinda k-1 cifre (Deoarece atunci cand a=0 k mai creste cu 1 inainte ca prog sa verifice daca a!=0 - asa functiona whileul, nu?), k-1 fiind numaru' de cifre al numarului pt care se verifica blablabla.
Daca c[1]>c[2] (c[1] e de fapt ultima cifra a sirului dar asta nu are relevanta pt ca tre sa fie crescator SAU descrescator) inseamna ca intre TOATE cifrele trebuie sa existe aceasi relatie, si anume ci<c[i+1]. De aceea verific intai relatia dintre primele 2 cifre. IF(1) c[1]<c[2] trebuie ca si intre cifrele de la 2 la k-1 relatia sa fie aceasi. Astfel, daca se gaseste un c[i<=c[i+1], variabila logica sirsm care este initializata cu valoarea adevarat ia valoarea fals. ELSE(1), daca c[1] nu e > c[2]: IF(2) -pe else 1- c[1]<c[2] e fix acelasi lucru doar ca trebuie sa nu existe c[i>=c[i+1], ELSE  -pe if 2- mai ramane doar cazul in care atat IF1 cat si IF2 sunt false. Daca c[1] nu e nici > nici < decat c[2] => c[1]=c[2] si cum sirul trebuie sa fie STRICT monton, e din start fals si variabila sirsm ia valoarea fals.
Dupa ce s-a incheiat verificarea relatiei dintre cifre, daca sirsm este inca adevarat cum a fost initializat inseamna ca nu a fost gasit nimic in neregula si ca cifrele se afla intradevar intr-o relatie de strica monotonie. Daca aceste e cazul, sir() ia valoarea true, altfel false. Dupa sirsm ia valoarea adevarat din nou... (Nu sunt sigura daca trebuie...acum imi dau seama ca pt fiecare numar pt care verifica o ia de la inceput deci sirsm va fi true la-nceput, asa cum trebuie. Corect? La fel si pt k...ca daca nu e adevarat pt sirsm atunci si lu' k i-ar trebui atribuita valoarea 1 la finalul suprog.)

Incepe programul propriu zis...Se citeste un nr n care va reprezenta lungimea vectorului a. Citesc vectorul. Apoi pt fiecare element al acestuia, apelez subprogramul sir. Daca rezultatul este adevarat inseamna ca a[i e format din cifre in relatie de strica monotonie si-l afisez.

Ah, si inca o intrebare. Pot sa folosesc aceasi variabila si-n program si-n subprogram si sa ii atribui alte valori in program decat in subprogram, nu...? Gen unsigned int i. Si-l pot declara global.

Da. Nu ma prind ce nu e bine. :))

Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: Quantum din Mai 21, 2011, 04:40:03 PM
Citat din: justakid din Mai 21, 2011, 04:08:24 PM
De ce, crezi ca l-am copiat de undeva? Sau ar trebui sa ma prind eu care e greseala descriindu-l? Ca de prins incerc de peste 2 ore.
Nu am considerat ca l-ai copiat de undeva. Doar ca nu eram sigur ca inteleg eu problema.
Cand zici ca nu mai merge, la ce te referi exact? Eu am rulat codul pe care l-ai postat si pare sa mearga (cel putin pentru cazuri particulare).
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: justakid din Mai 21, 2011, 05:30:01 PM
Pai mie-mi afiseaza orice numar introduc...
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: Quantum din Mai 21, 2011, 06:44:58 PM
Corecteaza urmatoarele:
Foloseste indexul sirului 0 pentru primul element in toate sirurile exemplu: a[0]
Foloseste acoladele ({}) cat mai des pentru a incadra blocuri de cod.
Edit: corectat gresala gramaticala si eliminat paragraf inutil

#include<iostream>

using namespace std;

bool sir(unsigned int a)
{
unsigned int r,c[5],k=0,i;
bool sirsm=true;

while(a!=0)
{
c[k]=a%10;
a/=10;
k++;
}

if(c[0]<c[1])

for(i=1;i<=k-2;i++)
{ if(c[i]>=c[i+1])
{

sirsm=false;
i=k;
}
       }

else
{
if(c[0]>c[1])

for(i=1;i<=k-2;i++)
{ if(c[i]<=c[i+1])
 {
sirsm=false;
i=k;
 }
   }
else
sirsm=false;


}

return sirsm;
}

int main()
{

unsigned int n,i,a[100];

cin>>n;

for(i=0;i<n;i++)
cin>>a[i];

for(i=0;i<n;i++)
{
if(sir(a[i])==true)
cout<<a[i]<<" ";
}
cin >>n;
return 0;
}
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: justakid din Mai 21, 2011, 10:42:27 PM
A meeers. Mersi. Ce stupid, probabil asta am facut, am modificat acoladele...ca m-am gandit ca nu e nevoie de ele.

Dar

if(blabla)
   for(blabla)
      if(...)

de ce nu merge? Ca au doar o instructiune fiecare...adica if are un for, forul are un if.

De inceputu' de la 0 stiam, dar mereu uit cand scriu programul. Mi se pare asa aiurea, ca eu nu-ncep sa numar de la 0... gen cifra 1 suna mai bine ca cifra 0, chiar daca de fapt e ultima cifra. =))
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: AlexandruLazar din Mai 21, 2011, 11:55:30 PM
Trebuie să delimitezi întotdeauna blocurile de instrucțiuni. Dacă blocul are un singur rând nu e nevoie de acolade, dar dacă sunt mai multe, trebuie delimitate clar cu acolade.

Sfat prietenesc care o să te scape de mulți nervi și multe ore de depanat aiurea: se poate să ai un profesor de informatică căruia îi place să facă economie de cretă și să nu pună acolade dacă nu e nevoie de ele, eventual explicându-ți cu mândrie și că nu e nevoie. Nu face ca el. Pune întotdeauna acoladele, chiar dacă nu e nevoie de ele acum. Patru taste apăsate cer prea mult timp, săpatul după o formulare corectă sintactic dar care nu înseamnă ce crezi ia mult mai mult.

Problema pare a fi aici:


if(c[1]>c[2])
for(j=2;j<=k-1;j++)
if(c[j]<=c[j+1])
{
sir=false;
break;
}
else
sir=false;


După indentare, cred că vroiai să pui else-ul de jos corespunzând lui if(c[1]>c[2]), dar din ce-mi mai aduc aminte din partea aia obscură din standard, un else fără acolade este asociat celui mai apropiat if. Deci de fapt este asociat cu if(c[j] <= c[j+1]).
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: justakid din Mai 24, 2011, 08:03:55 PM
Cum adica in else fara acolade? Adica

else
   {
      sirsm=false;
   }

?
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: AlexandruLazar din Mai 24, 2011, 10:17:04 PM
Prin else fără acolade înțeleg evident un... else după care nu pui nicio acoladă.

Comportamentul nu e bine definit de standard în acest caz. Unele compilatoare or să înțeleagă că ai vrut un bloc mare după for, dar vor lega else-ul de if-ul din for, nu de cel de deasupra lui. Majoritatea  însă cred că nu vor face nimic în for și pace.
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: tavy din Mai 25, 2011, 11:24:37 PM
Citat din: AlexandruLazar din Mai 24, 2011, 10:17:04 PM
Comportamentul nu e bine definit de standard în acest caz. Unele compilatoare or să înțeleagă că ai vrut un bloc mare după for, dar vor lega else-ul de if-ul din for, nu de cel de deasupra lui. Majoritatea  însă cred că nu vor face nimic în for și pace.
Din fericire nu ai dreptate și standardul ANSI C și ANSI C++ este foarte bine definit, cel puțin în cazul acesta. Pentru C++ nu bag mâna în foc dar pentru C sunt convins că standardul este exact definit pentru toate cazurile.
În cazul fragmentului de cod de mai sus, else face parte din ultimul if.
Mai exact codul este văzut astfel:

if(c[1]>c[2]){
    for(j=2;j<=k-1;j++){
        if(c[j]<=c[j+1]){
            sir=false;
            break;
        }else{
            sir=false;
        }
    }
}

Am făcut abuz de acolade pentru claritate.
Cred că mai ai o problemă în înțelegerea limbajelor C și C++:
Citat din: AlexandruLazar din Mai 21, 2011, 11:55:30 PM
Dacă blocul are un singur rând nu e nevoie de acolade, dar dacă sunt mai multe, trebuie delimitate clar cu acolade.
În C și C++ trecerea la linie nouă are semnificație doar în cazul directivelor preprocesor, compilatorul nu face diferența între linie nouă, spațiu sau tab atâta timp cât acestea nu fac parte dintr-un șir de caractere.
Mai exact, codul de mai sus pentru compilator i-ar fi tot una dacă ar fi scris:

if(c[1]>c[2]){for(j=2;j<=k-1;j++){if(c[j]<=c[j+1]){sir=false;break;}else{sir=false;}}}

sau:

if(c[1]>c[2])for(j=2;j<=k-1;j++)if(c[j]<=c[j+1]){sir=false;break;}else sir=false;

În ce privește instrucțiunea if sintaxa este următoarea:

if(expresie)instructiune1[else instructiune2]

unde instructiune1/instructiune2 pot fi orice instrucțiune a limbajului, inclusiv instrucțiunile foarte folosite dar mai puțin conștientizate ca instrucțiuni:
În ce privește asociativitatea if/else ea este de la dreapta la stânga, astfel, în secvența:
if(expr1)inst1 if(exp2)inst2 else inst3
else este legat de al doilea if
Citat din: AlexandruLazar din Mai 24, 2011, 10:17:04 PM
Unele compilatoare or să înțeleagă că ai vrut un bloc mare după for
În C/C++ nu prea avem noțiunea de bloc, există noțiunea de instrucțiune compusă.
Se mai obișnuiește și este în general acceptat, să se folosească noțiunea de bloc atunci când se vorbește de secvența dintre acoladele care formează definiția unei funcții dar a folosi noțiunea de bloc atunci când avem de-a face cu o instrucțiune compusă este deja un abuz de limbaj mult prea mare.
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: AlexandruLazar din Mai 26, 2011, 12:47:57 AM
Hai să le luăm pe rând -- întâi alea mici:

CitatÎn C/C++ nu prea avem noțiunea de bloc, există noțiunea de instrucțiune compusă.
Se mai obișnuiește și este în general acceptat, să se folosească noțiunea de bloc atunci când se vorbește de secvența dintre acoladele care formează definiția unei funcții dar a folosi noțiunea de bloc atunci când avem de-a face cu o instrucțiune compusă este deja un abuz de limbaj mult prea mare.

Ba o avem, e definită de standard :). ANSI C zice așa:

CitatA compound statement (also called a block )allows a set of
statements to be grouped into one syntactic unit, which may have its
own set of declarations and initializations (as discussed in
$3.1.2.4).  The initializers of objects that have automatic storage
duration are evaluated and the values are stored in the objects in the
order their declarators appear in the translation unit.

În schimb, C99 zice așa:

CitatA block allows a set of declarations and statements to be grouped into one syntactic unit.
The initializers of objects that have automatic storage duration, and the variable length
array declarators of ordinary identifiers with block scope, are evaluated and the values are
stored in the objects (including storing an indeterminate value in objects without an
initializer) each time the declaration is reached in the order of execution, as if it were a
statement, and within each declaration in the order that declarators appear.

Tot legat de standard:

CitatÎn C și C++ trecerea la linie nouă are semnificație doar în cazul directivelor preprocesor, compilatorul nu face diferența între linie nouă, spațiu sau tab atâta timp cât acestea nu fac parte dintr-un șir de caractere.

Corect, dar eu nu mă refeream la faptul că linia nouă are înțeles de delimitator de bloc, ci la stilul de a scrie programul ca atare. Una la mână, pentru că e foarte ușor să faci greșeli când editezi rapid, schimbând:


for(i=0;i<t;i++)
    s = pthread_create(&tinfo[tnum].thread_id, &attr, &thread_start, &tinfo[tnum]);


în


for(i=0;i<t;i++)
    dolock(s);
    s = pthread_create(&tinfo[tnum].thread_id, &attr, &thread_start, &tinfo[tnum]);


care acum înseamnă cu totul altceva. A doua la mână pentru că începe să devină de-a dreptul groaznic să citești cod care e scris așa atunci când sunt multe blocuri unul în altul.

CitatDin fericire nu ai dreptate și standardul ANSI C și ANSI C++ este foarte bine definit, cel puțin în cazul acesta. Pentru C++ nu bag mâna în foc dar pentru C sunt convins că standardul este exact definit pentru toate cazurile.
În cazul fragmentului de cod de mai sus, else face parte din ultimul if.
Mai exact codul este văzut astfel:

Știu, asta am zis și eu în postul de dinaintea celui la care faci quote:

CitatDupă indentare, cred că vroiai să pui else-ul de jos corespunzând lui if(c[1]>c[2]), dar din ce-mi mai aduc aminte din partea aia obscură din standard, un else fără acolade este asociat celui mai apropiat if. Deci de fapt este asociat cu if(c[j] <= c[j+1]).

Din păcate nu știu cât de bine s-a înțeles în al doilea post, și pe bună dreptate -- m-am exprimat ca un climatolog  ;D. Standardul e bine definit pentru ce vroia justakid să facă, eu aveam în cap niște probleme legate de ordinea de evaluare, dar care nu intervin la problema lui.
Titlu: Răspuns: Sir strict monoton crescator/descrescator
Scris de: tavy din Mai 26, 2011, 07:03:23 PM
Citat din: AlexandruLazar din Mai 26, 2011, 12:47:57 AM
Hai să le luăm pe rând -- întâi alea mici:

CitatÎn C/C++ nu prea avem noțiunea de bloc, există noțiunea de instrucțiune compusă.
Se mai obișnuiește și este în general acceptat, să se folosească noțiunea de bloc atunci când se vorbește de secvența dintre acoladele care formează definiția unei funcții dar a folosi noțiunea de bloc atunci când avem de-a face cu o instrucțiune compusă este deja un abuz de limbaj mult prea mare.

Ba o avem, e definită de standard :). ANSI C zice așa:

CitatA compound statement (also called a block )allows a set of
statements to be grouped into one syntactic unit, which may have its
own set of declarations and initializations (as discussed in
$3.1.2.4).  The initializers of objects that have automatic storage
duration are evaluated and the values are stored in the objects in the
order their declarators appear in the translation unit.

În schimb, C99 zice așa:

CitatA block allows a set of declarations and statements to be grouped into one syntactic unit.
The initializers of objects that have automatic storage duration, and the variable length
array declarators of ordinary identifiers with block scope, are evaluated and the values are
stored in the objects (including storing an indeterminate value in objects without an
initializer) each time the declaration is reached in the order of execution, as if it were a
statement, and within each declaration in the order that declarators appear.
Se pare că aici ai dreptate, văd că în standard se folosește denumirea de bloc pentru instrucțiunea compusă, nu mă așteptam. Mea culpa.

Citat din: AlexandruLazar din Mai 26, 2011, 12:47:57 AM
Tot legat de standard:

CitatÎn C și C++ trecerea la linie nouă are semnificație doar în cazul directivelor preprocesor, compilatorul nu face diferența între linie nouă, spațiu sau tab atâta timp cât acestea nu fac parte dintr-un șir de caractere.

Corect, dar eu nu mă refeream la faptul că linia nouă are înțeles de delimitator de bloc, ci la stilul de a scrie programul ca atare. Una la mână, pentru că e foarte ușor să faci greșeli când editezi rapid, schimbând:

Aici m-a derutat afirmația ta cum că:
Citat din: AlexandruLazar din Mai 24, 2011, 10:17:04 PM
Comportamentul nu e bine definit de standard în acest caz. Unele compilatoare or să înțeleagă că ai vrut un bloc mare după for, dar vor lega else-ul de if-ul din for, nu de cel de deasupra lui. Majoritatea  însă cred că nu vor face nimic în for și pace.
Am impresia că te refereai la ,,for" din secvența:

if(c[1]>c[2])
for(j=2;j<=k-1;j++)
if(c[j]<=c[j+1])
{
sir=false;
break;
}
else
sir=false;

Or afirmația: ,,Majoritatea  însă cred că nu vor face nimic în for și pace" presupune că după ,,for" am avea ,,;" (instrucțiunea vidă). Cum nu avem instrucțiunea vidă rezultă că în ,,for" se va executa urmatoarea intrucțiune, respectiv ,,if".