Calcolo delle distanze variabili

0

Sto tentando di scrivere un algoritmo che calcola la distanza tra le vertebre. Il parser di testo funziona già perfettamente nel selezionare i riferimenti vertebrali (cervicale 6, c-6, c6, c sei, cervicale sei).

Attualmente fa riferimento a un array di stringhe lineari e abbina Vertebra al loro indice, quindi sottrae Min da Max . Il risolve il 95% dei casi.

Il problema arriva da due scenari:

  • La distanza non è necessariamente lineare. Da L5 a Pelvis e da L5 a Sacrum sono entrambi considerati di un livello.
  • Le anomalie genetiche possono produrre vertebre extra. La maggior parte delle persone ha 12 vertebre toraciche, alcune ne hanno fino a 14.

Se avessi solo bisogno di risolvere l'uno o l'altro, non sarebbe un problema. Ora sto esaminando un complicato caos di soluzioni alternative per farlo funzionare, e sono certo che c'è una risposta più semplice.

private static int CalculateLevelNumber(IEnumerable<string> levels)
{
    List<int> levelindexes = new List<int>();
    List<string> spinemap = new List<string> { "occiput", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "l1", "l2", "l3", "l4", "l5", "s1", "s2" };

    foreach(string level in levels)
    {
        levelindexes.Add(spinemap.IndexOf(level));
    }

    return levelindexes.Max() - levelindexes.Min();
}

Ecco cosa intendo per brutta soluzione:

private static int CalculateLevelNumber(IEnumerable<string> levels)
{
    List<int> levelindexes = new List<int>();
    List<string> spinemap = new List<string> { "occiput", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "l1", "l2", "l3", "l4", "l5", "s1", "s2" };

    if(levels.Contains("t15"))
    {
        spinemap.InsertRange(spinemap.IndexOf("t12"), new List<string> { "t13", "t14", "t15" });
    }
    else if(levels.Contains("t14"))
    {
        spinemap.InsertRange(spinemap.IndexOf("t12"), new List<string> { "t13", "t14" });
    }
    else if (levels.Contains("t13"))
    {
        spinemap.InsertRange(spinemap.IndexOf("t12"), new List<string> { "t13" });
    }

    foreach (string level in levels)
    {
        if(level == "pelvis" || level == "ilium")
            levelindexes.Add(spinemap.IndexOf("s1"));
        else
            levelindexes.Add(spinemap.IndexOf(level));
    }

    return levelindexes.Max() - levelindexes.Min();
}
    
posta Wesley 14.04.2016 - 17:58
fonte

1 risposta

1

Bene, per i principianti, suppongo che avrei precomputo in anticipo diverse%% di elenchi dispinemap, e tenerli immutabili durante l'esecuzione dei calcoli, invece di scegliere quello giusto da utilizzare per ciascun caso.

Per finire, userei array di int invece di array di string per spinemap s. Trasformerei level s da string form a enum , e uso quel enum per indicizzare in spinemap . Gli array spinemap memorizzerebbero la posizione int direttamente su ciascun indice enum level .

Quindi avremmo quattro (?) spinemap s come matrice di int posizione indicizzabile per enum level , precalcolato e non modificato durante il calcolo.

Ci sono un certo numero di altre possibilità, inclusa la definizione di una classe per raggruppare i nomi insieme alle posizioni, il che potrebbe richiedere un po 'più di ricerca, ma potrebbe essere più gestibile. Potremmo anche iniziare con una serie di definizioni facilmente mantenute e leggibili, e quindi costruire le strutture di dati precalcolate necessarie da quella in modo da non dover fare così tante ricerche durante il calcolo.

    
risposta data 14.04.2016 - 18:41
fonte

Leggi altre domande sui tag