Avatar billede siul Nybegynder
28. januar 2003 - 23:03 Der er 27 kommentarer og
1 løsning

Base b

Hej allesammen
Jeg er begyndt at laere lidt omkring algorithmer og har faaet en opgave hvor jeg skal oversaette en algorithme til C++. Haaber at der er nogen der har mod paa at laer mig det.

Her foelger krav til algorithmen:
Input: en positiv long integer og en base b {2,3,...16}.
Output: Base b expansion af n a[k-1], a[k-2],..a[0].

for baser stoerre end 10 til 16 bruges:
10-A, 11-B, 12-C, 13-D, 14-E, 15-F

Her er algorthmen:

Procedure BaseConversion(n:positive integer, b:{2,3,..16})
int a[33]
int q,k
Begin
    q:=n
    k:=0
    While(q<>0)
          Begin
                a[k]:=q mod b
                q:= floor(q/b)
                k:=k+1
            End
    OutputBaseBValue(a,k,b)
End

Haaber der er en kan hjaelpe mig med det!
Paa forhaand tak!
Avatar billede arne_v Ekspert
28. januar 2003 - 23:17 #1
#include <iostream>

using namespace std;

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void calc(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  for(int i=k-1;i>=0;i--) {
      cout << c[a[i]];
  }
  cout << endl;
  return;
}

int main(int argc, char *argv[])
{
  calc(11,2);
  calc(11,4);
  calc(11,8);
  calc(11,10);
  calc(11,12);
  calc(11,16);
  return 0;
}
Avatar billede arne_v Ekspert
28. januar 2003 - 23:18 #2
Ovenstående er absolut ikke topmålet af C++ kode, men det virker
og er nem at relatere til algoritmen.
Avatar billede siul Nybegynder
28. januar 2003 - 23:41 #3
Hej Arne,
Mange tak for dit svar. Jeg har kigget paa det og compilet det, men desvaerre faar jeg ikke oenskede output, hvilket ville vaere:
Base    Value    C log (ceiling af log)
2        1000      4
3        121      3
4        100      2
etc      etc      etc.

Jeg er i tvivl om hvordan man oversaetter floor (q/b), altsaa hvordan man runder ned til naermeste integer.
Derudover er jeg i tvivl om hvorfor du har sat function call i main som du har gjort.
Er det muligt jeg kan faa en lille forklaring paa mine spoergsmaal?
Jeg saetter stor pris paa din hjaelp :=)
Avatar billede arne_v Ekspert
29. januar 2003 - 07:18 #4
Øh.

Jeg tror der er lidt misforståelse omkring hvad algoritmen gør !

Mit program udskriver:
1011
23
13
11
B
B
hvilket er korrekt 11 i 2, 4, 8, 10, 12 og 16 tals systemet !

Det har intet med beregning af ceil(log(x) at gøre.

Ellers så har jeg ihvertfald misforstået noget ganske alvorligt.
Avatar billede arne_v Ekspert
29. januar 2003 - 07:20 #5
Hvor kommer algoritmen iøvrigt fra ?  Det ligner noget ALGOL-60 fra
ACM anno ca. 1970 !

Da C og C++ altid laver trunkering ved helttals division, så kan
floor(q/b) bare oversættes til q/b.
Avatar billede arne_v Ekspert
29. januar 2003 - 07:52 #6
Jeg har tænkt lidt ovet det.

Det må naturligvis gælde at:

CEIL(LOGb(n)) = k-fra-beregning(n-1,b)

Er det det du leder efter ?
Avatar billede siul Nybegynder
29. januar 2003 - 18:41 #7
Hej Arne,
Jeg ser du har vaeret aktiv til at svare igen, tak for det.
Algorithmen kommer fra en laerer, der maaske har brugt den i 1970 mens han stadigvaek fra studerende:-)Han haveder at det stadigavek er "up to date".
Jeg undskylder at jeg er daarlig til at forklare opgaven, men det skyldes desvaerre den kendsgerning at jeg ikke forstaar hvordan jeg griber det an. Jeg proever igen:
I opgaven skal jeg skrive et program der laeser en long integer fra standard input og vil output en tabel til en disk file der indeholder base 2,3,...,16 representation af input integer og ceiling af log base 2,3,...,16 af en integer.
Haaber det hjaelper. Endnu engang tak for din hjaelp!
Avatar billede arne_v Ekspert
29. januar 2003 - 19:24 #8
Prøv med:

