Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2398 connectés 

  FORUM HardWare.fr
  Programmation

  C-Convertion chaine - Algo liste chaînée ordonnée -Fonction qui enlève

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

C-Convertion chaine - Algo liste chaînée ordonnée -Fonction qui enlève

n°112972
merou91
Team Fallback !!
Posté le 17-03-2002 à 11:31:14  profilanswer
 

J'aurai besoin de convertir un chaîne qui contient des chiffres et plusieurs caractères '.' de ce type : "192.135.1.1"
 
Si je fais :  
 
sscanf(ip,"%f",&a) -> a=192.135 (a float)
a=strtod(ip,NULL)  -> a=192.13500000000 (a double)
 
Le but est d'obtenir un chiffre unique pour une adresse IP donnée afin de ranger ces adresses par ordre dans une liste. Parce que je me vois mal faire l'algo de rangement sur les 4 octets de l'adresse IP.

 

[jfdsdjhfuetppo]--Message édité par merou91--[/jfdsdjhfuetppo]

mood
Publicité
Posté le 17-03-2002 à 11:31:14  profilanswer
 

n°112980
merou91
Team Fallback !!
Posté le 17-03-2002 à 11:53:20  profilanswer
 

Je viens de penser à un truc, y aurai moyen de faire ca :
"192.168.0.1" -> 192168000001 ?
Je peux récupérer les 4 digits avec sscanf(ip,"%ld.%ld.%ld.%ld",&a,&b,&c,&d)
 
Mais alors comment forcer ces nombres à avoir 3 chiffres cad transformer 3 en 003, 12 en 012 ?
Et finalement comment obtenir le nombre final concatenation des 4 nombres ?

n°112985
Tentacle
Posté le 17-03-2002 à 12:02:01  profilanswer
 

merou91 a écrit a écrit :

Je viens de penser à un truc, y aurai moyen de faire ca :
"192.168.0.1" -> 192168000001 ?
Je peux récupérer les 4 digits avec sscanf(ip,"%ld.%ld.%ld.%ld",&a,&b,&c,&d)
 
Mais alors comment forcer ces nombres à avoir 3 chiffres cad transformer 3 en 003, 12 en 012 ?
Et finalement comment obtenir le nombre final concatenation des 4 nombres ?  




 
sprintf ?

n°112986
merou91
Team Fallback !!
Posté le 17-03-2002 à 12:12:49  profilanswer
 

Tentacle : tu peux m'en dire un peu plus svp.
 
Sinon je viens de voir que inet_addr() transforme normalement une chaine de caractère contenant une @IP en un long mais je n'arrive pas à l'utiliser :  
unsigned long l;
char *ip="192.168.0.1";
l=inet_addr(ip);
 
donne l = 16820416 ?

n°112987
Tentacle
Posté le 17-03-2002 à 12:16:21  profilanswer
 

merou91 a écrit a écrit :

Tentacle : tu peux m'en dire un peu plus svp.
 
Sinon je viens de voir que inet_addr() transforme normalement une chaine de caractère contenant une @IP en un long mais je n'arrive pas à l'utiliser :  
unsigned long l;
char *ip="192.168.0.1";
l=inet_addr(ip);
 
donne l = 16820416 ?  




 
printf permet de formatter une chaîne en lui disant  par exemple d'afficher un nombre sur 3 chiffres. sprintf fait la même chose mais on peut en récupérer le résultat dans une string.
Regarde dans de la doc pour la syntaxe exacte parce que je ne me rappelle plus des détails... au fait c'est bien du C ? spécifie ton language dans le nom du post stp :)

n°112988
HappyHarry
Posté le 17-03-2002 à 12:17:47  profilanswer
 

ben tu l'as dit toi meme .. une ip c un nombre sur 4 octets ...
donc 192.168.0.1 =  
192<<24 + 168<<16 + 0<<8 + 1 ...
 
la conclusion tu la tireras toi meme ...

n°112989
merou91
Team Fallback !!
Posté le 17-03-2002 à 12:22:27  profilanswer
 

happyharry j'ai rien capté à ta comparaison de chiffres ?

