2012-06-29 3 views
1

У пользователя есть ArrayList чисел. Эти номера соответствуют приложениям, к которым у них есть доступ. Некоторые приложения имеют разные номера прав (т. Е. 3, 72 и т. Д.). Я хочу сохранить эти данные на карте, чтобы при входе пользователя в систему они могли вводить свои номера в Карту и быстро получать приложения, на которые они имеют право. Однако для некоторых приложений требуется от 2 до 3 номеров прав. Например, одна запись может быть: («101 и 234», «Приложение 1»). Мне было интересно, есть ли идеальный способ получить все значения с карты, которые удовлетворяют номерам пользователей.Нужна помощь в хранении/восстановлении данных

Как это у меня есть, программа сравнивает данные пользователей с каждым приложением и подтверждает или запрещает доступ. Это кажется неэффективным. Любая помощь нам очень ценится!

Примечание: Я читаю приложения и их номера из XML, поэтому я могу хранить их, как я хочу.

+0

Вы можете уточнить ваш вопрос с примером? Я не думаю, что у меня все дела. – nhahtdh

+0

Простите, что каждый раз, когда пользователь входит в систему, я хочу сравнить их список строк с картой строки, соответствующей приложению. Номера прав пользователей могут выглядеть примерно так: {"1", "2", "3", "5"}. Я хочу сравнить этот список строк со всем номером приложения. Большинство приложений имеют 1 номер права. Итак, я ввожу 1 в карту, и я возвращаю «Приложение 3». Это нормально. Но для некоторых приложений требуются номера прав «2 и 3». У меня возникают проблемы с этим в O (1) время, когда числа являются составными. Я думал о том, что один вывод карты еще один – cspada

+0

В случае: «1» -> «App1», «2» -> «App2», {«1», «2»} -> «AppTwoEntitlement» возможно ? И если вы дадите {"1", "2"}, он вернет все 3 приложения? – nhahtdh

ответ

0

Если для каждого приложения требуется большое количество чисел, наилучшим подходом является использование набора пересечений. Если числа являются смежными или, по меньшей мере, плотными, вы можете оптимизировать их в биты. Однако для одного или двух чисел я бы рекомендовал просто тестировать каждый номер по отдельности, так как он скорее всего будет быстрее, чем полный набор операций.

0

Решение:

  • Определение класса для каждого приложения (назовем его App). Класс содержит имя приложения и (отсортированный) список/массив прав.
  • Используйте карту, чтобы карта от String до App: Map<String, App> для всех приложений с одним правом (вы можете использовать HashMap или TreeMap - ваш выбор). Если есть несколько приложений, которым требуется только одно и то же право, рассмотрите Map<String, List<App>>. Исключите приложения, которым требуется несколько прав на карте, и сохраните их в отдельном списке/массиве.
  • Когда вам предоставляется список прав на получение приложений, просмотрите список и просто возьмите все, что Map отображает строку. Для тех, кто нуждается в нескольких правах, просто проверяйте индивидуально (вы можете ускорить проверку бит, сортируя список предоставленных прав и сохраняя права на каждый App в отсортированном порядке - но это может даже не иметь значения, так как размер невелик) ,

Решение уменьшает временную сложность операции. Тем не менее, несколько сотен приложений умножают количество прав около 10, по моему мнению, довольно мало, если вы не назовете это много раз. И лучше подойти к вашему оригинальному подходу и подобному подходу к сопоставлению - поскольку накладные расходы могут ослабить любое улучшение во времени.

Немного дальнейшего улучшения (или нет):

  • Использование Map<String, List<App>> и включают в себя даже приложения, которые требуют несколько пособий (те приложения будут отображаться на многих прав).
  • Когда мы ищем приложение, мы будем использовать Map<App, Integer>, чтобы отслеживать, сколько прав, которые мы подтвердили для нескольких приложений с правами. Таким образом, поток будет как:

    new mapAppInteger 
    foreach entitlement in inputListOfEntitlement 
        listOfApps = mapStringAppList.get(entitlement) 
    
        if listOfApps found 
         for each app in listOfApps 
          if app needs singleEntitlement 
           put app in output list 
          else // needs multiple 
           if app is in mapAppInteger 
            map app --> count + 1 
            if mapAppInteger.get(app) == app.numberOfRequiredEntitlement 
             put app in output list 
             remove app from mapAppInteger 
           else // not in mapAppInteger 
            map app --> 1 
    
+0

@NerdEcho: Сообщение отредактировано. – nhahtdh

+0

Большое спасибо! Я сравню их! – cspada

Смежные вопросы