Si quiero generar una matriz que va del 1 al 6 y aumenta en .01, ¿cuál es la forma más eficiente de hacerlo?C# Matriz de incrementos
Lo que yo quiero es una matriz, con minutos y MAXS sujetas a cambios después ... como esto: x[1,1.01,1.02,1.03...]
Si quiero generar una matriz que va del 1 al 6 y aumenta en .01, ¿cuál es la forma más eficiente de hacerlo?C# Matriz de incrementos
Lo que yo quiero es una matriz, con minutos y MAXS sujetas a cambios después ... como esto: x[1,1.01,1.02,1.03...]
Suponiendo una start
, end
y un valor increment
, puede abstracta esta otra:
Enumerable
.Repeat(start, (int)((end - start)/increment) + 1)
.Select((tr, ti) => tr + (increment * ti))
.ToList()
Vamos a desglosarlo:
Enumerable.Repeat
toma un número inicial, se repite para un número dado de elementos y devuelve un enumerable (Una colección). En este caso, empezamos con el elemento start
, encontrar la diferencia entre start
y end
y se divide por el increment
(esto nos da el número de incrementos entre start
y end
) y agregue para incluir el número original. Esto debería darnos la cantidad de elementos para usar. Solo ten en cuenta que dado que el increment
es un decimal/doble, puede haber errores de redondeo cuando selecciones un int.
Select
transforma todos los elementos de un enumerable dada una función de selector específico. En este caso, tomamos el número que se generó y el índice, y agregamos el número original con el índice multiplicado por el incremento.
Finalmente, la llamada al ToList
guardará la colección en la memoria.
Si usted se encuentra el uso de esta frecuencia, entonces usted puede crear un método para hacer esto para usted:
public static List<decimal> RangeIncrement(decimal start, decimal end, decimal increment)
{
return Enumerable
.Repeat(start, (int)((end - start)/increment) + 1)
.Select((tr, ti) => tr + (increment * ti))
.ToList()
}
Editar: Se ha cambiado al uso de la repetición, por lo que todavía se mantienen los valores de número no entero. Además, no se realiza ningún control de errores aquí, por lo que debe asegurarse de comprobar que increment
no es 0 y que start
< end * sign(increment
). La razón para multiplicar el extremo por el signo de incremento es que si está incrementando en un número negativo, el final debe ser antes del inicio.
+1 para mostrar realmente de dónde provienen los números (y para usar 'decimal') –
lo que haga, no utilice un tipo de datos de punto flotante (como double
), que don' Trabajar para cosas como esta en nombre del comportamiento de redondeo. Vaya para decimal
, o enteros con un factor. Para este último:
Decimal[] decs = new Decimal[500];
for (int i = 0; i < 500; i++){
decs[i] = (new Decimal(i)/100)+1 ;
}
no estoy de acuerdo con "lo que sea que hagas, no uses el tipo de datos de coma flotante" http://stackoverflow.com/questions/618535/what-is-the-difference-between-decimal-float-and-double-in -c – gsharp
Iba a la definición más tradicional de 'punto flotante binario' de coma flotante;) – Martijn
La forma más sencilla es utilizar Enumerable.Range
:
double[] result = Enumerable.Range(100, 500)
.Select(i => (double)i/100)
.ToArray();
(por lo tanto, eficiente en términos de facilidad de lectura y líneas de código)
Buena respuesta. Una corrección: el rango que desea es Enumerable.Range (100, 600). – jdmcnair
Probablemente debería basar todos los números del inicio, el final y el incremento, en lugar de calcularlos todos de antemano y pegar los números mágicos en el código. – Servy
@jdmcnair: corregido, aunque su 'Rango (100, 600)' sería un rango de 1 a 7. Tenga en cuenta que lo anterior excluye '6.00', si lo necesita, tome 501. –
var ia = new float[500]; //guesstimate
var x = 0;
for(float i =1; i <6.01; i+= 0.01){
ia[x] = i;
x++;
}
Se podría multi-hilo esto para la velocidad, pero probablemente no vale la pena la sobrecarga a menos que planees ejecutar esto en un procesador realmente muy lento.
Pero no puedo acceder a 'ia' fuera del ciclo, ¿o sí? ¿No es esto un problema de alcance? –
No entiendo lo que quiere decir, ia no se definió dentro del bucle, por lo tanto, su alcance no está limitado al interior del bucle –
Primero: eso no cabe en esa matriz. En segundo lugar, la conversión de estrechamiento implícito no funciona, necesita i + = 0.01F para esto, en tercer lugar, comenzará a recibir errores de redondeo en 1.52 – Martijn
utilizar un bucle con incrementos de 0,01:
List<decimal> myList = new List<decimal>();
for (decimal i = 1; i <= 6; i+=0.01)
{
myList.Add(i);
}
elegante
double[] v = Enumerable.Range(1, 600).Select(x => x * 0.01).ToArray();
eficiente
Use for loop
me acaba de hacer una simple función.
public IEnumerable<decimal> GetValues(decimal start, decimal end, decimal increment)
{
for (decimal i = start; i <= end; i += increment)
yield return i;
}
Luego puede convertir eso en una matriz, consultarla o hacer lo que quiera con ella.
decimal[] result1 = GetValues(1.0m, 6.0m, .01m).ToArray();
List<decimal> result2 = GetValues(1.0m, 6.0m, .01m).ToList();
List<decimal> result3 = GetValues(1.0m, 6.0m, .01m).Where(d => d > 3 && d < 4).ToList();
Me gusta esta solución de la mejor manera, ya que es simple y tiene muy poca sobrecarga en comparación con el uso de LINQ (no tiene que enumerar la colección dos veces, primero para construir el enumerable con rango/repetición, segundo para la función Seleccionar). – SPFiredrake
Puede resolverlo así. El método de solución devuelve un arreglo doble
double[] Solution(double min, int length, double increment)
{
double[] arr = new double[length];
double value = min;
arr[0] = value;
for (int i = 1; i<length; i++)
{
value += increment;
arr[i] = value;
}
return arr;
}
¿Qué tal utilizar un bucle con un valor decimal? – Terminador
Definir eficiente ... ¿menos código? ¿O más rápido? –
¿Incrementar por .01 los valores dentro de la matriz? o incrementar el tamaño de la matriz en 1? – gsharp