2011-08-16 11 views
7

Tengo una matriz de grados, [10, 90, 200, 280, 355] para un círculo.Dado un grado x, encuentre el grado más cercano en un conjunto de grados

Me otorgaron un título, digamos 1. ¿Cómo puedo determinar que 1 está más cerca de 355 grados?

+0

+1, que tenían la misma tarea recientemente y mi solución es libre de errores, así que estoy interesado en ver si hay algunas otras implementaciones antes intente y corrija :-) –

Respuesta

0

Tiene un valor que contendrá el grado de cierre encontrado found_degree y uno para la diferencia real degree_difference.

A continuación, itere sobre toda la matriz y calcule dos valores: abs(degree_at_position - target_degree) y abs(degree_at_position - 360 - target_degree). Si uno de esos valores es menor que degree_difference, tiene un grado más cercano - guárdelo en found_degree y actualice degree_difference en consecuencia.

Eso es todo.

Usted tal vez debe inicializar found_degree con -1 y degree_difference con 360, sólo para asegurarse de que puede interpretar correctamente el resultado en caso de una matriz dada vacío, así - o simplemente manejar el caso de una matriz de entrada vacía por separado.

¿Es esto una tarea, por cierto?

4

Reste los dos números. Si la diferencia es mayor por encima de 180 [o por debajo de -180], reste [o agregue] 360. Ahora puede simplemente comparar los valores absolutos de la diferencia.

+0

+1 pero necesita obtener el valor absoluto de la diferencia y compare con 180 (por ejemplo, podría ser -200), luego reste de 360. – RobG

+0

@RobG, buen punto. He editado la respuesta en consecuencia. –

4

Aquí es una fórmula real:

degreediff = min(abs(x-y),360-abs(x-y)) 
0

El método de fuerza bruta sería algo como esto:

var closestElement; 
var closestDivergence = 360; 

var toCompare = 355; 
var choices = [1, 90, 200, 280, 355]; 

for(i=0;i<choices.length;i++){ 
    var currentDivergence=choices[i] - toCompare; 
    if (currentDivergence<0) { 
     currentDivergence+=360; 
    } 
    if (currentDivergence < closestDivergence){ 
     closestDivergence = currentDivergence; 
     closestElement = i; 
    } 
} 

if (closestElement != NaN){ 
    alert('Closest value is '+choices[closestElement]); 
} 
+1

No funcionará para valores cercanos a cero, p. 1 está más cerca de 355 que 10 (por OP). – RobG

+0

Muy bien, he modificado mi respuesta. –

0

Aquí hay un pequeño polvo rápido

function closest(deg,ar) { 
    return ar.sort(function(a,b){var c = deg; return Math.min(360 - (a-c),Math.abs(a-c)) - Math.min(360 - (b-c),Math.abs(b-c))}) 
} 
var myArray = [355, 280, 200, 181, 90, 30]; 
alert(closest(180,myArray)); 

Clasifica y devuelve el arreglo de acuerdo con cuál es el más cercano al grado proporcionado. El índice 0 es el más cercano. Envuelve haciendo que 355 esté más cerca de 0 que 10.

0

Primero verifique la matriz (verifique qué elemento está más cerca) usando el grado dado (1 en su ejemplo), luego agregue 360 ​​y verifique con ese grado (361). Comparar qué resultado es mejor:

x el grado dado, y el primer resultado, z el segundo resultado

if (abs(x-y) < 360+x-z) 
    choose y; 
else 
    choose z; 

Si se ordena la matriz se puede comprobar con una especie binario que le da O (log n) tiempo en el peor de los casos. De lo contrario, tiene que navegar por toda la matriz dos veces.

0

Esta fórmula solo funcionará con círculos. Es pseudo código, por supuesto.

degree diff = min(abs(x-y),360-abs(x-y)) 
0

utilizando los comentarios en esta página me las arreglé para llegar a este código:

function closest(deg, degs) { 

deg = (deg/360 > 1 ? deg - (Math.floor(deg/360)*360) : deg); 

var difference = 360; 
var closest = -1; 

for(i=0;i<degs.length;i++) { 

    var x = degs[i]; 

    var diff = Math.min(Math.abs(x-deg),360-Math.abs(x-deg)) 

    if(diff <= difference) { 
     closest = i; 
     difference = diff; 
    } 
}; 

return closest; 

}

más cercano (1000, [10, 90, 200, 280, 355]) ;

1

Esto es más compacto y eficiente:

function difference(a, b) { 
    var d = Math.abs(a - b); 
    return d > 180 ? 360 - d : d; 
}; 

function closest(a, bs) { 
    var ds = bs.map(function(b) { return difference(a, b); }); 
    return bs[ds.indexOf(Math.min.apply(null, ds))]; 
}; 

> difference(1, 355) 
6 

> closest(1, [10, 90, 200, 280, 355]) 
355 
Cuestiones relacionadas