n°112994
HappyHarry
Posté le 17-03-2002 à 12:38:59  profilanswer
 

c des decalages ... 'fin bref ...
tu sais compter en base 2 ?
 
les adresses ip c des long, jusque la on est d'accord ?
la représentation sous forme de chaine, c la valeur de chacun des 4 octets qui composent le long, séparées par des points
 
si tu veux la valeur 'numérique' d'une adresse ip, en la calculant toi meme comme un grand, pour ta culture personnelle tu fais
 
premier octer * 2 puissance 24  
+ deuxieme octet * 2 puissance 16
+ troisieme octet * 2 puissance 8
+ quatrieme octet
 
m'enfin c clair que inet_addr ca va plus vite  :)  
 
reste juste a voir selon quels criteres tu veux les classer tes adresses

n°112999
merou91
Team Fallback !!
Posté le 17-03-2002 à 12:47:35  profilanswer
 

Je voudrais la triller par ordre croissant ou décroissant d'@IP. Faut que je regarde quelles sont les @ les plus fréquentes pour savoir si elles sont plutôt grande ou petite ce qui me permettra de choisir l'ordre.
 
Sinon j'ai toujours pas  capté tes puissances désolé  :D  
Y a pas de puissance 24 dans les @IP on s'arrête à 7 car elles sont découpées en octets et on prend les octets séparément. Transformer en binaire je sais faire mais je crois pas que c'est ce dont j'ai besoin là.
Et je capte donc toujours pas le résultat de inet_addr pour 192.168.0.1.
Désolé y en a être lent mais comprendre vite quand même  :pt1cable: .

n°113017
merou91
Team Fallback !!
Posté le 17-03-2002 à 13:51:54  profilanswer
 

Y a qqn qui peut m'expliquer le résultat de inet_addr pour "192.168.0.1" donnant 16820416 ?
 
Sinon à votre avis c'est plus rapide en temps d'exécution :
 
if(inet_addr(ip1)<inet_addr(ip2)) {etc etc }
ou
if (strcmp(ip1,ip2)<0) {etc etc }

mood
Publicité
Posté le 17-03-2002 à 13:51:54  profilanswer
 

n°113038
Procat
L'eternel insatisfait !
Posté le 17-03-2002 à 14:54:41  profilanswer
 

merou91 a écrit a écrit :

Y a qqn qui peut m'expliquer le résultat de inet_addr pour "192.168.0.1" donnant 16820416 ?
 
Sinon à votre avis c'est plus rapide en temps d'exécution :
 
if(inet_addr(ip1)<inet_addr(ip2)) {etc etc }
ou
if (strcmp(ip1,ip2)<0) {etc etc }  




 
Tu prends 1 comme octet de poid fort et 192 comme octet de poid faible
Donc a partir de là tu as en realité 1.0.168.192
 

  • Metjode 1 (methode de bourrin)

1.0.168.192 en decimal =>
0000 0001.0000 0000.1010 1000.1100 0000 en binaire =>
tu les mets cote a cote :
00000001000000001010100011000000 => 16820416 en decimal  
compris ??
 

  • Autre methode moins barbare

1.0.168.192=>
 
1*(256*256*256)       // octet de poid fort sur un groupe de 4  
                      // octet donc il y aura 3 octets apres
                      // d'ou *(256*256*256)  
+0*(256*256)          // pareil avec 2 octect apres => *(256*256)
+168*(256)            // encore un octet apres *(256)
+192                  // octet de  poid faible donc  
= 16820416


---------------
[:procat]
n°113103
merou91
Team Fallback !!
Posté le 17-03-2002 à 16:49:06  profilanswer
 

Ok merci.
 
Sinon je cherche encore un truc, une fonction qui enlève les espaces de début de chaîne (toujours en c/c++).

n°113106
HelloWorld
Salut tout le monde!
Posté le 17-03-2002 à 16:56:55  profilanswer
 

tu fais un tableau de 4 octets et tu mets chaque nombre dans les octets :

Code :
  1. unsigned char Tab[4];


