Προς το περιεχόμενο

Αλγοριθμος για την μετατροπη string σε integer


takis39

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπερα, θελω να φτιαξω ενα αλγοριθμο για την μετατροπη string σε int. O καθηγητης μας εδωσε τον παρακατω κωδικα ως παραδειγμα με χρηση της βιβλιοθηκης gnu mp:

 

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

#include "gmp.h"

/* Arithmos xarakthron*/
#define BASE 256 

/* Max megethos string*/
#ifndef MAXLEN
#define MAXLEN 256
#endif

/* Sunarthsh Metatrophs string se akeraio*/
void str_int(mpz_t r, char *string)
{
       long int str_len, i;
       unsigned char c;

       
       str_len = strlen(string);	// apothikeush tou megethous tou strinh sth metablhth str_len
       if(string[str_len - 1] == '\n')
               string[str_len - 1] = '\0';
       str_len = strlen(string);

  printf("%s -> %ld \n", string, str_len);

       /* r = 0 */
       mpz_set_ui(r, 0UL);

       
       for(i = str_len - 1; i >= 0; i--)
       {
               c = string[i];

               
               mpz_mul_ui(r, r, (unsigned long)BASE); // r=r*BASE
               mpz_add_ui(r, r, (unsigned long)c);    // r=r+c
       }
}

/* Sunarthsh Metatrophs akeraiou se string*/

void int_str(char *string, mpz_t org_str_int)
{
       long int str_len, i;
       mpz_t max_int, c_int, str_int;

       /* Arxikopoihsh */
       mpz_init(max_int);
       mpz_init(c_int);
       mpz_init(str_int);

       mpz_set(str_int, org_str_int); 	// ekxorei sthn metablhth str_int thn metablhth org_str_int


       /* megethos tou string */

       mpz_set_ui(max_int, 1UL);
       for(i = 0; i < MAXLEN; i++)
       {

               if(mpz_cmp(str_int, max_int) <= 0)
               {
                       str_len = i;
                       break;
               }

               mpz_mul_ui(max_int, max_int, (unsigned long)BASE);
       }

       /* metatroph grammaton */
       for(i = 0; i < str_len; i++)
       {
               mpz_mod_ui(c_int, str_int, (unsigned long)BASE);	// ekxoreitai sthn metablhth c_int=str_int mod BASE
               mpz_sub(str_int, str_int, c_int);			// ekxoreitai sthn metablhth str_int=str_int+c_int
               mpz_tdiv_q_ui(str_int, str_int, (unsigned long)BASE);

               string[i] = mpz_get_ui(c_int);
       }
       string[str_len] = '\0';

      printf("Arithmos Xarakthron --> %ld\n", str_len);

       /* apodesmeush xorou mnhmhs */
       mpz_clear(max_int);
       mpz_clear(c_int);
       mpz_clear(str_int);
}


int main()
{
       unsigned char string[MAXLEN], out_string[MAXLEN];
       mpz_t string_int, string_int_kry;

/* Arxikopoihsh */
       mpz_init(string_int);
       mpz_init(string_int_kry);

 /* Eisagogh Munhmatos */
       printf("Grapse to mhnuma sou(Mexri  %d xarakthres) !!!! :", MAXLEN);
       fgets(string, MAXLEN - 1, stdin);


       /* Metatroph string se akeraio arithmo*/
       str_int(string_int, string);


#ifdef HEX
       gmp_printf("string(%d)  -> %Zx\n\n", strlen(string), string_int);
#else
       gmp_printf("string(%d)  -> %Zd\n\n", strlen(string), string_int);
#endif


     /* Metatroph Akeraiou arithmou se string*/
       int_str(out_string, string_int);

#ifdef HEX
       gmp_printf("\n%Zd\n          ---> %s   (%d)\n", string_int, out_string, strlen(out_string));
#else
       gmp_printf("\n%Zd\n          ---> %s   (%d)\n", string_int, out_string, strlen(out_string));

#endif

       /* Apodesmeush xorou mnhmhs */
       mpz_clear(string_int);
       mpz_clear(string_int_kry);

     return 0;
}

 

