Algoritmo per generazione di variabili ottimizzata senza collisioni?

1

Sto cercando un algoritmo in grado di generare nomi di variabili ottimizzati sintatticamente validi (per javascript in questo caso) senza collisioni.

Quindi come regola generale vorrei qualcosa che ha generato

aa, ab, ac .... az, a1, a2, a3, a4, a5, a6, a7, a8, a9 ba, bb, bc .... bz, b1 .... zz ... z9 ... aaa, AAB ....

non li genera in una volta, passa attraverso una base di codice e lo fa ogni volta che vengono trovate determinate condizioni (questo verrà effettivamente fatto usando un plugin gulp in modo che questo non debba prendere in considerazione l'AST in considerazione ). Pertanto, deve essere in grado di sapere quale dovrebbe essere la variabile corrente da generare sulla base dell'ultima variabile.

Quindi, se l'ultima variabile è aaz, saprebbe fare aa1 e se l'ultima variabile è azz, saprebbe fare az1 e così via.

    
posta user254694 30.09.2015 - 10:41
fonte

1 risposta

3

Ci sono molti nomi di variabili più validi di quelli generati dalla serie nella tua domanda, ma ci andrò perché è semplice e potrebbe essere abbastanza buono.

Idealmente dovremmo tenere traccia di quante variabili sono state generate e semplicemente mappare quel numero al nome della variabile successiva. Affrontare la variabile nameSeed incrementale dovrebbe essere semplice, e c'è una funzione molto utile per il prossimo passo in JavaScript, che corrisponde esattamente alla nostra funzionalità desiderata quasi : Number#toString(radix) . radix è 10 di default (dando la rappresentazione decimale del numero) ma può essere fino a 36, che include non solo le cifre 0-9 ma anche le lettere a-z.

Ad esempio, (30).toString(36)u . (400).toString(36)b4 . Sfortunatamente, (1).toString(36) fornisce 1 , che non è un identificatore valido e ci sono infinitamente più casi in cui si verifica lo stesso tipo di errore ...

Se vuoi solo "tipo di minimo", puoi anteporre _ e avere un identificatore valido.

Se vuoi veramente minimo (entro i limiti di 0-9, a-z), dobbiamo modificare l'algoritmo per evitare quei nomi non validi. Dobbiamo anche evitare cose come undefined , var , ecc. Potrebbe esserci una buona strategia per fare questo "in modo preventivo", ma semplicemente convaliderò il risultato e correggendolo (così come la nameSeed ) se ha bisogno di essere riparato.

La funzione seguente accetta un seme da utilizzare per il nome e restituisce il nome generato e il successivo potenziale seme. Se il seme dato produce un risultato non valido, utilizza il primo seme valido più grande del seme dato (se tutti i semi fossero validi, non dovremmo restituire il "prossimo", ma ora è necessario poiché potremmo aver saltato un po ').

function generateName( seed ) {
  var name = seed.toString( 36 );
  if ( isNaN( name.substring( 0, 1 ) ) ) {
    // The name starts with a letter, now see if it collides with any builtins
    if ( builtins.indexOf( name ) < 0 ) {
      // Got a good name
      return { nextSeed: seed + 1, name: name };
    } else {
      // There's a collision, try the next seed
      return generateName( seed + 1 );
    }
  } else {
    // The name starts with a digit, just replace it with 'a' and try again
    // We could use the same strategy as above (just increment seed), but that might take a long time... better to jump to something with a good chance of working.
    name = "a" + name.substring( 1 );
    var newSeed = parseInt( name, 36 );
    return generateName( newSeed );
  }
}

Costruire l'array builtins è lasciato come esercizio per il lettore ...

    
risposta data 30.09.2015 - 11:31
fonte

Leggi altre domande sui tag