et tu initialise chaque caractere avec un nombre de l'ip ...
par exemple, 193.168.168.10 te donne :
Tab[0] = 193
Tab[1] = 168
Tab[2] = 168
Tab[3] = 10
 
pour avoir ensuite un long sous la forme "193168168010", tu fais juste :

Code :
  1. if((unsigned long)(*Tab) < ...)


Cela dit, il va peut etre falloir inverser les nombres (Tab[0] = 10, ..., Tab[3] = 193)
Il serait peut etre mieux alors d'utiliser une structure voire une union ...

Code :
  1. typedef union
  2. {
  3.     unsigned char Tab[4];
  4.     unsigned long val;
  5. }ip_t;


 
et le code devient

Code :
  1. ip_t ip;
  2. ip.Tab[0] = 193
  3. ip.Tab[1] = 168
  4. ip.Tab[2] = 168
  5. ip.Tab[3] = 10
  6. if(ip.val < ...)


 
à voir ...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°113172
merou91
Team Fallback !!
Posté le 17-03-2002 à 18:43:13  profilanswer
 

Ok merci tout le monde pour les réponses :).
 
Je cherche encore un truc, un lien vers l'algorithme de trie d'une liste chaînée selon 1 critère en c (j'en ai pondu 1 mais bon je pense qu'il y a mieux  :sarcastic: ).

n°113374
merou91
Team Fallback !!
Posté le 18-03-2002 à 00:42:20  profilanswer
 

Personne pour la fonction qui enlève les caractères espaces de début de chaîne et/ou un lien vers l'algorithme d'ajout trié d'un élément dans une liste chaînée selon 1 critère ?

n°113450
merou91
Team Fallback !!
Posté le 18-03-2002 à 10:19:01  profilanswer
 

up

n°113823
merou91
Team Fallback !!
Posté le 18-03-2002 à 20:25:12  profilanswer
 

:bounce: up

n°113926
LeGreg
Posté le 18-03-2002 à 23:39:58  profilanswer
 

Pour enlever les espaces
tu parcours ta chaine, tu reperes la position
du premier chiffre et tu decales simplement ta chaine
sur la gauche.. rien de sorcier.
 
pour le tri..
ca depend, du nombre d'elements a trier,
de leur ordre de depart.
Es-tu oblige d'utiliser une liste chainee?
si tu pouvais mettre tes valeurs dans un tableau
la fonction qsort ca marche pas mal.
 
A+
LEGREG

n°113937
merou91
Team Fallback !!
Posté le 19-03-2002 à 00:37:25  profilanswer
 

Oui c'est forcément une liste chaînée et je cherche l'algo qui ajoute un élément dans un liste selon 1 critère. Pas le tri à bulles qui trie après mais l'ago qui trie pendant l'ajout.
 
Sinon ouai je vois comment le faire à la main pour enlever les espaces de début mais bon comme ca va s'exécuter 2 fois pour les 2 millions de lignes du fichier que je lis si y a une fonction optimisée qui le fait c'est mieux quand même.

n°113944
LeGreg
Posté le 19-03-2002 à 01:27:16  profilanswer
 

merou91 a écrit a écrit :

Oui c'est forcément une liste chaînée et je cherche l'algo qui ajoute un élément dans un liste selon 1 critère. Pas le tri à bulles qui trie après mais l'ago qui trie pendant l'ajout.
Sinon ouai je vois comment le faire à la main pour enlever les espaces de début mais bon comme ca va s'exécuter 2 fois pour les 2 millions de lignes du fichier que je lis si y a une fonction optimisée qui le fait c'est mieux quand même.  




 
on n'optimise jamais un truc hors contexte.
Si ce sont des chaines statiques, tu peux
te contenter de deplacer le pointeur de debut
de chaine sur le premier caractere non espace.
Si tu dois operer une copie de ta chaine
a un moment (pour la mettre dans ta structure par ex),
et bien tu peux copier qu'a partir du premier
caractere non espace. etc.. etc..
 
Si tu as acces au C++, tu peux utiliser les structures
de la STL:

Citation :

void sort();  Sorts *this according to operator<. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain valid and continue to point to the same elements. [6] The number of comparisons is approximately N log N, where N is the list's size.

 
 