#include <iostream>

using namespace std;

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void calc(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  cout << n << " = ";
  for(int i=k-1;i>=0;i--) {
      cout << c[a[i]];
  }
  cout << " base " << b << " og oprundet LOG" << b << " = " << k << endl;
  return;
}

int main(int argc, char *argv[])
{
  for(int i=2;i<=16;i++) calc(11,i);
  calc(9, 10);
  calc(10, 10);
  calc(11, 10);
  calc(99, 10);
  calc(100, 10);
  calc(101, 10);
  calc(999, 10);
  calc(1000, 10);
  calc(1001, 10);
  return 0;
}
Avatar billede arne_v Ekspert
29. januar 2003 - 19:26 #9
Den virker næsten som den skal.

Den viser "oprundet" LOGn i den betydning, at den *altid* runder op.

1.1, 1.5 og 1.9 bliver som normalt rundet op til 2.

Men 1.0 bliver faktisk "rundet op" til 2 også - og det er
lidt specielt.
Avatar billede arne_v Ekspert
29. januar 2003 - 19:28 #10
Hvilket er korrekt til at udregne antal cifre.

Skal du have en mere normal CEIL LOGn, så skal du bruge:

#include <iostream>

using namespace std;

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void calc(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  cout << n << " = ";
  for(int i=k-1;i>=0;i--) {
      cout << c[a[i]];
  }
  cout << " base " << b << " og oprundet LOG" << b << " = ";
  q = n-1; // <------
  k = 0;
  while(q!=0) {
      q=q/b;
      k++;
  }
  cout << k << endl;
  return;
}