Επειδη τωρα εχω αρχισει να ασχολουμε με τον προγραμματισμο, μηπως εχεις καποιος την υπομονη να μου εξηγησει πως λειτουργει το παραπανω προγραμμα, και πως ακριβως γινεται η μετατροπη, για να φτιαξω και εγω την δικη μου εκδοχη? Εαν ειναι χρονοβορο αυτο που ζηταω η δυσκολο, τουλαχιστον θα μπορουσαμε να μου λυσετε καποιες αποριες σχετικα με ορισμενες εντολες? Π.Χ, τι ακριβως κανει η εντολη #ifndef MAXLEN - #endif ?

 

Υ.Σ Δεν ζητω ετοιμο κωδικα

 

Ευχαριστω για την οποια βοηθεια

Δημοσ.

τι ακριβως κανει η εντολη #ifndef MAXLEN - #endif ?

 

Πολύ συνοπτικά, μπορείς να το δείς σαν ένα if. Εννοεί ο ποιητής, πως αν δεν έχει οριστεί το MAXLEN σε καποιο αρχείο, τότε το ορίζει εκεί ώστε να έχει την τιμή 256. Δεν είναι όμως μεταβλητή. Απλά, όπου στο πρόγραμμα υπάρχει το string MAXLEN θα αντικατασταθεί από τον ακέραιο 256.

Δημοσ.
Πολύ συνοπτικά, μπορείς να το δείς σαν ένα if. Εννοεί ο ποιητής, πως αν δεν έχει οριστεί το MAXLEN σε καποιο αρχείο, τότε το ορίζει εκεί ώστε να έχει την τιμή 256. Δεν είναι όμως μεταβλητή. Απλά, όπου στο πρόγραμμα υπάρχει το string MAXLEN θα αντικατασταθεί από τον ακέραιο 256.

 

ευχαριστω πολυ για την απαντηση. Μηπως μπορεις να μου πεις τι γινεται σε αυτο το σημειο του κωδικα?

 

>str_len = strlen(string);	// apothikeush tou megethous tou strinh sth metablhth str_len
       if(string[str_len - 1] == '\n')
               string[str_len - 1] = '\0';
       str_len = strlen(string);

Δημοσ.
ευχαριστω πολυ για την απαντηση. Μηπως μπορεις να μου πεις τι γινεται σε αυτο το σημειο του κωδικα?

 

>str_len = strlen(string);	// apothikeush tou megethous tou strinh sth metablhth str_len
       if(string[str_len - 1] == '\n')
               string[str_len - 1] = '\0';
       str_len = strlen(string);

 

Επειδή στη συνάρτηση main διαβάζει το string με την fgets, υπάρχει περίπτωση ο τελευταίος χαρακτήρας του string να είναι ο newline χαρακτήρας '\n'. Για περισσότερες πληροφορίες δές την τεκμηρίωση της fgets. Αυτός όμως δε θέλει να τον κρατήσει τον χαρακτήρα αυτό, και βάζει στη θέση του το '\0'.

Δημοσ.

>str_len = strlen(string);	// apothikeush tou megethous tou strinh sth metablhth 
str_len
       if(string[str_len - 1] == '\n')
               string[str_len - 1] = '\0';
       str_len = strlen(string);

 

Εστω ότι x = "abcd";

η strlen(x) επιστρέφει σαν ακέραιο αριθμό το μήκος του αλφαριθμητικου x (δηλαδή 4)

το x έχει δηλαδη είναι πίνακας με χαρακτήρες απο τη θέση 0 έως τη θέση strlen(x)-1 (δηλαδή απο x[0] εως χ[3])

στη θέση strlen(x) υπάρχει ο ειδικός χαρακτηρας NUL (δηλαδή αριθμητική τιμή 0 ή '\0')

Το '\n' είναι ο χαρακτηρας αλλαγης γραμμης.

 

Ο έλεγχος if(string[str_len - 1] == '\n') ελεγχει αν ο τελευταιος χαρακτηρας στο αλφαριθμητικο string είναι αλλαγη γραμμής και αν είναι

string[str_len - 1] = '\0'; τον σβήνει βάζοντας το NUL (δηλαδη κοντένοντας το string) γι'αυτο και το ξαναυπολογισζει μετά (έχει μειωθει κατα 1)

Δημοσ.

Νομίζω πως το να κάνεις μετατροπή String σε Integer είναι κάτι πολύ απλό και όχι με τον τρόπο αυτόν.

 