N*LogN c'est le temps d'execution moyen de la plupart des algorithmes de tri par comparaison.
 
Parfois c'est aussi rapide de conserver la liste en ordre
au fur et a mesure que tu rajoutes des elements.
Cela s'appelle le tri par insertion.
Tu prends une liste vide tu mets le premier element,
tu mets le deuxieme element en conservant l'ordre avec le premier.
Quand tu as une liste de n elements tries. Pour ajouter
ton n+1eme nombre, il suffit de parcourir ta liste a la recherche du plus petit element superieur a ton nombre
et d'inserer ce nombre a sa place. etc..
Si tu disposes d'une liste au depart quasiment triee,
le cout de construction de la liste triee est faible.
(tu peux faire le tri sur place mais pour une liste
chainee, la difference entre le tri sur place et la creation d'une nouvelle liste est totalement anecdotique).
 
Une variante plus efficace est le tri shell, qui consiste
a utiliser un pas variable pour rechercher le plus petit element superieur. Le principe de comment marche le tri shell est plus complique a comprendre mais il est efficace en pratique.
 
Il y a plein d'implantations disponibles sur internet:
http://www.google.fr/search?q=shell+sort
 
A+
LEGREG

n°113945
kvl
Posté le 19-03-2002 à 01:29:37  profilanswer
 

Ta premiere idée me semble pas mal en utilisant un sscanf(ip,%[0-9]...,&a...) puis aprés complément à gauche %3d ...

 

[jfdsdjhfuetppo]--Message édité par kvl--[/jfdsdjhfuetppo]

n°113948
merou91
Team Fallback !!
Posté le 19-03-2002 à 03:05:52  profilanswer
 

Je ne dispose pas de liste de départ, c'est moi qui la crée et comme il peut y avoir plus de 50000 éléments à l'intérieur ce serait préférable que lorque j'ajoute un nouvel élément je la trie parce que le parcours de 50000 éléments 2 millions de fois ca peut être long (à l'heure actuelle c comme ca, c'est une pile).(si un élément est en double j'incrémente un compteur)
C'est une liste chaînée de structure et pour ca l'algorithme de shell ne m'aide pas bcp. Je cherche l'algo pour les listes chaînées parcequ'il y a pleins de cas chiants à gérer liste nulle, ajout avant le premier élément, ajout après, garder la le pointeur précédent pour faire une chaînage entre deux éléments, cas des éléments identiques etc.
 
Pour le coup de espaces je vais regarder ce que tu propose thx :).

n°114040
LeGreg
Posté le 19-03-2002 à 11:13:40  profilanswer
 

merou91 a écrit a écrit :

Je ne dispose pas de liste de départ, c'est moi qui la crée et comme il peut y avoir plus de 50000 éléments à l'intérieur ce serait préférable que lorque j'ajoute un nouvel élément je la trie parce que le parcours de 50000 éléments 2 millions de fois ca peut être long (à l'heure actuelle c comme ca, c'est une pile).(si un élément est en double j'incrémente un compteur)



 
Si tu dois faire beaucoup de "lookup" dans ta liste,
il vaut certainement mieux passer a un b-tree
qui te permettra de passer d'un lookup en N
a un lookup en Log2(N)
M'enfin c'est juste un conseil.
 
Ou un arbre d'index.. enfin tu dois avoir
vu tout ca dans tes cours de prog, non?
 
LEGREG

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  C-Convertion chaine - Algo liste chaînée ordonnée -Fonction qui enlève

 

Sujets relatifs
[C] et [Algo] sur IRC[PHP / JS]Existe t'il une fonction qui
[PHP] Liste déroulante[Java] liste des changements entre 2 versions du JDK
Fonction mail avec EasyPhpOptimisation pour une comparaison de chaîne en c/c++
pl/sql fonction recherche caractere?[php/javascript/html]Passage de la valeur d'une liste de selection
[PHP] - fonction round ![JAVASCRIPT] Comment déterminer en pixels la taille d'une chaine ???
Plus de sujets relatifs à : C-Convertion chaine - Algo liste chaînée ordonnée -Fonction qui enlève


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR