2010-09-11 4 views
1

Поскольку я не знаком с java, я не знаю, есть ли где-нибудь библиотека, которая может это сделать. Если нет, есть ли у кого-нибудь идеи, как это можно сделать?Замените подстроку комбинацией регулярных выражений

Например, у меня есть строка «foo», и я хочу изменить букву f на «f» и «a», чтобы функция вернула список строк со значениями «foo» и «aoo».

Как справиться с этим, когда есть еще одно и то же письмо? «ffoo» в «ffoo», «afoo», «faoo», «aaoo».

Лучшее объяснение: (("а", ("а", "б)), (" с»("с", "d"))) Выше группа символов, которые необходимо заменяется на «a» и «b». «c» заменяется на «c» и «d».

Если я есть строка «ас», в результате комбинации, мне нужно это: «ас» «Ьс» «объявление» «бод»

Если строка «IaJaKc», в результате комбинации: «IaJaKc " "IbJaKc" "IaJbKc" "IbJbKc" "IaJaKd" "IbJaKd" "IaJbKd" "IbJbKd"

Количество комбинаций может быть вычислена следующим образом: (replacements_of_a^letter_amount_a) * (replacements_of_c^letter_amount_c) первый случай: 2^1 * 2^1 = второй случай: 2^2 * 2^1 = 8

Если, скажем, группа (("а", ("а («c», «d», «e»))), а строка «aac», количество комбинаций: 2^2 * 3^1 = 12

+2

Какой результат вы хотите? –

+0

Чтобы получить все комбинации при замене. Я думал, может быть, есть функция, которая берет строку, письмо и регулярное выражение («f | a»). В любом случае, мне нужно сгенерировать варианты строк, основанные на замене определенного письма несколькими другими. Это символ по замене символов. Количество комбинаций можно рассчитать, но я не знаю, как их создавать. – Lats

+0

Я обновил свой ответ, посмотрю на него. – Roman

ответ

0

Здесь:

public static void returnVariants(String input){ 
     List<String> output = new ArrayList<String>(); 
     StringBuffer word = new StringBuffer(input); 
     output.add(input); 

     String letters = "ac"; 
     int lettersLength = letters.length(); 
     int wordLength = word.length(); 
     String replacement = ""; 

     for (int i = 0; i < lettersLength; i++) { 
      for (int j = 0; j < wordLength; j++) { 
       if(word.charAt(j)==letters.charAt(i)){ 
        if (word.charAt(j)=='a'){ 
         replacement = "ab"; 
        }else if (word.charAt(j)=='c'){ 
         replacement = "cd"; 
        } 
        List<String> tempList = new ArrayList<String>(); 
        for (int k = 0; k < replacement.length(); k++) { 
         for (String variant : output){ 
          StringBuffer tempBuffer = new StringBuffer(variant); 
          String combination = tempBuffer.replace(j, j+1, replacement.substring(k, k+1)).toString(); 
          tempList.add(combination); 
         } 
        } 
        output.addAll(tempList); 
        if (j==0){ 
         output.remove(0); 
        } 
       } 
      } 
     } 
     Set<String> uniqueCombinations = new HashSet(output); 
     System.out.println(uniqueCombinations); 
    } 

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

1

Вот код для вашего примера с обув и АОО

public List<String> doSmthTricky (String str) { 
    return Arrays.asList("foo".replaceAll("(^.)(.*)", "$1$2 a$2").split(" ")); 
} 

Для ввода «Foo» этот метод возвращает список с 2 строки «Foo» и «Лоо».

Он работает только в том случае, если в вашей строке ввода нет пробелов («foo» в вашем примере). В противном случае это немного сложнее.

Как с этим бороться, когда есть более одинаковые буквы? «ffoo» в «ffoo», «afoo», «faoo», «aaoo».

Я сомневаюсь, что регулярные выражения могут помочь здесь, вы хотите сгенерировать строки на основе исходной строки, это не задача для регулярного выражения.

UPD: Я создал рекурсивную функцию (на самом деле это половина рекурсии половинной итеративный), который генерирует строки на основе строки шаблона, заменив его первые символы с символами из заданного набора:

public static List<String> generatePermutations (String template, String chars, int depth, List<String> result) { 
    if (depth <= 0) { 
     result.add (template); 
     return result; 
    } 
    for (int i = 0; i < chars.length(); i++) { 
     String newTemplate = template.substring(0, depth - 1) + chars.charAt(i) + template.substring(depth); 
     generatePermutations(newTemplate, chars, depth - 1, result); 
    } 
    generatePermutations(template, chars, depth - 1, result); 
    return result; 
} 

Параметр @depth означает, сколько символов от начала строки должно быть заменено. Количество перестановок (chars.size() + 1)^depth.

Тесты:

System.out.println(generatePermutations("ffoo", "a", 2, new LinkedList<String>())); 

Output: [aaoo, faoo, afoo, ffoo] 

-- 
System.out.println(generatePermutations("ffoo", "ab", 3, new LinkedList<String>())); 

Output: [aaao, baao, faao, abao, bbao, fbao, afao, bfao, ffao, aabo, babo, fabo, abbo, bbbo, fbbo, afbo, bfbo, ffbo, aaoo, baoo, faoo, aboo, bboo, fboo, afoo, bfoo, ffoo] 
+0

Роман, спасибо за попытку, но мне все еще нужен другой пример для работы. Если я использую replaceAll, я могу получить «ffoo», ничего не делая, а затем «afoo» и «aaoo», но «faoo» по-прежнему отсутствует ... :( – Lats

+0

Превосходит красиво, но не то решение, которое мне нужно. Извините, если я трачу ваше время: S – Lats

0

Я не уверен, что вам нужно. Укажите источник и ожидаемый результат. Во всяком случае, для этой цели вы должны использовать стандартные классы Java: java.util.regex.Pattern, java.util.regex.Matcher. Если вам нужно иметь дело с повторяющимися буквами в начале, тогда есть два способа: используйте символ «^» - это означает начало строки, или с той же целью вы можете использовать ярлык «\ w», что означает начало слово. В более сложных случаях, пожалуйста, взгляните на выражения «lookbehind». Есть более чем полные описания этих методов, которые вы можете найти в java doc для java.util.regex, и если этого недостаточно, просмотрите www.regular-expressions.info удачу.

+0

Не так много источника, чтобы показать :(Вот лучшее объяснение. У меня есть набор символов, которые мне нужно заменить. Каждый символ в этом наборе должен быть заменен на символ из его отличительной группы.Функция должна возвращать все комбинации исходной строки.Имена не обязательно находятся в начале строки.Система может быть любой, но группа что-то вроде этого (("a" , («a», «b)), (« c », (« c »,« d »))). Значение замените все« a »на« a »и« b », но получите все комбинации, аналогично с «c», замените его на «c» и «d». – Lats

+0

Спасибо за ваш ответ. Я полагаю, что ваша задача намного проще, чем раньше. Более того, я думаю, вы можете h и его вообще без регулярного выражения. На вашем месте я бы поместил символы в необходимость замены в коллекции, тогда было бы 2 цикла: внешние для этой коллекции и внутренние, которые проверяют исходную строку на существование текущего заменяемого символа, это может быть сделано методом indexOf (int pos, String character) String. Во внутреннем цикле я бы заполнил возвращаемую коллекцию замененных строк и увеличил «pos», если символ был найден. Надеюсь, это поможет. – dhblah

+0

Я пытался решить это так, но не могу вернуться назад, чтобы охватить все комбинации ... он охватывает все это от начала до конца, но зацикливается на последнем изменении последней буквы. Если «a» изменяется на «a» и «b» и «c» на «c» и «d», строка «ac» выводит «ac», «bc», «bc» снова и «bd» ... – Lats