0 Daumen
339 Aufrufe

Eine Zahl wird als langweilig bezeichnet, wenn sie nicht in der Online-Enzyklopädie der Zahlenfolgen enthalten ist.
Gegeben ist die Zeichenkette s = 'Zur Zeit ist 14972 die kleinste langweilige Zahl.'.

Extrahieren Sie die Zahl 14972 aus s und wandeln Sie sie in eine binäre Zahl um. Erstellen Sie eine String-Ausgabe, die wie folgt aussieht:

Dezimal: 14972
Binär: 11101001111100

Geben Sie diese Zeichenkette mit print(ausgabe) aus. Schreiben Sie dabei die beiden Zahlen nicht als Literale in den Code, sondern setzen Sie den String aus den berechneten Werten zusammen. Unterteilen Sie auch diese Aufgabe wieder sinnvoll in Code- und Textzellen.

Avatar von

1 Antwort

0 Daumen

Hallo:-)

Man kann das Extrahieren der Zahl 14972 aus dem String s = 'Zur Zeit ist 14972 die kleinste langweilige Zahl.' darauf verallgemeinern:

Extrahiere die Zahl \(z\) aus dem String s = 'Zur Zeit ist \(z\) die kleinste langweilige Zahl.'

Ich gehe zunächst mal davon aus, dass du nur mit nichtnegativen ganzen Zahlen arbeitest. Im Prinzip gehst du dabei den String s durch und prüfst jedes Zeichen darauf, ob es eine ganze Zahl ist. Das was einer Zahl in S entspricht fügst du an einem externen String (ich nenne ihn mal) \(count\) an.

Ansonsten musst nur noch deine Dezimalzahl in eine Binärzahl umwandeln.

Avatar von

Hallo Allerseits!

Strings kann man auf verschiedene Weise in ihre Einzelteile aufteilen. Dabei hat man zum Beispiel die Funktion sscanf(in stdio.h) zur Verfügung:

#include <stdio.h>
#include <string.h>


void DEZUBI( unsigned int zahl, char zudi[])                                                    /*22:16 */
{
char wort[35], worz[35];
int slei, sleib;
unsigned int dum2, testwert, kon = 1;

for (slei = 0; slei <= 34; slei++)                                                       
wort[slei] = worz[slei] = '\0';                                                         

kon <<= 31 ;

for (slei = 0; slei <= 31; slei++)
{             
testwert = kon >> slei;  /* Bit30(1073741824dez) ist auf Char-Nr.0 */
dum2 = zahl & testwert;
if (dum2)  wort[slei] = '1';
  else   wort[slei] = '0';
}

for (slei = 0; slei <= 31; slei++)
if (wort[slei] == '1') break;

for (sleib = 0; sleib <= 32; sleib++)
      {
      worz[sleib] = wort[slei];
      if (wort[slei] == '\0')
        break;
      slei++;
      }

for (slei = 0; slei <= 32; slei++)
zudi[slei] = worz[slei]; /* ohne Vornullen */
}

int main(int argc, char **argv)
{
int laenge = 0, i;
char satz[] = "Zur Zeit ist 14972 die kleinste langweilige Zahl.";
char strarray[8][48] = {0};
char binzahl[34] = {0};
int zahl = 0;

laenge = strlen(satz);
printf("Satz urspruenglich:\n%s\n", satz);
printf("Laenge in Byte: %d\n", laenge);
sscanf(satz, "%s%s%s%d%s%s%s%s", strarray[0],strarray[1],strarray[2],&zahl,strarray[4],strarray[5],strarray[6],strarray[7]);
printf("\nProbe:\n");

for (i = 0; i < 3; i++) printf("%s ", strarray[i]);
printf("%d ",zahl);
for (i = 4; i < 8; i++) printf("%s ", strarray[i]);
 
DEZUBI(zahl, binzahl);
printf("\nZahl dezimal: %d\nZahl binaer : %s\n", zahl, binzahl);

}

Die Funktion 'DEZUBI' wandelt dabei die Dezimalzahl in einen String um.

Dabei ist es wichtig was für einen Prozessor man vor sich hat. Bei ganz alten Boards 16 Bit, was eigentlich nur in einigen Steuerungen vorkommt. Dann noch 32Bit-Prozessoren und die 64-Bit-Brozessoren. Bei den alten Betriebssystemen kommt es dann darauf an, ob jetzt das Programm für den real mode oder den protected mode geschrieben wurde. Solche alte Compiler für DOS haben für den Datentyp int nur 16Bit, also 2 Byte zur Verfügung. Das sollte man dann mal kontrollieren wie lange welcher Datentyp ist.

