Ştiri:

Vă rugăm să citiţi Regulamentul de utilizare a forumului Scientia în secţiunea intitulată "Regulamentul de utilizare a forumului. CITEŞTE-L!".

Main Menu

Program care citeşte 3 numere reale

Creat de Flavius, Octombrie 30, 2011, 05:40:54 PM

« precedentul - următorul »

0 Membri şi 1 Vizitator vizualizează acest subiect.

Flavius

Să se scrie un program care citeşte trei numere reale şi verifică dacă acestea pot forma laturile unui triunghi.

eu nu am facut asa ceva pana acuma...

Electron

#1
Nici eu. Si ce-i cu asta?

e-
Don't believe everything you think.

Flavius


Electron

Esti blocat la programarea solutiei, sau la partea de geometrie a problemei?

Daca nu ne spui nimic despre ce ai incercat si unde te-ai blocat, nu avem cum sa te ajutam. Doar nu astepti solutia mura in gura...

e-
Don't believe everything you think.

florin_try


tavy

Citat din: Flavius din Octombrie 30, 2011, 05:40:54 PM
Să se scrie un program care citeşte trei numere reale şi verifică dacă acestea pot forma laturile unui triunghi.

eu nu am facut asa ceva pana acuma...

Un astfel de program nu va putea rula niciodată pe vreun calculator, niciodată un calculator nu va putea lucra cu numere reale pentru că ar avea nevoie de memorie infinită.

În loc de numere reale calculatoarele folosesc așa numitele numere cu virgulă mobilă unde sunt memorate două numere întregi cuprinse într-un interval rezonabil astfel încât numerele pot fi memorate de calculator. Unul din numere se numește mantisă iar celălalt exponent

Fără a fi riguros, numărul rezultat ar fi de genul [tex]m\cdot10^e[/tex] unde [tex]m[/tex] este mantisa iar [tex]e[/tex] este exponentul. De fapt mantisa este, de obicei, un număr cuprins în intervalul [tex](-1,1)[/tex] sau [tex](-10,10)[/tex], nu mai știu sigur, cu un număr fix de zecimale, un număr cu un număr fix de zecimale este echivalent, cel puțin din punct de vedere al tehnicii de calcul, cu un întreg, se mai numește număr cu virgulă fixă, numărul întreg fiind un caz special de număr cu virgulă fixă.

Nu am pretenția că ce am spus în paragraful anterior ar fi exact, scriu din amintiri, esențial este primul paragraf. Dacă te interesează detalii găsești la http://en.wikipedia.org/wiki/Floating_point.

De remarcat că exponentul specifică cu câte cifre, și în ce direcție, se deplasează virgula în cadrul mantisei, de aici și numele de reprezentare în virgulă mobilă.

Știu, vor fi unii care vor zice că ma cramponez de definiții, asta este, am avut prea mult de suferit din cauza celor care interpretează cuvintele cum vor ei astfel încât nu am de gând să accept exprimări profund greșite și confuzii ale unei mulțimi cu număr finit de elemente cu mulțimea numerelor reale.

AlexandruLazar

Din pacate am vazut multe manuale de informatica de liceu care fac aceasta greseala.

Pe de alta parte, pot numai sa remarc ca e o distinctie extrem de importanta. Am vazut de mai multe ori probleme intervenite din cauza ca programatorul se astepta ca operatiile in virgula mobila sa se desfasoare la fel si sa aiba aceleasi proprietati ca si cand s-ar desfasura pe numere reale.

In alta ordine de idei, asteptam detalii de la Flavius ca sa vedem unde s-a blocat :).

HarapAlb

Nu zice nimeni ca trebuie sa ne limitam la precizia implicita a "calculatorului" ci putem folosi operatiile arimetice cu precizie arbitrara. Mergand mai departe, nimeni nu poate efectua toate operatiile respective pentru ca ar avea nevoie de spatiu de stocare infinit (memorie, banda magnetica, hartie etc.)

Totusi, cred ca altul era obiectivul lectiei :)

Quantum

Din moment ce se pare ca Flavius nu mai are nevoie de ajutor, am scris o solutie in Java care calculeaza perimetrul, aria si unghiurile daca cele trei numere pot fi laturile unui triunghi:

import javax.swing.JOptionPane;
import java.lang.Math;
import java.text.*;

