/// <summary> /// ermittelt alle einzel und doppel Kombinationen aller Widerstände und gibt diese sortiert zurück /// </summary> /// <param name="allResistors">Liste mit allen Basis-Widerständen</param> /// <returns>fertig sortierte Liste mit entsprechenden Widerständen</returns> static KeyValuePair <long, Resistor>[] GetAllDoubles(Resistor[] allResistors) { if (doubleCache != null) { return(doubleCache); } var result = new KeyValuePair <long, Resistor> [allResistors.Length * allResistors.Length]; int p = 0; foreach (var r in allResistors) { result[p++] = new KeyValuePair <long, Resistor>(r.valueMilliOhm, r); } // --- serielle und parallele Kombinationen sammeln --- for (int y = 0; y < allResistors.Length - 1; y++) { for (int x = y + 1; x < allResistors.Length; x++) { var rs = new ResistorCombined(true, allResistors[x], allResistors[y]); var rp = new ResistorCombined(false, allResistors[x], allResistors[y]); result[p++] = new KeyValuePair <long, Resistor>(rs.valueMilliOhm, rs); result[p++] = new KeyValuePair <long, Resistor>(rp.valueMilliOhm, rp); } } Array.Sort(result, (x, y) => x.Key.CompareTo(y.Key)); return(doubleCache = result); }
/// <summary> /// Suchmethode, um passende Widerstände bzw. deren Kombinationen zu finden /// </summary> /// <param name="allResistors">Alle Widerstände, welche zur Verfügung stehen</param> /// <param name="searchValue">gesuchter Widerstandswert</param> /// <param name="maxResistors">optional: gibt die maximale Anzahl der kombinierbaren Widerstände an, welche verwendet werden dürfen (default: 2)</param> /// <param name="maxError">optional: maximale Abweichung des Ergebnisses (default: 1.10 = 10 % Abweichung)</param> /// <returns>Enumerable der gefundenen Ergebnisse</returns> public static IEnumerable <ResistorResult> Search(Resistor[] allResistors, Resistor searchValue, int maxResistors = 2, double maxError = 1.10) { if (allResistors.Length < 2) { yield break; } long search = searchValue.valueMilliOhm; long max = (long)(search * maxError) - search; foreach (var r in allResistors) { long err = Math.Abs(r.valueMilliOhm - search); if (err <= max) { yield return(new ResistorResult(r, err)); } } var fullList = GetAllDoubles(allResistors); var fullRevList = GetAllRevDoubles(allResistors); if (maxResistors >= 2) // 2-teilige Suche { int p = BinarySearch(fullList, search - max); while (p < fullList.Length && fullList[p].Key - search < max) { yield return(new ResistorResult(fullList[p].Value, Math.Abs(search - fullList[p].Key))); p++; } } if (maxResistors >= 3) { // --- 3er Kombination - seriell --- for (int z = 0; z < allResistors.Length - 2; z++) { for (int y = z + 1; y < allResistors.Length - 1; y++) { for (int x = y + 1; x < allResistors.Length; x++) { long err = Math.Abs(allResistors[x].valueMilliOhm + allResistors[y].valueMilliOhm + allResistors[z].valueMilliOhm - search); if (err <= max) { yield return(new ResistorResult(new ResistorCombined(true, allResistors[x], allResistors[y], allResistors[z]), err)); } } } } // --- 3er Kombination - parallel --- for (int z = 0; z < allResistors.Length - 2; z++) { for (int y = z + 1; y < allResistors.Length - 1; y++) { for (int x = y + 1; x < allResistors.Length; x++) { var c = new ResistorCombined(false, allResistors[x], allResistors[y], allResistors[z]); long err = Math.Abs(c.valueMilliOhm - search); if (err <= max) { yield return(new ResistorResult(c, err)); } } } } } }