PDA

View Full Version : [C] Ora ho problemi con questo... grrr.... non si finisce mai


Manugal
22-09-2005, 17:55
Devo creare una funzione che mi verifichi se una stringa è palindroma o no ignorando gli spazi. Ad esempio se ho scritto:

"otto" oppure "ott o" queste sono entrambe palindrome.

Io ho scritto una cosa del genere:



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

int palindroma(char a[]);

int main(void){

int ris;
char a[]="o tt o";
ris=palindroma(a);
printf("%d", ris);
return 0;
}

int palindroma(char a[]){

int i=strlen(a),j=0;

while(j!=i){
if(isalpha(i) && isalpha(j)){
if(a[i]!=a[j])
return 0;
else{
--i;
++j;
}
}
else if(isalpha(i)){
++j;
}
else if(isalpha(j)){
--i;
}
}
return 1;
}



Praticamente lo faccio partire e si blocca devo per forza premere Ctrl-C. Che cosa c'è che non va? Grazie :)

Gica78R
22-09-2005, 18:11
Devo creare una funzione che mi verifichi se una stringa è palindroma o no ignorando gli spazi. Ad esempio se ho scritto:

"otto" oppure "ott o" queste sono entrambe palindrome.

Io ho scritto una cosa del genere:



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

int palindroma(char a[]);

int main(void){

int ris;
char a[]="o tt o";
ris=palindroma(a);
printf("%d", ris);
return 0;
}

int palindroma(char a[]){

int i=strlen(a),j=0;

while(j!=i){
if(isalpha(i) && isalpha(j)){
if(a[i]!=a[j])
return 0;
else{
--i;
++j;
}
}
else if(isalpha(i)){
++j;
}
else if(isalpha(j)){
--i;
}
}
return 1;
}



Praticamente lo faccio partire e si blocca devo per forza premere Ctrl-C. Che cosa c'è che non va? Grazie :)
La condizione (i!=j) non funziona sempre; ad esempio, se non ci sono spazi e i=5, i e j assumono le seguenti coppie di valori:
- 5,0
- 4,1
- 3,2
- 2,3
- 1,4
ecc. ecc. ed il ciclo non termina mai; inoltre, i dovrebbe partire da
strlen(a)-1
anche se alla prima iterazione ci pensa l'if a ristabilire il giusto valore iniziale.

Ho dato un'occhiata fugace, magari mi e' sfuggito qualcosa :)

Manugal
22-09-2005, 19:19
Grazie. Allora potrei modificare il while mettendo while(j<=i)? Però sono sicuro che il problema non stia tanto lì quanto al conteggio degli spazi (io gli spazi li devo ignorare).

Gica78R
22-09-2005, 20:31
Grazie. Allora potrei modificare il while mettendo while(j<=i)? Però sono sicuro che il problema non stia tanto lì quanto al conteggio degli spazi (io gli spazi li devo ignorare).
Se posso darti un consiglio, scriviti una funzioncina che ti elimina gli spazi dalla stringa, e poi procedi col test se e' palindroma o meno (sempre che non ti sia chiesto di preservare la stringa originale, eh). Io l'ho risolto cosi'. :)

anx721
22-09-2005, 20:33
int pal(char p[]){
int len = strlen(p);
int i = 0, j = len - 1;
while(i < j){
if(p[i] == ' '){
i++;
continue;
}
if(p[j] == ' '){
j--;
continue;
}
if(p[i] != p[j])
return 0;
else{
i++;
j--;
}
}
return 1;
}

Gica78R
22-09-2005, 20:46
int is_palindroma(char *frase)
{
remove_blanks(frase);

int len = strlen(frase) - 1;
int i = 0;
while (i < len)
if (frase[i++] != frase[len--])
return 0;
return 1;
}



void remove_blanks(char *f)
{
int i = 0;
int j = 0;
while (f[i] != '\0')
isalpha(f[i]) ? f[j++] = f[i++] : i++;
f[j] = '\0';
}


Pero' come ha fatto anx721 non altera la stringa (anche se tutti quegli if - else farebbero arrabbiare fek :D )


Ciao

EDIT: ora che ci penso, pero', la mia soluzione funziona solo in caso di stringhe composte di soli caratteri alfabetici... Cmq e' quello che serve quando si ha a che fare con stringhe rappresentanti frasi in un linguaggio umano (cioe' e' giusto ignorare i segni di interpunzione, accenti, apostrofi, ecc.) imho :)

anx721
22-09-2005, 20:51
[CODE]
Pero' come ha fatto anx721 non altera la stringa (anche se tutti quegli if - else farebbero arrabbiare fek :D )


ma la tua crea segmentation fault se si passa un letterale stringa :)

Gica78R
22-09-2005, 20:57
ma la tua crea segmentation fault se si passa un letterale stringa :)
Cioe' se faccio

ret = is_palindroma("Questa non e' palindroma");

Mi sa che hai ragione...
Nalla mia soluzione completa, in realta', la stringa era passata come parametro al main, quindi non ci ho badato :muro:

Grazie...

Manugal
22-09-2005, 20:57
Grazie. Infatti non deve alterare la stringa deve solo vedere se è palindroma o no anche se ci sono spazi (che vanno ignorati). Il problema del mio maledetto compilatore (Dev-C++) è che quando qualcosa non va non mi dice mai se va in Segmentation Fault o qualche altra cosa. Semplicemente si limita a non scrivere niente e a ritornarmi al prompt dei comandi. Che dite che compilatore posso usare?

