Newsgroup: it.comp.lang.c
Titolo: Algoritmo per Anagrammi (!Aiuto! dai GURU)

Ho pensato anche alla ricorsione, ma non mi viene in mente come sfruttarla.
Ecco la soluzione ricorsiva :
var s         : string;
    stack     : string;
    stack_idx : longint;
function estratto(t : string; i : integer) : string;
begin
  delete(t, i, 1);
  estratto := t;
end;
procedure scrivi_anagrammi(t : string);
var i : integer;
begin
  if length(t) = 0 then
  begin
    inc(stack_idx);
    writeln(stack_idx:5, ') ' + stack);
  end
  else
    for i := 1 to length(t) do
    begin
      stack := stack + t[i];
      scrivi_anagrammi(estratto(t, i));
      stack := copy(stack, 1, length(stack)-1);
    end;
end;
begin
  stack := '';
  stack_idx := 0;
  write('parola : '); readln(s);
  scrivi_anagrammi(s);
end.
Io l'ho pensata cosi' :
Scrivere gli algoritmi di ROMA equivale a scrivere di volta in volta
R antecedente tutti gli anagrammi di OMA
O antecedente tutti gli anagrammi di RMA
M antecedente tutti gli anagrammi di ROA
A antecedente tutti gli anagrammi di ROM
e cosi' via per ciascuno degli estratti cioe', per esempio per 'OMA'
O antecedente tutti gli anagrammi di MA
M antecedente tutti gli anagrammi di OA
A antecedente tutti gli anagrammi di OM
etc.... etc...
Andrea, mica uno qualunque...
--------------------------------------------------
"Ho cambiato signature, si vede ?"
--
Posted from 
itaca.ulysse.it
 [195.223.254.1]
via Mailgate.ORG Server - 
http://www.mailgate.org
------------ END MSG -------------
Per sfizio io ho cecato di tradurlo in linguaggio C senza snaturarlo nel
seguente modo :
(vi ho impiegato 10 minuti e si vede)
--- Inizio PROG ---
#include <stdio.h>
#include <string.h>
char s[255];
char stack[255];
int stack_idx=0;
void cancella ( char * p, int i )
{
  int ii;
  ii=i;
  while(p[ii]!='\0')
  {
      p[ii]=p[ii+1];
      ii++;
  }
}
char* estratto ( char* t, int i)
{
  char temp[255];
  strcpy(temp,t);
  cancella(temp,i);
  return(temp);
}
void scrivi ( char* t)
{
 int i;
 int ul;
 char te[255];
 if (strlen(t)==0) {
    stack_idx++;
    printf("%d ) %s\n",stack_idx,stack);
  }
 else
    for (i=0; i<strlen(t); i++)
     {
 ul=strlen(stack);
 stack[ul]=t[i];
 stack[ul+1]='\0';
 strcpy(te,t);
 scrivi(estratto(t,i));
 strcpy(t,te);
 stack[strlen(stack)-1]='\0';
     }
}
void main()
{
  printf("parola :\n");
  scanf("%s",s);
  scrivi(s);
}
--- Fine Prog.-----
Per funzionare funziona, ma non mi sembra una soluzione molto elegante:
vari motivi sono l'uso:
1) delle stringhe te e temp per evitare che nella ricorsione t venga
distrutto;
2) delle variabile "globali":  s,stack e stack_idx che dovrebbe essere
passate alle funzioni;
3) etc...
C'è qualche programmatore che mi può illuminare?
Ringrazio tutti anticipatamente dei consigli ( astenersi dagli insulti,
Thanx ).

C'h qualche programmatore che mi pur illuminare?
Be', essendo io l'autore di quel programma scritto in pascal, credo di essere il
piu' motivato a risponderti ;-) 
Ecco, di seguito, la versione in linguaggio C con tutte le ottimizzazioni del
caso :
#include <stdio.h>
#include <string.h>
typedef char string[256] ;
typedef struct { unsigned long idx;
                 string buffer;
               } buffer_record ;
char * estratto( char * t, int i )
{
   string temp;
   strcpy(temp, t);
   while (temp[i] = temp[i+1]) ++i;
   return ( temp );
}
char * concat_char( char * s, char c )
{
       unsigned l = strlen( s ) ;
       s[l] = c ;
       s[l+1] = '\0' ;
       return s;
}
char * remove_last_char( char * s )
{
      unsigned l = strlen( s ) ;
      s[l-1] = s[l];
      return ( s ) ;
}
void scrivi_anagrammi( char * t, buffer_record * a )
{
  unsigned i, len = strlen( t );
  if ( len )
  {
    for ( i = 0 ; i < len ; i++ )
    {
	concat_char( a->buffer, t[i] ) ;
	scrivi_anagrammi( estratto( t, i ), a );
        remove_last_char( a->buffer ) ;
    }
  }
  else
    printf("%5lu) %s\n", ++(a->idx), a->buffer );
}
int main()
{
  string mio ;
  buffer_record mio_record = { 0, "" };
  printf("inserisci parola : "); gets( mio );
  scrivi_anagrammi( mio, &mio_record );
  return 0;
}
 ___
(___)
()__
(___)
 __()
(___)
Skyscraper
----------------------------------------------------------------
"Sopra il camper la capra campa, sotto il camper la capra crepa"


piu' motivato a risponderti ;-)
Grazie per la tempestività e la chiarezza del codice...
Ma scusami l'ignoranza,
avendo scaricato il news da W95 ( e non Linux ) l'ho provato subito ( con un
bel taglia e incolla ) su Turbo C++
e per parole con due lettere funge, con tre caratteri entra in loop nella
stampa...
Mi riprometto di provarlo con il gcc di Linux.
Dove ho sbagliato, forse nell'utilizzo del compilatore DOS sotto Windoz ?
Grazie ancora.

Dove ho sbagliato, forse nell'utilizzo del compilatore DOS sotto Windoz ?
Probabilmente, ma non ne sono sicuro...
Skyscraper
---------------------------
andrea_...@bigfoot.com
