Programme de Compression en C
Je veux compresser une série de caractères. Par exemple, si je tape
D'entrée : FFFFFBBBBBBBCCBBBAABBGGGGGSSS (27 x 8 bits = 216 bits)
Sortie: F5B7C2B3A2B2G5S3 (14 x 8 bits = 112bits)
Jusqu'à présent c'est ce que j'ai, je peux compter le nombre de Caractères dans le Tableau. Mais la tâche la plus importante est de les compter dans la même séquence. Je n'arrive pas à comprendre ça 🙁
Ive a regardé faire C juste il y a quelques semaines, j'ai des connaissances sur le Tableau, les pointeurs, la valeur ASCII
mais en tout cas ne semble pas possible de compter les caractères dans une séquence. Ive essayer un peu de tout. Cette approche n'est pas bon, mais il est le plus près je suis venu à elle.
#include <stdio.h>
#include <conio.h>
int main()
{
int charcnt=0,dotcnt=0,commacnt=0,blankcnt=0,i, countA, countB;
char str[125];
printf("*****String Manipulations*****\n\n");
printf("Enter a string\n\n");
scanf("%[^'\n']s",str);
printf("\n\nEntered String is \" %s \" \n",str);
for(i=0;str[i]!='#include <stdio.h>
#include <conio.h>
int main()
{
int charcnt=0,dotcnt=0,commacnt=0,blankcnt=0,i, countA, countB;
char str[125];
printf("*****String Manipulations*****\n\n");
printf("Enter a string\n\n");
scanf("%[^'\n']s",str);
printf("\n\nEntered String is \" %s \" \n",str);
for(i=0;str[i]!='\0';i++)
{
//COUNTING EXCEPTION CHARS
if(str[i]==' ')
blankcnt++;
if(str[i]=='.')
dotcnt++;
if(str[i]==',')
commacnt++;
if (str[i]=='A' || str[i]=='a')
countA++;
if (str[i]=='B' || str[i]=='b')
countA++;
}
//PRINT RESULT OF COUNT
charcnt=i;
printf("\n\nTotal Characters : %d",charcnt);
printf("\nTotal Blanks : %d",blankcnt);
printf("\nTotal Full stops : %d",dotcnt);
printf("\nTotal Commas : %d\n\n",commacnt);
printf("A%d\n", countA);
}
';i++)
{
//COUNTING EXCEPTION CHARS
if(str[i]==' ')
blankcnt++;
if(str[i]=='.')
dotcnt++;
if(str[i]==',')
commacnt++;
if (str[i]=='A' || str[i]=='a')
countA++;
if (str[i]=='B' || str[i]=='b')
countA++;
}
//PRINT RESULT OF COUNT
charcnt=i;
printf("\n\nTotal Characters : %d",charcnt);
printf("\nTotal Blanks : %d",blankcnt);
printf("\nTotal Full stops : %d",dotcnt);
printf("\nTotal Commas : %d\n\n",commacnt);
printf("A%d\n", countA);
}
Vous avez besoin de mettre en place un tableau de compteurs, un pour chaque personnage que vous pourriez rencontrer. En essayant de les faire séparément les variables discrètes serait assez lourd.
Je pense qu'il veut de longueur de course de l'encodage.
il est assez évident que ce que vous voulez faire dans l'exemple que vous nous avez montré, mais vous avez besoin de dire quoi faire avec tous les puncuation caractères.
Vous pouvez également profiter de la ce fil à CodeGolf, sur un minimum de programmes pour décoder le type de sortie généré ici.
OriginalL'auteur Delandilon | 2013-11-03
Vous devez vous connecter pour publier un commentaire.
Ce que vous essayez de faire est appelée Run-Length Encoding.
Je pense que le comptage de l'ensemble des personnages et, plus précisément, de quelque caractère particulier (par exemple, des points, des virgules, des espaces) est une distraction inutile si votre objectif est simplement de longueur compresser la chaîne. Donc, nous allons ignorer pour l'instant.
Voici comment vous pouvez le faire facilement en run-length encoding (encodage d'une chaîne de caractères ASCII en place. c'est à dire la chaîne d'origine sera remplacée par le comprimé de la chaîne. Cela peut ou peut ne pas être ce que vous voulez, mais il économise de l'attribution d'un autre tampon et est facile à coder.
Si le nombre ou l'exclusion de tous les caractères spéciaux le long de la route est nécessaire, vous pouvez le faire facilement dans la
while
boucle.Ajouter ce pour permettre de tester à partir de la ligne de commande. Exécuter avec votre chaîne d'origine comme le seul argument.
À vos exigences pour la sortie ne sont pas complètement spécifié, si mes hypothèses sont les suivantes:
Optimisation de l'hypothèse: Pistes de longueur 1 ne sont pas compressés. C'est facile à détecter lors de la décompression et assure la compression de la chaîne n'est jamais plus long que l'original. par exemple,
"ABBCDEF"
comprime"AB2CDEF"
(au lieu de"A1B2C1D1E1F1"
)Hypothèse simplificatrice: Pistes de plus de 9 caractères seront compressés en plusieurs morceaux. Cela garantit une longueur de course peut toujours être exprimé en une seule ASCII des chiffres. c'est à dire
"AAAAAAAAAAAABBBB"
comprime"A9A3B4"
Si vous avez besoin de la sortie de la"A12B4"
, il n'est pas difficile. Supprimer larun_len == 9
de comparaison et d'étendre le code sousrun_len > 1
à utiliseriota
pour la chaîne de rendu.OriginalL'auteur Darren Stone
L'installation d'un compteur. Analyse du tableau dans une boucle for. Gardez à incrémenter le comte, tant que la matrice a même séquence de caractères, dès que le caractère de la séquence de sauts de définir le comte de la compression nombre de caractères et le nombre de 0 à ajouter à nouveau pour la séquence suivante. Pour vérifier la séquence simple de mettre une variable char qui maintient la valeur du dernier élément de tableau et la compare avec le prochain élément de tableau dans la boucle suivante pour voir si la séquence de sauts.
C'est un algorithme O(n) et doit être utilisé.
OriginalL'auteur
Il me semble que vous avez deux problèmes mélangés.
La première, comme cela a été souligné par @Darren, est appelé Run-Length Encoding: look pour une séquence d'octets identiques, et de les remplacer par un seul octet suivi par un nombre de répétitions. La seconde, aussi loin que je peux dire, est de compter combien de certains des caractères "spéciaux" se produisent dans la chaîne.
Run-Length Encoding
Je vais vous donner une mise en œuvre différente de RLE que @Darren. Comme sa solution, mine de ne pas traiter avec le "caractère spécial" pièces= de la cession. Je vais commencer avec
C'est le squelette de run-length encoding: se déplacer dans l'entrée de trouver des pistes, puis émet ceux exécuter dans la sortie, correctement encodés. Cette boucle est constituée de trois étapes:
find_run
fonction est d'aller le chercher le plus long autorisé exécuter en commençant à l'emplacement actuel de l'entrée, pointé parin
. Il retourne la longueur de la course, qui sera toujours plus grande que zéro.emit_run
prend un caractère et une répétition de compter, et génère le bon encodage dans la mémoire tampon de sortie. Il retourne le prochain emplacement à utiliser dans le tampon de sortie.len
octets et répéter la boucle.Après la boucle est terminée, on ajoute un octet NUL sur le tampon de sortie de sorte qu'il forme une chaîne valide. Dans un vrai compresseur de toute sorte, cette dernière étape ne serait pas fait, et l'entrée et la sortie des tampons seraient tous les deux ont des tailles qui leur sont associés.
La seule bits de gauche sont pour la mise en œuvre
find_run
etemit_run
. Commençons paremit_run
que c'est un peu plus simple:Cela prend un tampon de sortie
out
, un personnagec
, et c'est assocated nombre de répétitionslen
. Compte tenu, par exemple,c == 'A'
etlen == 5
, il ajouteC5
de la mémoire tampon de sortie.Il y a un assez grave problème avec cette fonction. Examinons ce qui se passe à la chaîne
"ABCDE"
: chaque lettre a un compteur de répétition de l'un, et la chaîne est codé comme"A1B1C1D1E1"
, ce qui est très peu compressé. Il existe plusieurs approches à ce problème, certains sont discutés dans les réponses à cette question, et tout ce qui peut être mis en œuvre par de petits changements àemit_run
.Ce qui nous laisse avec le problème de trouver les pistes en premier lieu.
Cette fonction est donné un endroit pour commencer la numérisation,
in
, et renvoie combien de fois le premier caractère de l'entrée se répète.run_char
, et initialiserrun_len
à zéro.c
dans l'entrée, et de décider si la course a pris fin ou non. La course se termine si unc
n'est pas égal àrun_char
, ou si l'exécution a atteint sa longueur maximale. Notez que la vérification dec
pas égal àrun_char
gère également frapper la fin de la chaîne, c'est à dire,c
estNUL
.Toutes ces pièces ensemble, de mettre en œuvre une version simple de run-length encoding. Ce qui suit est un squelette d'un petit programme de test.
J'ai essayé de mettre en place cette mise en oeuvre particulière afin de maximiser la clarté de l'algorithme, mais @Darren version est plus proche de ce que vous pouvez voir dans le code de production dans l'ensemble de la mise en œuvre est en une seule fonction. Son choix pour encoder en place est certainement valable, bien que je pense que les deux en place et de séparer en sortie de la mémoire tampon versions sont communs. Les premiers sont un peu plus difficile à comprendre si vous êtes nouveau à C, et en particulier des pointeurs. Aussi, dans toutes les versions de production, à la fois l'entrée et la sortie des tampons serait donné de manière explicite les longueurs, et il y aurait un code supplémentaire de vérifier pour le débordement de la mémoire tampon de sortie, les deux dont j'ai ignoré ici.
Caractère De Comptage
Concernant le caractère de comptage, n'essayez pas de garder une magie variable séparée pour chaque caractère spécial. Au lieu de cela, je suggère à l'aide d'un 256-élément de tableau d'accumuler des comtes de tous de caractères, puis plus tard d'imprimer seulement les entrées que vous voulez.
C'est assez facile de modification de
find_run
si vous utilisez un réseau mondial, mais encore une fois, vous ne voudriez pas le faire de cette façon dans une véritable mise en œuvre.OriginalL'auteur Dale Hagglund
Voici la solution que j'ai travaillé pour cette mission - Cette fonction a été utilisée pour faire la compression de la chaîne. Espérons qu'il aidera si tout toujours avoir de problème.
OriginalL'auteur Delandilon
Peut-être trop long mais facile à comprendre je pense.
OriginalL'auteur vmule