В эти выходные я провожу несколько минут, перегружая вместе алгоритм, который взял бы в заголовке (в градусах) и возвратил бы Строку для кардинального направления (я использую его в приложении компаса андроида, которое я использую). То, с чем я закончил, было этим:
private String headingToString(Float heading)
{
String strHeading = "?";
Hashtable<String, Float> cardinal = new Hashtable<String, Float>();
cardinal.put("North_1", new Float(0));
cardinal.put("Northeast", new Float(45));
cardinal.put("East", new Float(90));
cardinal.put("Southeast", new Float(135));
cardinal.put("South", new Float(180));
cardinal.put("Southwest", new Float(225));
cardinal.put("West", new Float(270));
cardinal.put("Northwest", new Float(315));
cardinal.put("North_2", new Float(360));
for (String key: cardinal.keySet())
{
Float value = cardinal.get(key);
if (Math.abs(heading - value) < 30)
{
strHeading = key;
if (key.contains("North_"))
{
strHeading = "North";
}
break;
}
}
return strHeading;
}
Мой вопрос, действительно ли это - лучший способ сделать это? Это, должно быть, делалось много раз прежде, хотя я еще не сделал поиска примеров в сети. Какие-либо другие люди попробовали это и нашли более опрятное решение?
Редактирование для Thilo Reverand, ответы shinjin и Chrstoffer:
Решение
public static String headingToString2(double x)
{
String directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"};
return directions[ (int)Math.round(( ((double)x % 360) / 45)) ];
}
Это нормально в большинстве случаев, хотя для того, чтобы сделать его оптимизированным и (IMO) Cleaner, что вы можете сделать, это найти функцию, чтобы связать входную заголовок к одному использованному на карте.
Например: (Я уверен, что это правильно, но вы захотите проверить его)
45* (int)Math.round(( ((double)x % 360) / 45))
, что это делает первым x% 360
, гарантирует, что заголовок находится в пределах действительного диапазона. Тогда
45 * round(.../45)
находит ближе всего 45.
Теперь измените вашу карту, чтобы быть
HashMap<Integer, String> map = new HashMap<Integer, String>()
map.put(0, "North")
map.put(45, "Northeast")
etc...
Итак, теперь ваш алгоритм становится быстрым математическим расчетом, а не итерацией через карту. Кроме того, вам не нужно, так как здесь не нужно, так как он предоставляет конструкции для параллелизма (если я правильно запомню), и в вашем случае это фактически приведет к снижению производительности.
Еще раз, удар производительности может быть полностью незначительным для ваших потребностей.
Редактировать предложения Thilo и Shinjin:
Вместо умножения на 45, просто держите оставшуюся часть уравнения, что дает вам значения для 0-7 и сделать массив ваших строк.
String directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}
return directions[ (int)Math.round(( ((double)x % 360) / 45)) % 8 ]
И вы получили свою проблему, решенную в двух строках.
Одно примечание: модуль не будет работать правильно для отрицательных чисел. Если наш входной заголовок отрицателен, вам нужно сделать его положительным первым.
Вы можете добавить 15 градусов вперед, чтобы избежать North_1 и North_2.