Stringa con caratteri ripetuti una volta sola

di il
4 risposte

Stringa con caratteri ripetuti una volta sola

Questa è la consegna dell'esercizio:
La funzione accetta una stringa C (zero terminata) e ritorna una stringa C allocata dinamicamente sull’heap, contenente tutti i caratteri della stringa s presi una sola volta, nell’ordine con cui appaiono in s.
Ad esempio data la stringa s=“ciao casa”, la funzione deve ritornare “ciao s”. Infatti, scorrendo s, incontriamo prima ‘c’, poi ‘i’, poi ‘a’, poi ‘o’, poi ‘’. Nessuno di questi è già stato visto. Poi incontriamo ‘c’, ma questo carattere è già stato incontrato e quindi non viene concatenato alla stringa di ritorno. Lo stesso succede per ‘a’, poi si incontra ‘s’ e viene mandato in output. Infine troviamo ancora ‘a’ e di nuovo lo ignoriamo.
Il puntatore ritornato deve puntare ad un’area di memoria grande esattamente il numero di byte necessari a contenere i caratteri unici e il terminatore. s non sarà mai NULL.
questo è il mio main
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>


extern char *unici(const char *s);


int main(){

	char str[] = "ciao casa";

	char ris = unici(str);
	
	return 0;

}
questo è il mio file.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

char *unici(const char *s){

	size_t lunghezza = strlen(s);
	size_t doppioni = 0;
	size_t i = 0;
	size_t k;
	
	for (i = 0; i < strlen(s); i++){

		k = i + 1;

		while (s[k] != '\0'){

			if (s[i] == s[k]){
				doppioni++;
				break;
			}
			k++;
		}
	}

	size_t strnew = strlen(s) - doppioni;
	char *ris = malloc((strnew + 1) * sizeof(char));
	size_t j = 0; 
	size_t f = 0; // indice nuova stringa
	
	for (i = 0; i < strlen(s); i++){
		
		k = i + 1;

		while (s[k] != '\0'){

			if (s[i] == s[k]){
				break;
			}
			
			
			k++;
		}
		ris[f] = s[i];
		f++;

	}

	ris[strnew] = "\0";

	return ris;

}
Premetto che il mio programma non funziona come dovrebbe. Una prima parte sembrerebbe corretta, perchè tramite la variabile 'doppioni' scarto le lettere in più, cosi da allocare la giusta dimensione di memoria tramite la malloc. Però poi quando devo allocare i caratteri della stringa non riesco a capire come dovrei fare.. ho cercato di provare un doppio ciclo, ma con scarsi risultati
Qualcuno riesce a darmi una mano?

4 Risposte

  • Re: Stringa con caratteri ripetuti una volta sola

    A una prima occhiata noto che scrivi char ris = unici(str);
    In effetti, se ris deve "ricevere" un puntatore a un'area di memoria allocata dinamicamente, ris deve essere un puntatore a char, non un char.
    Per questo dovresti scrivere char *ris = unici(str);

    Ora vado a vedere il resto.
  • Re: Stringa con caratteri ripetuti una volta sola

    Più avanti scrivi ris[strnew] = "\0";
    In effetti per terminare una stringa dovresti scrivere ris[strnew] = '\0';

    In un altro punto, compare una variabile non utilizzata size_t j = 0;

    Inutilizzato è anche size_t lunghezza;

    P.S. Prima di lasciare il programma, non dimenticare di deallocare la memoria allocata.
  • Re: Stringa con caratteri ripetuti una volta sola

    Io avrei seguito un procedimento diverso. Tipo...

    Appurato che la stringa risultante può essere AL MASSIMO lunga quanto quella originale, comincio controllando la lunghezza della stringa originale ed allocando uno spazio di memoria dinamica di dimensioni sufficienti a contenerne una copia (verifico sempre gli eventuali errori nell'allocazione). Se uso calloc() invece di malloc() non devo neppure preoccuparmi di terminare la stringa con '\0'.

    Predispongo un array di 256 char da usare come flag per "segnare" i caratteri ogni volta che ne incontro la prima occorrenza. Ad esempio, quando esce 'a' la prima volta, imposto su 1 il carattere all'indirizzo 97 nell'array e copio la 'a' in coda alla stringa che vado accumulando nella memoria dinamica. Quando incontrerò altre 'a', controllando il flag corrispondente saprò di averle già "viste" in precedenza ed eviterò di copiarle più volte.
    Nell'usare le lettere come indici per contrassegnare gli elementi dell'array va tenuto presente il fatto che i caratteri vanno da -128 a 127. Per aggirare l'ostacolo basta un bel cast a unsigned char per avere valori utilizzabili come indici, da 0 255.

    Riduco al minimo la memoria allocata, usando realloc().

    Non aggiungo codice, se no poi mi sgridano.
  • Re: Stringa con caratteri ripetuti una volta sola

    Okok capito, grazie mille!
Devi accedere o registrarti per scrivere nel forum
4 risposte