2010-04-23 3 views
4

проблема - у меня есть что-то вроде следующих записей, 1000 из них:Как реализовать сборку (список, карту?) Сложных строк в Java?

args1=msg args2=flow args3=content args4=depth args6=within ==> args5=content 
args1=msg args2=flow args3=content args4=depth args6=within args7=distance ==> args5=content 
args1=msg args2=flow args3=content args6=within ==> args5=content 
args1=msg args2=flow args3=content args6=within args7=distance ==> args5=content 
args1=msg args2=flow args3=flow ==> args4=flowbits 
args1=msg args2=flow args3=flow args5=content ==> args4=flowbits 
args1=msg args2=flow args3=flow args6=depth ==> args4=flowbits 
args1=msg args2=flow args3=flow args6=depth ==> args5=content 
args1=msg args2=flow args4=depth ==> args3=content 
args1=msg args2=flow args4=depth args5=content ==> args3=content 
args1=msg args2=flow args4=depth args5=content args6=within ==> args3=content 
args1=msg args2=flow args4=depth args5=content args6=within args7=distance ==> args3=content 

я делаю какой-то метод внушения. Скажем, args1 = тзд args2 = поток args3 = поток ==> args4 = flowbits

Если предложение содержит глутамат натрия, поток, а другой поток, то я должен вернуть предложение flowbits.

Как я могу это сделать? Я знаю, что я должен сканировать (всякий раз, когда персонаж нажимает на текстовую область) список или массив для соответствия и возвращает результат, но 1000 записей, как мне его реализовать?

Я думаю о HashMap, но могу ли я сделать что-то подобное?

< «тзд, поток, поток», «flowbits»>

Кроме того, в предложении аргументы не может быть в порядке, так что если предположить, что это поток, поток, сообщ то я ничего не могу соответствовать в HashMap, поскольку ключ является «msg, flow, flow».

Что делать в этом случае? Пожалуйста помоги. Бесконечно благодарен!

ответ

4

Ключ A Map может быть другим Map или Set. Похоже, все, что вам нужно, это что-то вроде Map<Set<String>, String> или, возможно, Map<Map<String, String>, Map.Entry<String, String>> - не знаю, где эти «args1», «args2» имеют значение.

+0

Hi. Я прочитал в Set , поскольку я не использовал его раньше. Как насчет вопроса «аргументы могут быть не в порядке»? Есть ли у вас какие-либо идеи о том, как ее решить, если я реализую карту? Благодаря! –

+0

Пожалуйста, проигнорируйте args1 и args2, он есть, когда я вытащил записи из сгенерированного результата априори. –

+0

@Alex: Из того, что вы написали, мне кажется, что вы хотите проигнорировать заказ при поиске матчей. Использование клавиши Set as сделает именно это. –

0

Да, вы можете сделать < «msg, flow, flow», «flowbits»> в hashmap. Это лучшее решение, я не знаю.

0

На первый взгляд это выглядит как хорошее использование для синтаксического анализатора и формальной грамматики, а не для коллекции. ANTLR - популярный генератор синтаксического анализатора для Java.

Где синтаксический анализатор не будет решить вашу проблему, если аргументы могут отображаться в любом порядке. В этой ситуации я бы использовал какой-то объект Case, который объединяет правила и действия и использует простой Map<String,List<Case>>, чтобы найти экземпляры, которые могут применяться к данному тексту (вы должны извлекать отдельные слова из текста, чтобы исследовать карту, и могли бы объединить списки, возвращаемые с каждого зонда).

У меня нет времени, чтобы дать полный пример, но Case объект вероятно, будет выглядеть примерно так:

public interface Case { 
    boolean evaluate(String text); 
    String result(); 
} 
+0

Привет, спасибо за ответ. Я все еще немного озадачен тем, что вы предложили. Однако, если это возможно, я бы предпочел не использовать для этого внешние инструменты. Я еще посмотрю ANTLR, спасибо за ссылку! –

0

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

0