public class LaturiTriunghi
{
public static void main(String[] args)
{

DecimalFormat f = new DecimalFormat("##.00");
double numar1=0.0, numar2=0.0, numar3=0.0;
boolean validat=false;

while (!validat)
{
try
{
numar1=Double.parseDouble(JOptionPane.showInputDialog(null,
"Introduceti primul numar:",
"Introducere parametru 1", JOptionPane.QUESTION_MESSAGE));
validat=true;
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null,"Ati introdus un parametru invalid. Mai incercati.","Eroare!",
JOptionPane.INFORMATION_MESSAGE);
validat=false;
}
}
validat = false;
while (!validat)
{
try
{
numar2=Double.parseDouble(JOptionPane.showInputDialog(null,
"Introduceti al doilea numar:",
"Introducere parametru 2", JOptionPane.QUESTION_MESSAGE));
validat=true;
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null,"Ati introdus un parametru invalid. Mai incercati.","Eroare!",
JOptionPane.INFORMATION_MESSAGE);
validat=false;
}
}
validat = false;
while (!validat)
{
try
{
numar3=Double.parseDouble(JOptionPane.showInputDialog(null,
"Introduceti al treilea numar:",
"Introducere parametru 3", JOptionPane.QUESTION_MESSAGE));
validat=true;
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null,"Ati introdus un parametru invalid. Mai incercati.","Eroare!",
JOptionPane.INFORMATION_MESSAGE);
validat=false;
}
}
if (numar1+numar2>numar3 && numar2+numar3>numar1 && numar1+numar3>numar2)
{
double perimetrul = numar1+numar2+numar3;
double aria = Math.sqrt((perimetrul/2)*(perimetrul/2-numar1)*(perimetrul/2-numar2)*(perimetrul/2-numar3));
double unghi1=Math.acos((numar2*numar2+numar3*numar3-numar1*numar1)/(2*numar2*numar3))*(180/Math.PI);
double unghi2=Math.acos((numar1*numar1+numar3*numar3-numar2*numar2)/(2*numar1*numar3))*(180/Math.PI);
double unghi3=Math.acos((numar1*numar1+numar2*numar2-numar3*numar3)/(2*numar1*numar2))*(180/Math.PI);

JOptionPane.showMessageDialog(null,
  "Cele trei numere pot forma un triunghi cu perimetrul: "+f.format(perimetrul)+", aria "+f.format(aria)+"\nunghiul 1: "
  +f.format(unghi1)+", unghiul 2: "+f.format(unghi2)+", unghiul 3: "+f.format(unghi3),
  "Caracteristicile triunghiului (unghiurile in grade)",
  JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null,
  "Cele trei numere NU pot forma un triunghi",
  "Rezultatul analizei",
  JOptionPane.INFORMATION_MESSAGE);
}
}
}

AlexandruLazar

Tare :). Ca o observatie (lucru la care dealtfel sunt sigur ca te-ai gandit deja, dar daca topicul e unul didactic, nu strica amintita) e ca secventa de citire a fiecarui numar e de fapt destul de repetitiva si se poate muta intr-o functie. Nu e numai o problema de eleganta, ci si una de utilizare -- in acest fel, daca o sa vrei sa faci o interfata web sau una de consola pentru program, va trebui modificata doar functia de citire a numarului, intr-un singur loc (exemplul este desigur trivial, dar cred ca destul de ilustrativ).

tavy

Nu știu Java dar secvența:

validat = false;
while (!validat)
{
  try
  {
    numar2=Double.parseDouble(JOptionPane.showInputDialog(null,
          "Introduceti al doilea numar:",
          "Introducere parametru 2", JOptionPane.QUESTION_MESSAGE));
    validat=true;
  }
  catch(NumberFormatException e)
  {
    JOptionPane.showMessageDialog(null,"Ati introdus un parametru invalid. Mai incercati.","Eroare!",
        JOptionPane.INFORMATION_MESSAGE);
    validat=false;
  }
}

este un exemplu de cum să nu folosești instrucțiunea while.
Corect este să nu uităm de existența instructiunii do ... while

do{
  try
  {
    numar2=Double.parseDouble(JOptionPane.showInputDialog(null,
          "Introduceti al doilea numar:",
          "Introducere parametru 2", JOptionPane.QUESTION_MESSAGE));
    validat=true;
  }
  catch(NumberFormatException e)
  {
    JOptionPane.showMessageDialog(null,"Ati introdus un parametru invalid. Mai incercati.","Eroare!",
        JOptionPane.INFORMATION_MESSAGE);
    validat=false;
  }
}while(!validat);

Pentru că este un caz clar de ciclu cu test final și pentru că nu are nici un sens să execuți în plus la început instrucțiunea validat = false; și nici să testezi valoarea lui validat înainte să fi citit un număr și să fi setat valoarea lui validat în funcție de validitatea acestuia.
Fac caz de această nuanță pentru că codul se vrea unul cu caracter educativ și poate induce unui începător o practică greșită de utilizare a instrucțiunii while, altfel codul poate funcționa bine și așa cum a fost scris de Quantum.

Quantum

Citat din: AlexandruLazar din Noiembrie 05, 2011, 12:03:42 PM
[...] secventa de citire a fiecarui numar e de fapt destul de repetitiva si se poate muta intr-o functie.
Da asa e. In cazul meu am citit un numar si am facut copy/paste rezultatul fiind repetivitatea nenecesara, dorind sa scriu o solutie cat mai rapida. O functie e mult mai utila si din cauza ca poate fi refolosita.

Citat din: tavy din Noiembrie 05, 2011, 12:18:27 PM
Pentru că este un caz clar de ciclu cu test final și pentru că nu are nici un sens să execuți în plus la început instrucțiunea validat = false; și nici să testezi valoarea lui validat înainte să fi citit un număr și să fi setat valoarea lui validat în funcție de validitatea acestuia.
Fac caz de această nuanță pentru că codul se vrea unul cu caracter educativ și poate induce unui începător o practică greșită de utilizare a instrucțiunii while, altfel codul poate funcționa bine și așa cum a fost scris de Quantum.
Da, buna observatie. Probabil ca e si o problema de obisnuinta, unde la diferite alternative mai mult sau mai putin riguroase, aleg aceeasi solutie.
Ma bucur de ambele interventii. Asa o sa fiu si eu mai riguros.