Μια function έιναι που παίρνει ένα ένα τα στοιχέια του String βάζει το πρώτο σε μια ακέραια μεταβλητή και στην συνέχεια για κάθε ένα απο τα υπόλοιπα πολλαπλασιάζει τον αριθμό επι δέκα και προσθέτει τον νέο. Χρειάζεται μόνο ένα case για τους αριθμούς και ένας έλεγχος για μη αποδεκτούς χαρακτήρες.

ΠΧ

String "123"

Number=1

Number=Number*10+2 = 12

Number=Number*10+3 = 123

 

Πάνω κάτω ο αλγόριθμος είναι αυτός.

Τσεκάρεις αν ο πρώτος χαρακτήρας είναι - όποτε πολλαπλασιάζεις τον αριθμό στο τέλος επι -1.

Και απλά η function γυρνά έναν ακέραιο.

Δημοσ.

Καταρχην ευχαριστω για τις απαντησεις. Προσπαθησα να κανω την αντικαταστήση με την αλλα δεν μου παιζει. δεν μου βγαζει μηνυμα λαθους αλλα το απουελεσμα ειναι:

 

Grapse to mhnuma sou(Mexri 256 xarakthres) !!!! : takis /* το μηνυμα που δινω*/

string(6) -> 0

 

Arithmos Xarakthron --> 0

 

0

---> (0)

 

Αυτο γιατι γινεται?

 

2) Μπορεις να μου πεις ο πιο ευκολος τροπος πως υλοποιειται?

 

3) Φιλε C6WGMN, εαν εχεις ασχοληθει με την gmp, μπορεις να μου εξηγησεις τι κανει ο παρακατω κωδικας?

 

>/* r = 0 */
       mpz_set_ui(r, 0UL);

      
       for(i = str_len - 1; i >= 0; i--)
       {
               c = string[i];

              
               mpz_mul_ui(r, r, (unsigned long)BASE); // r=r*BASE
               mpz_add_ui(r, r, (unsigned long)c);    // r=r+c
       }
}

 

Συμφωνα με το manual της gmp:

 

The space will not be automatically increased, unlike the normal mpz_init, but instead an application must ensure it’s sufficient for any value stored. The following space requirements apply to various functions,

• mpz_set_ui need room for the value they store.

• mpz_add_ui need room for the larger of the two operands, plus an extra mp_bits_per_limb.

• mpz_mul_ui need room for the sum of the number of bits in their operands, but each rounded up to a multiple of mp_bits_per_limb.

 

Μολις εχθες διαβασα για πρωτη φορα πινακες, εχω χαθει εντελως εαν μπορεις εξηγησε μου :(

Δημοσ.

Εγώ έλεγα κάτι τέτοιο

 

int string_int(char* string_val)

{

int number_val=0;

int temp=0;

int pos = 0;

char negative = 'N';

int str_length=strlen(string_val);

if (string_val[pos] == '-')

{

negative = 'Y';

pos = pos + 1;

}

char cr;

for (int lo=pos;lo<=str_length-1;lo++)

{

cr=string_val[lo];

switch (cr){

case '1': temp=1; break;

case '2': temp = 2; break;

case '3': temp = 3; break;

case '4': temp = 4; break;

case '5': temp = 5; break;

case '6': temp = 6; break;

case '7': temp = 7; break;

case '8': temp = 8; break;

case '9': temp = 9; break;

case '0': temp = 0; break;

default: //error here; μη αποδεκτός χαρακτήρας

}

 

number_val = number_val * 10 + temp;

 

}

if (negative == 'Y') number_val = number_val * -1;

return number_val;

}

 

Μπορεί να μου ξεφεύγει κανένας έλεγχος αυτή την στιγμή (ΠΧ μην βάλει κανέναν πολύ μεγάλο αριθμό, το String είναι κενό κτλ) είναι ένας απλός τρόπος όμως και χρησιμοποιείς πολύ απλά εργαλεία. Βέβαια δεν ξέρω τι θέλει ο καθηγητής σου. Η function αφορά μετατροπή char * σε int. Α και ο κώδικας μπορεί να γραφτεί και πιο όμορφα... οπότε παίξε μπάλα..

Δημοσ.

Δεν χρειάζεται καν το switch-case. Μπορείς να χρησιμοποιήσεις αριθμητική χαρακτήρων. Αν π.χ. ch είναι ο χαρακτήρας (ψηφίο) με το οποίο ασχολείσαι αυτή τη στιγμή και val ένας ακέραιος, μπορείς να κάνεις

val = ch - '0';

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...