Dazu habe ich für meine Linux-System mit 64-Bit auf gcc und codelite folgendes kleines Programm gezimmert:

#include <iostream>
//#include <stdio.h>
#include <cstdlib>
#include <limits.h>
#include <float.h>

int main(int argc, char** argv) {

long double ulle;
__uint128_t testv;
  std::cout << std::endl << "Länge der Datentypen\nund deren Wertebereiche V0.21" << std::endl << std::endl;
  std::cout << "char..........: " << sizeof(char) << " Byte in Bit: " <<  CHAR_BIT << std::endl;
  std::cout << "signed char...: " << CHAR_MAX << "  bis " << CHAR_MIN << std::endl;
std::cout << "unsigned char.: 0  bis " << UCHAR_MAX << std::endl << std::endl;
//printf("SCHAR_MAX : %d\n", SCHAR_MAX);
  //printf("SCHAR_MIN : %d\n", SCHAR_MIN);
std::cout << "short........: " << sizeof(short) << "Byte" << std::endl;

  std::cout << "SHRT_MAX   : " << SHRT_MAX << std::endl;
  std::cout << "SHRT_MIN   : " << SHRT_MIN << std::endl;
 
  std::cout << "USHRT_MAX   : " << USHRT_MAX << std::endl << std::endl;

  std::cout << "Datentyp int   " << sizeof(int) << " Byte" << std::endl;
std::cout << "INT_MAX   : " << INT_MAX << std::endl;
  std::cout << "INT_MAX   : " << INT_MIN << std::endl;
 
  std::cout << "UINT_MAX   : " << UINT_MAX << std::endl;
std::cout << std::endl << "long       : " << sizeof(long) << " Byte" << std::endl;
  std::cout << "LONG_MAX   : " << LONG_MAX << std::endl;
  std::cout << "LONG_MIN   : " << LONG_MIN << std::endl;
std::cout << "ULONG_MAX : " << ULONG_MAX << std::endl<< std::endl;

  std::cout << "float     : " << sizeof(float) << " Byte" << std::endl;
std::cout << "FLT_MAX   : ±" << std::fixed << FLT_MAX << std::endl;
  std::cout << "FLT_MAX   : ±" << std::scientific << FLT_MAX << std::endl;
std::cout << "FLT_MIN   : " <<  FLT_MIN << std::endl;
std::cout << "FLT_DIG   : " <<  FLT_DIG << std::endl;

  std::cout << std::endl << "double     : " << sizeof(double) << " Byte" << std::endl;
//printf("DBL_MAX   : %lf\n", DBL_MAX);
std::cout << "DBL_MAX   : ±" << DBL_MAX << std::endl;
std::cout << "DBL_MIN   : " << DBL_MIN << std::endl;
std::cout << "DBL_DIG   : " << FLT_DIG << std::endl;
 
  std::cout << std::endl << "Datentyp long double: " << sizeof(long double) << " Byte" << std::endl;
  std::cout << "LDBL_MIN   : " << LDBL_MIN << std::endl;
  std::cout << "_DBL_MAX   : " << LDBL_MAX << std::endl;
std::cout << "LDBL_DIG   : " << LDBL_DIG << std::endl;
 
     
  std::cout << std::endl << "Long long int " << sizeof(long long int) << " Byte" << std::endl;
  std::cout << "Long long int min: " <<  LLONG_MIN << std::endl;
  std::cout << "Long long int max: " <<  LLONG_MAX << std::endl;
 
  std::cout << std::endl << "Long long uint " << sizeof(long long int) << " Byte" << std::endl;
  std::cout << "Long long uint max: " << ULLONG_MAX << std::endl;
 
  ulle = (long double) ULLONG_MAX;
  printf("\nLong long uint max: %LE\n", ulle);

  std::cout << std::endl <<"__uint128_t laenge: " << sizeof(testv) << " Byte" << std::endl;

  return EXIT_SUCCESS;
}

Da könnt Ihr dann kontrollieren wie lange welcher Typ ist und was für ein Datenbereich er hat.

Beide Programme und alle Sourcen hier stelle ich unter GPL-Lizenz.

