Difference between revisions of "Palindroma"

From Sistemi Operativi
Jump to navigation Jump to search
(Created page with "Visto che qui non succede nulla, inizio io: Ecco una implementazione in python3... chi mi propone altre soluzioni alternative? <syntaxhighlight language=python> #!/usr/bin/e...")
 
m
 
(23 intermediate revisions by 4 users not shown)
Line 3: Line 3:
 
Ecco una implementazione in python3... chi mi propone altre soluzioni alternative?
 
Ecco una implementazione in python3... chi mi propone altre soluzioni alternative?
  
<syntaxhighlight language=python>
+
<syntaxhighlight lang="python">
 
#!/usr/bin/env python3
 
#!/usr/bin/env python3
  
Line 18: Line 18:
 
   print("is {} palindrome? {}".format(s,"true" if palindrome(s) else "false"))
 
   print("is {} palindrome? {}".format(s,"true" if palindrome(s) else "false"))
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Domenique ha proposto questa funzione in C:
 +
<syntaxhighlight lang="C">
 +
int palindroma(char *pnt){
 +
 +
int dim=strlen(pnt)-1;
 +
int l=dim/2;
 +
int k;
 +
 +
for(k=0;k<=l;k++)
 +
{
 +
if(pnt[k]!=pnt[dim])
 +
return 0;
 +
else
 +
dim--;  
 +
}
 +
        return 1;
 +
}
 +
</syntaxhighlight>
 +
 +
altre proposte?
 +
Cosa ne dite di questa soluzione?
 +
<syntaxhighlight lang="C">
 +
#include <stdio.h>
 +
#include <string.h>
 +
 +
#ifdef REC
 +
int recpali(char s[], int i, int f){
 +
        if (i>=f)
 +
                return 1;
 +
        else if (s[i]!=s[f])
 +
                return 0;
 +
        else
 +
                return recpali(s, i+1, f-1);
 +
}
 +
 +
int palindroma(char s[]){
 +
        return recpali(s, 0, strlen(s)-1);
 +
}
 +
#else
 +
int palindroma(char *s) {
 +
        char *t;
 +
        for (t=s+(strlen(s)-1); s < t; s++, t--)
 +
                if (*t != *s) return 0;
 +
        return 1;
 +
}
 +
#endif
 +
 +
 +
#ifdef DEBUGMAIN
 +
int main(int argc, char *argv[])
 +
{
 +
        if (argc < 2) return -1;
 +
        printf("%s: %se\' una stringa palindroma\n",argv[1],palindroma(argv[1])?"":"non ");
 +
}
 +
#endif
 +
</syntaxhighlight>
 +
 +
per compilare il main di prova chiamate il compilatore con il comando seguente
 +
    gcc -DDEBUGMAIN -o pali pali.c
 +
(ovviamente mutatis mutandis, se il vostro sorgente non si chiama pali come il mio)
 +
 +
Patti aveva proposto questa soluzione ricorsiva in C:
 +
<syntaxhighlight lang="C">
 +
int palin(char s[], int i, int f){
 +
if (s[i]!=s[f])
 +
return 0;
 +
if (i>=f)
 +
return 1;
 +
return palin(s, i+1, f-1);
 +
}
 +
 +
int palindroma(char s[]){
 +
if (strlen(s)<2)
 +
return 1;
 +
return palin(s, 0, strlen(s)-1);
 +
}
 +
</syntaxhighlight>
 +