Поскольку порядок отображения строк не важен, вы можете их в алфавитном порядке при создании ключа. Предположим, что вы хотите использовать те же предложения для msg, flow, flow и flow, msg, flow и flow, flow, msg - в алфавитном порядке, они являются «потоком, потоком, msg», так что это то, что вы используете в качестве ключа.

+0

Привет. Хорошее предложение. Я попробую. Благодарю. –

1

Другими словами, постарайтесь не выполнять всю свою логику в своем парсере. Разделите логику, чтобы синтаксический анализатор просто обнаруживал структуру, а затем создавал объекты, чтобы помочь вам применять правила.Парсер может легко обнаруживать аргументы и использовать их для создания списка.

Если вы создаете класс, чтобы содержать свои аргументы, как так:

public class Arg { 
    public int number; 
    public String value; 

    public Arg(int num, String val) { 
     this.number = num; 
     this.value = val; 
    } 

    @Override 
    public String toString() 
    { 
    return "[Arg num=" + number + ", value=" + value + "]"; 
    } 

} 

, то вы можете поместить те в простой Hashtable.

Map<Arg> argList = new HashMap<Arg>(); 

Затем вы можете сделать логику, используя, возможно, счетчик и содержит() или IndexOf() и т.д.

Имея класс Arg делает сортировку легко. Если вам нужен список, отсортированный по позиции аргумента, для этого вы создаете Компаратор.

import java.util.Comparator; 

public class ArgNumComparator implements Comparator<Arg> { 
    public int compare(Arg o1, Arg o2) { 
     if (o1.number == o2.number) { 
     return 0; 
     } 
     return o1.number < o2.number ? -1 : 1 ; 
    }  
} 

Сортировка по значению аргумента еще проще, поскольку вы можете повторно использовать compareTo() строк.

import java.util.Comparator; 

public class ArgValComparator implements Comparator<Arg> 
{ 
    public int compare(Arg o1, Arg o2) 
    { 
     return o1.value.compareTo(o2.value); 
    } 
} 

Затем, чтобы сделать сортировку использовать Collections.sort() следующим образом:

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class ArgList{ 
    public static void main(String[] args) { 
     //args1=msg args2=flow args3=content args4=depth args6=within ==> args5=content 
     List<Arg> l = new ArrayList<Arg>(); 
     // hard-coded example instead of more likely parsing 
     l.add(new Arg(1, "msg")); 
     l.add(new Arg(2, "flow")); 
     l.add(new Arg(3, "content")); 
     l.add(new Arg(4, "depth")); 
     l.add(new Arg(5, "flow")); 
     l.add(new Arg(6, "within")); 

    Collections.sort(l, new ArgValComparator()); // take your pick of comparators 

    System.out.println(l); // uses the toString() of Arg. 
    } 
} 

EDIT: добавлен метод ToString() для Arg и изменил список в примере, чтобы иметь два «поток» args.

Запуск с новым кодом ToString помещает следующее в консоли:

[[Арг Num = 3, значение = содержание], [Арг Num = 4, значение = глубина], [Арг NUM = 2, значение = поток], [Арг Num = 5, значение = поток], [Арг Num = 1, значение = тзд], [Арг Num = 6, значение = в пределах]]

Как вы можете видеть, два аргумента со значением = «поток» теперь находятся рядом друг с другом. Для обнаружения нескольких аргументов, где значение = «поток» может быть выполнено таким образом:

boolean flowFound = false; 
for (Arg arg : l){ 
    if (arg.value.compareToIgnoreCase("flow") == 0) { 
     if (flowFound) //already found one? { 
     // action when second "flow" exists 
     System.out.println("2nd flow found"); 
     } 
     else { 
     flowFound = true; // found the first "flow" 
     } 
    }   
} 
+0

Привет, Келли. Я все еще пытаюсь переварить то, что вы опубликовали. Благодарю. –

+0

После попытки, я думаю, я понял. Я распечатал список после коллекции Collections.sort и получил обратно msg, поток, контент, глубину, содержимое внутри. Что делать, если я хочу найти «msg, flow, content, depth, in» из отсортированного списка? –

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