Gica78R
22-09-2005, 21:07
Che dite che compilatore posso usare?
gcc (sotto Linux :p )
Senno' ce ne sono della Borland liberamente scaricabili, pero' poi non saprei dirti come integrarlo nel tuo IDE (se usi un IDE).

Ciao

anx721
22-09-2005, 21:11
Grazie. Infatti non deve alterare la stringa deve solo vedere se è palindroma o no anche se ci sono spazi (che vanno ignorati). Il problema del mio maledetto compilatore (Dev-C++) è che quando qualcosa non va non mi dice mai se va in Segmentation Fault o qualche altra cosa. Semplicemente si limita a non scrivere niente e a ritornarmi al prompt dei comandi. Che dite che compilatore posso usare?

io uso mingw developer studio come ide che pero ha lo stesso compilatore di devcpp (che non è un compilatore in sè); se c'è un segmentation fault c'è la fnestra d'errore di windows, ma questa dovrebbe esserci indipendentemente dal compilatore che usi, piu che altro dipende dal sistema su cui ti trovi

cionci
22-09-2005, 21:47
gcc (sotto Linux :p )
Senno' ce ne sono della Borland liberamente scaricabili, pero' poi non saprei dirti come integrarlo nel tuo IDE (se usi un IDE).

Sta usando gcc sotto Windows e gli vuoi fare cambiare ? :D

In Dev-C++ metti un input (scanf o qualsiasi cosa del genere) prima dell'uscita del programma almeno ti si vede la console...

cionci
22-09-2005, 22:08
Io la farei così...

#include <ctype.h>
.....
.....
.....
int palindroma(const char *str)
{
int i = 0;
int j = strlen(str)-1;

while(i > j)
{
while(isspace(str[i])) ++i;
while(isspace(str[j])) ++j;

if(str[i] != str[j])
return 0;
}

return 1;
}

Gica78R
22-09-2005, 22:16
Io la farei così...

#include <ctype.h>
.....
.....
.....
int palindroma(const char *str)
{
int i = 0;
int j = strlen(str)-1;

while(i > j)
{
while(isspace(str[i])) ++i;
while(isspace(str[j])) ++j;

if(str[i] != str[j])
return 0;
}

return 1;
}

Magari con

while (i < j)

e

while (isspace(str[j])) --j;

funziona meglio :D :D :D

cionci
22-09-2005, 22:35
In effetti :)

anx721
22-09-2005, 22:38
Io la farei così...

#include <ctype.h>
.....
.....
.....
int palindroma(const char *str)
{
int i = 0;
int j = strlen(str)-1;

while(i > j)
{
while(isspace(str[i])) ++i;
while(isspace(str[j])) ++j;

if(str[i] != str[j])
return 0;
}

return 1;
}


oltre alle correzioni già segnalate bisogna anche aggiustare le condizioni dei due while interni: anche esse devono controllare che (i < j) se no gli indici possono essere decrementati o incrementati oltre i valori limiti

cionci
22-09-2005, 22:44
oltre alle correzioni già segnalate bisogna anche aggiustare le condizioni dei due while interni: anche esse devono controllare che (i < j) se no gli indici possono essere decrementati o incrementati oltre i valori limiti
Invece no... E' questa la furbata :) Perchè il primo carattere diverso da spazio per entrambe le direzioni è già stato verificato essere lo stesso ;)

supersayan
22-09-2005, 22:58
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void togli_gli_spazi (char *s, char *s1) {
int i=0, j=0;
s[strlen(s)-1]= '\0';
while (s[i]) {
if (s[i] != ' ') {
s1[j]= s[i];
j++;
}
i++;
}
}

int main (int argc, char **argv) {
char *s, *s1;
int i=0, j=0;
s= (char *) calloc (32, sizeof(char));
s1= (char *) calloc (32, sizeof(char));
printf("Inserisci la stringa: ");
fgets(s, 31, stdin);
if (s[0]=='\n') {
printf("hai inserito una stringa vuota!\n");
exit(EXIT_FAILURE);
}
togli_gli_spazi(s, s1);
j= strlen(s1) -1;
while (i<j) {
if (s1[i]==s1[j]) {
i++;
j--;
}
else break;
}
if (i>=j) printf("!!!la stringa e' palindroma!!!\n");
else printf("!!!la stringa non e' palindroma!!!\n");
exit(EXIT_SUCCESS);
}

Gica78R
22-09-2005, 22:59
Invece no... E' questa la furbata :) Perchè il primo carattere diverso da spazio per entrambe le direzioni è già stato verificato essere lo stesso ;)
Una stringa di soli spazi e' palindroma? Secondo me si. In tal caso, credo che la tua funzione restituisca 0, vero?
Dopo i due while (isspace()), str[i] sarebbe l'ultimo carattere della stringa, cioe' '\0', mentre str[j] e' indefinito e probabilmente diverso da '\0'. Sbaglio?

cionci
22-09-2005, 23:19
Sì...in tal caso non funziona...

anx721
22-09-2005, 23:35
Invece no... E' questa la furbata :) Perchè il primo carattere diverso da spazio per entrambe le direzioni è già stato verificato essere lo stesso ;)

era appunto al caso della stringa di soli spazi che mi riferivo come il caso in cui c'era il problema