Distanza di editing

di il
7 risposte

Distanza di editing

Ciao a tutti ho bisogno di una dritta su un problema.
Ho dovuto calcolare la minima distanza di editing tra due stringhe e l ho fatto attraverso l algoritmo di Levenshtein e fin qui tutto bene....
il mio problema consiste ne dover stampare quali operazioni vengono eseguite per modificare la prima parola nella seconda coi relativi input ....
cioè se inserisco una lettera devo anche dire in che posizione e specificare la lettera.
Mi potreste aiutare in qualche modo ?
Grazie mille in anticipo

7 Risposte

  • Re: Distanza di editing

    E dove sta il problema? In Java si usa System.out.println() per stampare.
    Magari posta l'algoritmo o una parte interessante di esso per essere aiutato meglio.
    Ti posso già dire che se hai implementato l'algoritmo in modo modulare (cioè hai risolto i sottoproblemi separatamente e poi li hai messi insieme) anzichè in un unico blocco, hai già qualche vantaggio.
  • Re: Distanza di editing

    L algoritmo è questo
    	public static int distanzaEditing (CharSequence lhs, CharSequence rhs) {                          
    		    int len0 = lhs.length() + 1;                                                     
    		    int len1 = rhs.length() + 1;                                                     
    		    int cost_replace =0;
    		    int cost_insert =0;
                int cost_delete =0;
    		    // the array of distances                                                       
    		    int[] cost = new int[len0];                                                     
    		    int[] newcost = new int[len0];                                                  
    		                                                                                    
    		    // initial cost of skipping prefix in String s0                                 
    		    for (int i = 0; i < len0; i++) cost[i] = i;                                     
    		                                                                                    
    		    // dynamically computing the array of distances                                  
    		                                                                                    
    		    // transformation cost for each letter in s1                                    
    		    for (int j = 1; j < len1; j++) {                                                
    		        // initial cost of skipping prefix in String s1                             
    		        newcost[0] = j;                                                             
    		                                                                                    
    		        // transformation cost for each letter in s0                                
    		        for(int i = 1; i < len0; i++) {                                             
    		            // matching current letters in both strings                             
    		            int match = (lhs.charAt(i - 1) == rhs.charAt(j - 1)) ? 0 : 1;             
    		                                                                                    
    		            // computing cost for each transformation                               
    		             cost_replace = cost[i - 1] + match;                                 
    		             cost_insert  = cost[i] + 1;                                         
    		             cost_delete  = newcost[i - 1] + 1;                                  
    		                                                                                    
    		            // keep minimum cost                                                    
    		            newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);
    		        }                                                                           
    		                                                                                    
    		        // swap cost/newcost arrays                                                 
    		        int[] swap = cost; 
    		        cost = newcost; 
    		        newcost = swap;                          
    		    }
    		    
    		                                                                                    
    		    // the distance is the cost for transforming all letters in both strings        
    		    return cost[len0 - 1] ;                                                          
    		}
    
    io da qui dovrei estrapolare gli indici (e nel caso della sostituzione e aggiunta anche il carattere ) che poi dovrò stampare per ciascun metodo di editing.
    Come potrei fare ?
  • Re: Distanza di editing

    Da quello che mi pare di capire, tu non sai quale operazione di modifica avviene quando le lettere sono diverse. Cioè
    //ok, occorre una modifica
    int match = (lhs.charAt(i - 1) == rhs.charAt(j - 1)) ? 0 : 1;
          
    //che può essere una replace, una insert o una delete
    cost_replace = cost[i - 1] + match;                                 
    cost_insert  = cost[i] + 1;                                         
    cost_delete  = newcost[i - 1] + 1;
    
    //comunque non mi importa che tipo di modfica è, "conta sempre come uno!"
    newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);
    Gli indici comunque li hai, sono i e j, quindi ti resta da capire se questi sono coinvolti in una replace, in una insert o in una delete.

    Per farla breve a te serve l'algoritmo costruttivo che a partire da due stringhe A e B, ti indica i passi per trasformare A in B.
  • Re: Distanza di editing

    Esattamente .....E ora la domanda sorge spontanea
    Come faccio ?
  • Re: Distanza di editing

    In questo momento non conosco un algoritmo del genere.
    Comunque provo a ragionare.
    Sia n la lunghezza della stringa A e m la lunghezza della stringa B:

    1) Caso n=m.
    Non servono inserimenti o rimozioni ma eventualmente solo delle sostituzioni.
    Casi particolari:
    A=B non c'è da fare nulla.
    Per ogni 0<=i<n il carattere A è diverso dal carattere B; in questo caso servono n sostituzioni.
    2) Caso n<m.
    Non servono cancellazioni ma solo inserimenti e eventualmente sostituzioni. In particolare servono m-n inserimenti e k sostituzioni,
    con k numero dei caratteri diversi.
    3) Caso n>m.
    Non servono inserimenti ma solo cancellazioni e eventualmente sostituzioni. In particolare servono n-m cancellazioni e k sostituzioni.
  • Re: Distanza di editing

    Dopo tanto tempo riprendo questo thread perchè son riuscito dopo varie ricerche a stampare la distanza minima di editing tra due stringhe ma ho qualche difficoltà nello scorrere la latrice per identificare le operazioni .
    posto tutto il codice se qualcuno riesce a darci un occhiata e darmi qualche suggerimento ....
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    public class DistanzaDiEditing {
    	
    	
    	private static int[][] matriceDiAdiacenza ;
    	
    	
    	public static String distanza(String str1,String str2){
    	
    		String operazioni=" op: ";
    		int lunghezza1 = str1.length();
    		int lunghezza2 = str2.length();
    		 matriceDiAdiacenza = new int[lunghezza1+1][lunghezza2+1];
    		int match; 
    		
    		/*riempimento della riga 0 della matrice di adiacenza*/
    		for(int i = 0 ; i <= lunghezza1 ; i++){
    			matriceDiAdiacenza[i][0]=i;
    		}
    		/*riempimento della colonna 0 della matrice di adiacenza*/
    		for(int j = 0 ; j <= lunghezza2 ;j++){
    			matriceDiAdiacenza[0][j]=j;
    		}
    		/*Calcolo della distanza tra tutte le sottosringhe delineate nella matrice*/
    	
    		for(int i = 1 ; i <= lunghezza1 ;i++){
    			for( int j=1 ;j <= lunghezza2 ; j++){
    				//valuto se i caratteri son uguali 
    				if(str1.charAt(i-1)==str2.charAt(j-1)){
    					match = 0;
    				}else{
    					match = 1;
    					}
    					matriceDiAdiacenza[i][j]=Math.min(matriceDiAdiacenza[i-1][j]+1// costo cancellazione
    							,Math.min(matriceDiAdiacenza[i][j-1]+1,//costo inserzione
    									matriceDiAdiacenza[i-1][j-1]+match));// costo sostituzione
    				if(i>1 && j>1 && str1.charAt(i-1)==str2.charAt(j-2)&&str1.charAt(i-2)==str2.charAt(j-1)){
    					matriceDiAdiacenza[i][j]= Math.min(matriceDiAdiacenza[i][j],matriceDiAdiacenza[i-2][j-2]+match);//costo scambio
    				}
    				 
    				// System.out.print(matriceDiAdiacenza[i-1][j-1]+"\t");
    			}
    			
    			
    		}
    		for(int i = 0 ; i < matriceDiAdiacenza.length ;i++){
    			for(int j=0 ;j <matriceDiAdiacenza[i].length ; j++){
    				 System.out.print(matriceDiAdiacenza[i][j]+"\t");
    			}
    			// System.out.print(matriceDiAdiacenza[i][0]+"\n");
    			 System.out.print("\n");
    			}
    		   int k = 0;
    		   int h = 0;
    		 for( k=1,h=1 ; k < matriceDiAdiacenza.length ;k++,h++){
    				//if(k>1 && h>1 && str1.charAt(k-1)==str2.charAt(h-2)&&str1.charAt(k-2)==str2.charAt(h-1))
    		
    			 if(matriceDiAdiacenza[k][h]== (matriceDiAdiacenza[k][h-1])){
    	  			 operazioni += "canc("+ k + ") ";
    	  			 if(k < matriceDiAdiacenza.length-1)
    	    	     k++;
    	    	   }
    	  		  
    	  		   
    		  }  
    	  		   
    		
    		return matriceDiAdiacenza[lunghezza1][lunghezza2] +"\n" +operazioni;
    		
    	}
    	
    }
    
    in particolare in questa parte
    
    	           int k = 0;
    		   int h = 0;
    		 for( k=1,h=1 ; k < matriceDiAdiacenza.length ;k++,h++){
    				//if(k>1 && h>1 && str1.charAt(k-1)==str2.charAt(h-2)&&str1.charAt(k-2)==str2.charAt(h-1))
    		
    			 if(matriceDiAdiacenza[k][h]== (matriceDiAdiacenza[k][h-1])){
    	  			 operazioni += "canc("+ k + ") ";
    	  			 if(k < matriceDiAdiacenza.length-1)
    	    	     k++;
    	    	   }
    	  		  
    	  		   
    		  }  
    	  		   
    
    che mi lancia un eccezione se ci son più di due caratteri cancellati
  • Re: Distanza di editing

    Il medesimo thread è già stato aperto su http://www.ioprogrammo.it/index.php?topic=26755.msg97405;topicseen#msg97405, in violazione alla regola sul cross posting. Il presente viene pertanto chiuso.
Devi accedere o registrarti per scrivere nel forum
7 risposte