Bei der Funktion DEZUBI prüfe ich mit dem Bitoperand '&' ob ein Bit gesetzt ist oder nicht. Dazu setze ich zunächst den Prüfwert der Zahl auf eins und schiebe dann den Wert um 31 Bit nach links. Dann ist beim Prüfwert nur das höchste Bit gesetzt. Nach und nach wird wenn jedes Bit einzeln getestet wird, der Wert wieder nach rechts verschoben um den richtigen Prüfewert für das jeweilige Bit zu haben. Ist der Wert ungleich Null so wird im String der nachher die binäre Zahl beiinhaltet eine eine 1 gesetzt, sonst eine Null.

Einige Compiler hatten dazu in den 90ern, wie etwa Symantec c++7.0 eine extra Funktion BCD genannt, die eine Dezimalzahl als Integerwert darstellte. Da es aber zu Verwechslungen kommen kann, sollte man mit so etwas vorsichtig sein:

unsigned int bcd(unsigned int dezimalwert)
{
unsigned int slei, bitwert, testwert, dumsm, rewer;

testwert = 1 << 7;
bitwert = 0;
dumsm = 1;
rewer = 0;

for (slei = 0; slei <= 7; slei++)
{
bitwert = dezimalwert & testwert;
testwert >>= 1;
if (bitwert) rewer += dumsm;
dumsm *= 10;
}


return rewer;
}

Diese ist meine eigene Version. Wiederum unter GPL-Lizenz. Hier der Vollständigkeit halber zum experimentieren. Der Vorteil dieses Verfahrens liegt in der Länge der benötigten Variablen. Um einen 8-Bit-Wert in c darzustellen benötige ich mindestens ein char-Array von 9 Byte Länge, da ja in c Strings Nullterminiert sind. Es gilt also Länge der darzustellenden Dezimalzahl in bit + 1 = Länge des char-Arrays in Byte. Bei der Darstellung von unsigned char sind es hier nur 4 Byte für unsigend int.

Bei der Funktion bcd sollte man eigentlich immer unsigned long als Rückgabewert verwenden um eine Dezimalzahl in binärer Form darzustellen. Hier eine Version nur für die Darstellung von unsigend char als binäre Zahl. Ansonsten muss obere Funktion dementsprechend modifiziert werden.

Die Ausgabe der ursprünglich gestellten Aufgabe mit meinem Beispiel ist folgende:

Satz urspruenglich:
Zur Zeit ist 14972 die kleinste langweilige Zahl.
Laenge in Byte: 49

Probe:
Zur Zeit ist 14972 die kleinste langweilige Zahl.
Zahl dezimal: 14972
Zahl binaer : 11101001111100
Hit any key to continue...

In einem englisch-sprachigen Forum hatte ich mal dieses Beispiel rein gestellt:

// splits a String into several parts
#include <stdio.h>  //printf
#include <stdlib.h> //atoi EXIT_SUCCESS
#include <string.h> // strcpy, strtok

// argument 1(*var)= strint to split
// argument 2=delimiter
// argument 2 = 2 dimensional array where the tokens are copied
// Return-Value: number of tokens where found
int mixed(char *var, char *delimiter, char numbers[20][30])
{

printf ("the delimiter is: %s(space)\nTokens:\n", delimiter);

int retval = 0, i = 0;
char * d;
d = strtok (var, delimiter);

while (d != NULL)
{
  strcpy(numbers[i], d);
printf ("i: %2d     String: %s\n", i, numbers[i]);
  i++;
d = strtok (NULL, delimiter);
retval++;
}

return retval;
}

int main(int argc, char **argv)
{
char test[] = {"60 10 Winston Charly John 44 67 Henry 0 Mary-Jane_Lovley"};
char delimiter[] = " ";
char numbers[20][30] = {0};
int ival = 0, i,j, result_a, sum = 0;

printf ("String to split ino tokens:\n%s\n\n", test);
result_a =mixed(test, delimiter, numbers);


printf ("\nNumber of tokens: %d\n-----tokens splited into characters-------\n", result_a);
for (i = 0; i < result_a; i++)
{
printf("i: %2d   ", i);
for (j = 0; j < 30; j++)
  printf(" %c ", numbers[i][j]);
printf("\n");
}
printf ("-----tokens converted into int-values------\n");

for (i = 0; i < result_a; i++)
{
  ival = atoi(numbers[i]);
  sum += ival;
printf("ival: %d\n", ival);
}
 
printf("\nsum of all int-values: %d\n\n", sum);

return EXIT_SUCCESS;
}

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community