(era dentro l'ifdef REC sopra).
 +
L'ho leggermente migliorata in due aspetti:
 +
* e' buona cosa nella ricorsione controllare il caso base (caso di uscita) come prima operazione. Come vedete questo consente qui di eliminare il controllo prima della chiamata palin (che ho ridenominato recpali).
 +
* e' sempre bene indicare esplicitamente l'else agli if anche in caso di return. Cosi' il codice e' piu' leggibile.
 +
* una ulteriore nota: se avete necessit&agrave; della lunghezza della stringa in piu' punti, e la stringa non viene modificata, e' meglio assegnare l'output ad una variabile locale invece che chiamare strlen in piu' punti.
 +
 +
Chi ha voglia ora di proporre una soluzione iterativa in Python?
 +
 +
Questa suppongo sia considerabile una [https://github.com/tomOgn/University/blob/master/OS-Python/Palindrome/Palindrome.py soluzione iterativa]:
 +
<syntaxhighlight lang="python">
 +
def IsPalindrome(word):
 +
    return word == word[::-1]
 +
</syntaxhighlight>
 +
 +
Ottimo (rd20131101), ma ora te la ottimizzo. La tua ''itera'' troppo! Il controllo di palindromia (neologismo ;-) lo fai due volte! La versione seguente ha meta' complessita':
 +
<syntaxhighlight lang="python">
 +
def IsPalindrome(word):
 +
  h=len(word)//2
 +
  return word[:h] == word[::-1][:h]
 +
</syntaxhighlight>
 +
 +
*[Python] soluzione iterativa (Federico&Alessio):
 +
<syntaxhighlight lang="python">
 +
a=raw_input("Parola?\n" )
 +
def pal(x):
 +
if len(x)<2:
 +
return 1
 +
else:
 +
a=len(x)-1
 +
if len(x)%2!=0:
 +
i=0
 +
while i!=a:
 +
if x[i]!=x[a]:
 +
return 0
 +
a=a-1
 +
i=i+1
 +
return 1
 +
else:
 +
i=0
 +
m=a/2
 +
while i!=m+1:
 +
if x[i]!=x[a]:
 +
return 0
 +
a=a-1
 +
i=i+1
 +
return 1
 +
 +
if pal(a)==1:
 +
a="palindromo"
 +
else:
 +
a='non palindromo'
 +
 +
print '%r'%a
 +
</syntaxhighlight>
 +
*a parte qualche piccola correzione sintattica(inizzializzazioni,parentesi,etc.) questo codice si presta molto ad essere portato in c.
 +
 +
... ma e' un po' prolisso (rd 20131101).
 +
La traduzione del loop C:
 +
 +
<syntaxhighlight lang="C">
 +
  for (t=s+(strlen(s)-1); s < t; s++, t--)
 +
    if (*t != *s) return 0;
 +
  return 1;
 +
</syntaxhighlight>
 +
 +
puo' essere fatta in modo piu' compatto.
 +
<syntaxhighlight lang="python">
 +
def pal(word):
 +
  for i in range(len(word)//2):
 +
    if word[i] != word[-(i+1)]: return False
 +
  else:
 +
    return True
 +
</syntaxhighlight>
 +
 +
Notate, plz, l'uso dell'else nel for. Anche se qui e' inutile per la correttezza del risultato, rende il codice piu' leggibile: indica che l'assegnamento a True viene effettuato solo se si completano tutti i cicli del loop.
 +
 +
 +
 +
* Non avevo pensato alla possibilità dell'indice negativo che effettivamente è molto elegante (lo voglio provare per una mia versione ricorsiva):
 +
<syntaxhighlight lang="python">
 +
def pal_ric_supp(w,i):
 +
if i>=len(w)/2:
 +
return True
 +
else:
 +
if w[i]!=w[-i-1]:
 +
return False
 +
else:
 +
return pal_ric_supp(w,i+1)
 +
 +
def pal_ric(w):
 +
if len(w)<2:
 +
return True
 +
else:
 +
return pal_ric_supp(w,0)
 +
</syntaxhighlight>
 +
-Fede

Latest revision as of 18:59, 1 November 2013

Visto che qui non succede nulla, inizio io:

Ecco una implementazione in python3... chi mi propone altre soluzioni alternative?

#!/usr/bin/env python3

def palindrome(x):
  if len(x) < 2: return True
  else:
    if x[0] == x[-1]:
      return palindrome(x[1:-1])
    else:
      return False

if __name__ == "__main__":
  s=input("type in a string: ")
  print("is {} palindrome? {}".format(s,"true" if palindrome(s) else "false"))

Domenique ha proposto questa funzione in C:

int palindroma(char *pnt){

	int dim=strlen(pnt)-1;
	int l=dim/2;
	int k;

	for(k=0;k<=l;k++)
	{ 
		if(pnt[k]!=pnt[dim])
			return 0;
		else
			dim--;	  						
	}
        return 1;
}

altre proposte? Cosa ne dite di questa soluzione?

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

#ifdef REC
int recpali(char s[], int i, int f){
        if (i>=f)
                return 1;
        else if (s[i]!=s[f])
                return 0;
        else
                return recpali(s, i+1, f-1);
}
 
int palindroma(char s[]){
        return recpali(s, 0, strlen(s)-1);
}
#else
int palindroma(char *s) {
        char *t;
        for (t=s+(strlen(s)-1); s < t; s++, t--)
                if (*t != *s) return 0;
        return 1;
}
#endif


#ifdef DEBUGMAIN
int main(int argc, char *argv[])
{
        if (argc < 2) return -1;
        printf("%s: %se\' una stringa palindroma\n",argv[1],palindroma(argv[1])?"":"non ");
}
#endif

per compilare il main di prova chiamate il compilatore con il comando seguente

   gcc -DDEBUGMAIN -o pali pali.c

(ovviamente mutatis mutandis, se il vostro sorgente non si chiama pali come il mio)

Patti aveva proposto questa soluzione ricorsiva in C:

int palin(char s[], int i, int f){
	if (s[i]!=s[f])
		return 0;
	if (i>=f)
		return 1;
	return palin(s, i+1, f-1);
}

int palindroma(char s[]){
	if (strlen(s)<2)
		return 1;
	return palin(s, 0, strlen(s)-1);	
}

(era dentro l'ifdef REC sopra). L'ho leggermente migliorata in due aspetti:

  • e' buona cosa nella ricorsione controllare il caso base (caso di uscita) come prima operazione. Come vedete questo consente qui di eliminare il controllo prima della chiamata palin (che ho ridenominato recpali).
  • e' sempre bene indicare esplicitamente l'else agli if anche in caso di return. Cosi' il codice e' piu' leggibile.
  • una ulteriore nota: se avete necessità della lunghezza della stringa in piu' punti, e la stringa non viene modificata, e' meglio assegnare l'output ad una variabile locale invece che chiamare strlen in piu' punti.

Chi ha voglia ora di proporre una soluzione iterativa in Python?

Questa suppongo sia considerabile una soluzione iterativa:

def IsPalindrome(word):
    return word == word[::-1]

Ottimo (rd20131101), ma ora te la ottimizzo. La tua itera troppo! Il controllo di palindromia (neologismo ;-) lo fai due volte! La versione seguente ha meta' complessita':

def IsPalindrome(word):
   h=len(word)//2
   return word[:h] == word[::-1][:h]
  • [Python] soluzione iterativa (Federico&Alessio):
a=raw_input("Parola?\n" )
def pal(x):
	if len(x)<2:
		return 1
	else:
		a=len(x)-1
		if len(x)%2!=0:
			i=0
			while i!=a:
				if x[i]!=x[a]:
					return 0
				a=a-1
				i=i+1
			return 1
		else:
			i=0
			m=a/2
			while i!=m+1:
				if x[i]!=x[a]:
					return 0
				a=a-1
				i=i+1
			return 1

if pal(a)==1:
	a="palindromo"
else:
	a='non palindromo'

print '%r'%a
  • a parte qualche piccola correzione sintattica(inizzializzazioni,parentesi,etc.) questo codice si presta molto ad essere portato in c.

... ma e' un po' prolisso (rd 20131101). La traduzione del loop C:

  for (t=s+(strlen(s)-1); s < t; s++, t--)
    if (*t != *s) return 0;
  return 1;

puo' essere fatta in modo piu' compatto.

def pal(word):
   for i in range(len(word)//2):
     if word[i] != word[-(i+1)]: return False
   else:
     return True

Notate, plz, l'uso dell'else nel for. Anche se qui e' inutile per la correttezza del risultato, rende il codice piu' leggibile: indica che l'assegnamento a True viene effettuato solo se si completano tutti i cicli del loop.


  • Non avevo pensato alla possibilità dell'indice negativo che effettivamente è molto elegante (lo voglio provare per una mia versione ricorsiva):
def pal_ric_supp(w,i):
	if i>=len(w)/2:
		return True
	else:
		if w[i]!=w[-i-1]:
			return False
		else:
			return pal_ric_supp(w,i+1)

def pal_ric(w):
	if len(w)<2:
		return True
	else:
		return pal_ric_supp(w,0)

-Fede