int main(int argc, char *argv[])
{
  for(int i=2;i<=16;i++) calc(11,i);
  calc(9, 10);
  calc(10, 10);
  calc(11, 10);
  calc(99, 10);
  calc(100, 10);
  calc(101, 10);
  calc(999, 10);
  calc(1000, 10);
  calc(1001, 10);
  return 0;
}
Avatar billede siul Nybegynder
30. januar 2003 - 04:26 #11
Hej igen,
Takker endnu engang for at bruge tid paa mig.
Jeg har compilet dit program og kunne godt taenke mig at hoere hvad tankegangen er bag funnction calls i main (calc(9, 10), calc (...etc.) altsaa hvorfor du vaelger at vise base 10. Ville man ikke have svaret paa spoergsmaalet ved at undlade de function calls? Er det noedvendigt at bruge argc/*argv??
Tak igen - imponerende at faa saa god en hjaelp.
Avatar billede arne_v Ekspert
30. januar 2003 - 07:23 #12
Jeg skulle illustrere finessen med oprunding af 1.0 til 2.

Jeg kunne godt have brugt en anden base, men vi vi kender jo alle
base 10 bedst.

De function calls i main er der kun for at illustrtere hvordan
funktionen virker.

argc/argv er ikke nødvendige, da vi ikke bruger nogle argumenter,
men mange C/C++ programmører taster dem altid ind.
Avatar billede arne_v Ekspert
30. januar 2003 - 11:20 #13
Hvor læser du henne ?
Avatar billede siul Nybegynder
30. januar 2003 - 11:33 #14
Jeg laeser i USA, hvorfor jeg ikke altid oversaetter til ren dansk. Detter er dog ikke for at vaere smart - det er jo aldrig et sundt tegn ikke at kunne huske sit eget sprog :-) Jeg er meget nybegynder som du kan se, begyndte sidste aar, men kom ud for en ulykke saa jeg er tilbage fra bunden. Kommer formentlig snart til Danmark igen.

Programmet koerer jo fint, men er i tvivl om finessen med at output skal jeg skrive et program der laeser en long integer fra standard input og vil output en tabel til en disk file der indeholder base 2,3,...,16 representation af input integer og ceiling af log base 2,3,...,16 af en integer.

Vil det sige at jeg skal aabne en output file som kunne vaere saaledes:
for at aable filen:

#include <iostream>
#include <fstream>
ofstream outfile;
outfile.open(resultater");

For at lukke filen:

#include <iostream>
#include <fstream>
#include <cassert>

ofstream outfile;
outfile.open(resultater");
assert(outfile);

hvad der skal bruges til outfile....
outfile.close();

Vil det sige at jeg skal oprette en fil der hedder "resultater" og saette det ind som skal bruges til output, eller hvordan foregaar den disk file??

Vil selvfoelgelig gerne donere flere points til dig, da jeg jo har gjort dette en stor omgang.
Avatar billede arne_v Ekspert
30. januar 2003 - 12:03 #15
Noget i retning af:

#include <iostream>
#include <fstream>

using namespace std;

ofstream outf("resultat.dat");

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void calc(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  outf << n << " = ";
  for(int i=k-1;i>=0;i--) {
      outf << c[a[i]];
  }
  outf << " base " << b << " og oprundet LOG" << b << " = " << k << endl;
  return;
}

int main(int argc, char *argv[])
{
  int n,b;
  cout << "Indtast tal: ";
  cin >> n;
  cout << "Indtast base: ";
  cin >> b;
  calc(n,b);
  return 0;
}
Avatar billede arne_v Ekspert
30. januar 2003 - 12:04 #16
200 point er helt fint.

(og det er iøvrigt slet ikke tilladt at give flere point i henhold
til ekspertens regler)
Avatar billede siul Nybegynder
31. januar 2003 - 09:50 #17
Hej Arne,
Opgaven er ikke helt loest i henhold til problemformuleringen. Jeg skal indlaese en positiv long integer fra standard input programmet vil saa output en tabel med base representation af input integer og ceiling af log base 2,3..16 af integeren.
I henhold til logaritmen (som jeg skrev i mit foerste indlaeg)skal jeg have en function der hedder OutputBaseBValue (a,k,b).
den positive long integer kunne vaere den som prompter brugeren for "indtast et tal", men hvordan kommer OutputBaseBValue ind i billedet?
Hvorfor har du valgt at indsaette 11,i i dit functions kald (jeg forstaar godt i)?
Avatar billede arne_v Ekspert
31. januar 2003 - 10:44 #18
testing
Avatar billede arne_v Ekspert
31. januar 2003 - 10:45 #19
Jeg tror Eksprten har et teknisk problem.

Men jeg prøver igen.
Avatar billede arne_v Ekspert
31. januar 2003 - 10:46 #20
De 11 var bare et eksempel for at illustrere de forskellige
tal-systemer.
Avatar billede arne_v Ekspert
31. januar 2003 - 10:48 #21
#include <iostream>
#include <fstream>

using namespace std;

ofstream outf("resultat.dat");

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void BaseConversion(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  OutputBaseBValue(a,k,b);
  return;
}

void OutputBaseBValue(int *a,int k,int b)
{
  outf << n << " = ";
  for(int i=k-1;i>=0;i--) {
      outf << c[a[i]];
  }
  outf << " base " << b << " og oprundet LOG" << b << " = " << k << endl;
  return;
}

int main(int argc, char *argv[])
{
  int n,b;
  cout << "Indtast tal: ";
  cin >> n;
  cout << "Indtast base: ";
  cin >> b;
  BaseConversion(n,b);
  return 0;
}
Avatar billede siul Nybegynder
31. januar 2003 - 11:14 #22
saa blev mit indlaeg vist slettet??
Avatar billede siul Nybegynder
31. januar 2003 - 11:23 #23
Ok, jeg proever igen saafremt det sidste indlaeg blev slettet.
Jeg fik dit program, compilede det og aendrede lidt, da der var lidt fejl med at den nye function Output...ikke var defineret.
Jeg proevede at lave en fil med navnet "result.dat.cpp" for at se output, men det virkede ikke. Lige nu kan jeg kun se:
Indtast tal: 2 (2 som jeg selfoelgelig indtastede)
Indtast base: 2(2 som jeg selfoelgelig indtastede)
Press any key to continue

dette er programmet som jeg compilede:
#include <iostream>
#include <fstream>

using namespace std;
void BaseConversion(int, int);
void OutputBaseBValue(int *,int ,int );

ofstream outf("resultat.dat");

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};


int main(int argc, char *argv[])
{
  int n,b;
  cout << "Indtast tal: ";
  cin >> n;
  cout << "Indtast base: ";
  cin >> b;
  BaseConversion(n,b);
  return 0;
}
void BaseConversion(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  OutputBaseBValue(a,k,b);
  return;
}

void OutputBaseBValue(int *a,int k,int b)
{
 
  for(int i=k-1;i>=0;i--) {
      outf << c[a[i]];
  }
  outf << " base " << b << " and ceiling of LOG" << b << " = " << k << endl;
  return;
}
Avatar billede arne_v Ekspert
31. januar 2003 - 19:09 #24
Jeg prøver for femte gang.

Når du kører programmet skulle der ligge en fil resultat.dat med
output.
Avatar billede arne_v Ekspert
01. februar 2003 - 16:30 #25
Har du fundet filen ?
Avatar billede siul Nybegynder
01. februar 2003 - 20:49 #26
Nej, jeg har ikke fundet filen. Det var en hjemmeopgave som jeg afleverede igaar. Min laerer kiggede paa det og opgaven er desvaerre ikke loest. Pointen var at programmet skulle indlaese en long int og udprinte en tabel som denne ved hjaelp af logaritmen jeg skrev tidligere:
Base    Value    C log (ceiling af log)
2        1000      4
3        121      3
4        100      2
etc      etc      etc.

Det er grunden til at jeg blev ved med at spoerge. Jeg saetter selvfoelgelig stor pris paa din hjaelp men vil lade spoergsmaalet staa, hvis der er en der kommer forbi paa siden der kan loese problemet.
Avatar billede arne_v Ekspert
01. februar 2003 - 21:27 #27
Når jeg kører dit program så ligger den en fil resultat.dat i
current directory med indhold som:

Indtast tal: 10
Indtast base: 8

C:\>type resultat.dat
12 base 8 and ceiling of LOG8 = 2

Hvilket er korrekt i forhold til algoritmen.

Hvis du vil have for alle base så skal der ikke spørges om base men
bare loopes:

#include <iostream>
#include <fstream>

using namespace std;
void BaseConversion(int, int);
void OutputBaseBValue(int *,int ,int );

ofstream outf("resultat.dat");

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};


int main(int argc, char *argv[])
{
  int n,b;
  cout << "Indtast tal: ";
  cin >> n;
  for(int b=2;b<=16;b++) {
    BaseConversion(n,b);
  }
  return 0;
}
void BaseConversion(int n,int b)
{
  int a[33];
  int q = n;
  int k = 0;
  while(q!=0) {
      a[k]=q%b;
      q=q/b;
      k++;
  }
  OutputBaseBValue(a,k,b);
  return;
}

void OutputBaseBValue(int *a,int k,int b)
{

  for(int i=k-1;i>=0;i--) {
      outf << c[a[i]];
  }
  outf << " base " << b << " and ceiling of LOG" << b << " = " << k << endl;
  return;
}

Og det giver følgende indhold af resultat.dat:

Indtast tal: 10

C:\>type resultat.dat
1010 base 2 and ceiling of LOG2 = 4
101 base 3 and ceiling of LOG3 = 3
22 base 4 and ceiling of LOG4 = 2
20 base 5 and ceiling of LOG5 = 2
14 base 6 and ceiling of LOG6 = 2
13 base 7 and ceiling of LOG7 = 2
12 base 8 and ceiling of LOG8 = 2
11 base 9 and ceiling of LOG9 = 2
10 base 10 and ceiling of LOG10 = 2
A base 11 and ceiling of LOG11 = 1
A base 12 and ceiling of LOG12 = 1
A base 13 and ceiling of LOG13 = 1
A base 14 and ceiling of LOG14 = 1
A base 15 and ceiling of LOG15 = 1
A base 16 and ceiling of LOG16 = 1

Jeg kan ikke forstå, at du ikke får en fil resultat.dat - og jeg kan
ikke se at der skulel være noget galt me dudregningen.
Avatar billede siul Nybegynder
02. februar 2003 - 09:24 #28
Ja, det ser bestemt ud som om det virker.
Jeg siger mange tak for din hjaelp og taalmodighed som jeg saetter stor pris paa :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester