Я предполагаю, что вы хотите хранить данные о преобразовании в виде тройки (fstUnit, sndUnit, multiplier)
.
Для преобразования единицы измерения:
O(1)
используйте некоторые хэш-функции для изменения единицы измерения на число, а затем поместите все множители в матрицу (вам нужно запомнить только правую верхнюю часть, потому что отражение то же самое, но обратное).
Для сложных случаев: Пример 1. м/с в км/ч. Вы проверяете (m,km) в матрице, затем (s,h), затем перемножаете результаты. Пример 2. от м^3 до км^3. Вы проверяете (m,km) и возводите его в третью степень.
Конечно, бывают ошибки, когда типы не совпадают, например, поле и объем.
Я бы начал с хеш-таблицы (или постоянной таблицы поиска - ваш выбор, как вы ее реализуете), которая содержит преобразование единиц между любым количеством пар, которое вы хотите ввести. Если вы введете все возможные пары, то это будет ваша грубая сила. подход.
Если у вас есть только частичные пары, вы можете затем выполнить поиск по парам, которые вам нужны, чтобы найти комбинацию. Например, предположим, что у меня есть эти две записи в моей хеш-таблице:
Feet|Inches|1/12
Inches|Centimeters|2.54
Теперь, если я хочу преобразовать футы в сантиметры, у меня есть простой поиск по графу: вершины - это футы, дюймы и сантиметры, а края - это 1/12 и 2,54 коэффициента преобразования. Решением в этом случае являются два ребра 1/12, 2,54 (конечно, объединенные посредством умножения). При желании вы можете поработать с параметрами графика.
Другой подход может заключаться в применении абдуктивного мышления - посмотрите тексты AI о средствах решения алгебраических задач для этого ...
Редактировать: Адресация составных единиц
Упрощенная задача: преобразовать «акры» в «метры ^ 2 "
В этом случае ключи понимают, что мы говорим об единицах длины, так почему бы нам не вставить новый столбец в таблицу для типа единицы , который может быть" длиной " или «площадь». Это повысит производительность даже в более ранних случаях, поскольку дает вам простой столбец для сокращения пространства поиска.
Теперь уловка состоит в том, чтобы понять, что длина ^ 2 = площадь. Почему бы не добавить еще один поиск, который хранит эти метаданные:
Area|Length|Length|*
Мы соединяем это с таблицей основных единиц:
Meters|Feet|3.28|Length
Acres|Feet^2|43560|Area
Итак, алгоритм таков:
Обратите внимание на то, что:
Вы можете сделать класс для единиц, который принимает коэффициент пересчета и экспоненты всех основных единиц (я бы предложил использовать для этого метрические единицы, что облегчает вашу жизнь). Например, в Pseudo-Java:
public class Unit {
public Unit(double factor, int meterExp, int secondExp, int kilogrammExp ... [other base units]) {
...
}
}
//you need the speed in km/h (1 m/s is 3.6 km/h):
Unit kmPerH = new Unit(1 / 3.6, 1, -1, 0, ...)
Я бы начал с выбора стандартного блока для каждой величины (например, метры для длины, ньютоны для силы и т. д.), а затем сохраняя все коэффициенты преобразования для этой единицы в таблице
, а затем переходя от дней к часам, например, вы найдете коэффициенты преобразования для секунд в день и секунды в час и разделите их, чтобы найти ответ.
для двусмысленности каждая единица может быть связана со всеми типами величин, которые она измеряет, и для определения того, какое преобразование нужно сделать, вы должны пересечь эти два набора типов (и если у вас останется 0 или более чем один вы бы ошибку выдали)
Какую бы структуру вы ни выбрали, и ваш выбор вполне может быть направлен вашей предпочтительной реализацией (объектно-ориентированный? Функциональный? Таблица СУБД?) Я думаю, вам нужно определить структуру самих модулей.
Например, измерение 1000 км / ч состоит из нескольких компонентов:
Ваше моделирование измерений с помощью единиц должно отражать, по крайней мере, эту сложность.
Как уже было предложено, вы должны установить, какой базовый набор единиц вы собираетесь использовать, и базовые единицы СИ немедленно напрашиваются сами собой. После этого ваша структура данных для единиц моделирования будет определена в терминах этих базовых единиц. Поэтому вы можете определить таблицу (здесь подразумевается РСУБД, но легко переводимая в вашу предпочтительную реализацию) с такими записями, как:
unit name dimension conversion to base
foot Length 0.3048
gallon(UK) Length^3 4.546092 x 10^(-3)
kilowatt-hour Mass.Length^2.Time^(-2) 3.6 x 10^6
и так далее.Вам также понадобится таблица для перевода префиксов (кило-, нано-, мега-, миби и т. Д.) В коэффициенты умножения и таблица основных единиц для каждого из измерений (т.е. метр является базовой единицей для длины, секунды на время и т. д.). Вам также придется иметь дело с такими единицами, как футов
, которые являются просто синонимами для других единиц.
Цель измерения, конечно же, состоит в том, чтобы гарантировать, что ваши преобразования и другие операции (например, добавление 2 футов
к 3,5 метра
) будут соразмерными.
И для дальнейшего чтения я предлагаю эту книгу Кардарелли .
РЕДАКТИРОВАТЬ в ответ на комментарии ...
Я пытаюсь уклониться от предложения (зависящих от реализации) решений, поэтому я еще немного пофантазирую. Сложные единицы, такие как киловатт-часы, действительно создают проблему. Один из подходов заключался бы в том, чтобы пометить измерения несколькими единицами-выражениями, такими как киловатт
и час
, и правилом для их объединения, в данном случае умножением
Я мог бы вижу, что это довольно быстро становится волосатым. Возможно, было бы лучше ограничить допустимый набор единиц наиболее распространенными в домене приложения.
Что касается измерений в смешанных единицах, то цель определения Размерности единицы состоит в том, чтобы предоставить некоторые средства, гарантирующие, что только разумные операции могут применяться к измерениям с единицами измерения. Итак, разумно сложить две длины (L + L) вместе, но не длину (L) и объем (L ^ 3). С другой стороны, разумно разделить объем на длину (чтобы получить площадь (L ^ 2)).И это своего рода задача приложения, чтобы определить, действительны ли странные единицы, такие как киловатт-часы на квадратный метр.
Наконец, книга, на которую я ссылаюсь, действительно перечисляет все возможности, я полагаю, что наиболее разумные приложения с модулями будут реализовывать только выбор.