2014-02-16 3 views
0

я пошел на майкрософт кодирования вызов в колледже, и это был задан вопрос:Текст сопоставления запросов (сложно)

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

1) Запрос должен соответствовать только тексту тела, если он соответствует началу слова в тексте тела.

2) То есть начало запроса также должно быть началом слова в тексте тела. Например, запрос «cat» будет соответствовать строкам «cat», «cat toy», «это кошка» и «catty». Однако запрос «cat» не соответствует строке «location».

3) Ваша программа должна быть нечувствительна к регистру.

4) Ваша программа должна иметь возможность сопоставлять запросы без пробелов в них, даже если тело имеет пробелы. Например, строка «Luke Johnston» будет соответствовать запросу «luke j» и запросу «lukej».

5) Однако это не работает наоборот. Запрос «luke j» не должен соответствовать строке «lukejohnston».

Я могу написать код, который удовлетворяет первым 4 требованиям, но я не могу найти решение для 5-го. Любые подсказки/помощь приветствуются. Вот моя версия кода.

package regex; 

import java.util.Scanner; 

public class TextQueryMatch { 
public static void main(String[] args){ 
    Scanner in = new Scanner(System.in); 
    System.out.print("Enter the Text: "); 
    String text = in.nextLine(); 
    text = text.toLowerCase(); 
    String[] substexts = text.split("\\s"); 
    text = ""; 
    for(int i = 0; i < substexts.length; i++){ 
     char capLetter = Character.toUpperCase(substexts[i].charAt(0)); 
     text += capLetter + substexts[i].substring(1, substexts[i].length()); 
    } 
    System.out.println(text); 
    System.out.print("Enter the Query: "); 
    String query = in.nextLine(); 
    query = query.toLowerCase(); 
    String[] subquerys = query.split("\\s"); 
    query = ""; 
    for(int i = 0; i < subquerys.length; i++){ 
     char capLetter = Character.toUpperCase(subquerys[i].charAt(0)); 
     query += capLetter + subquerys[i].substring(1, subquerys[i].length()); 
    } 
    System.out.println(query); 
    System.out.print("Match: "); 
    if(text.matches("(.*)"+query.charAt(0)+"(.*)")){ 
     text=text.toLowerCase(); 
     query=query.toLowerCase(); 
     System.out.print(text.matches("(.*)"+query+"(.*)")); 
    }else{ 
     System.out.print("False"); 
    } 
} 
} 

ответ

1

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

По вопросу,

пунктами 1 & 2, запрос должен соответствовать тексту только если запрос строка находится в начале текста или преуспевает пространство. Таким образом, в основном регулярное выражение для этого было бы что-то вроде -

(^|\s)(query-string) 

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

Для пунктов 4 & 5- запрос должен соответствовать тексту, даже если запрос не имеет пробела, но если в запросе есть пробел, он должен быть правильно подобран в тексте.

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

Это должно работать -

public static boolean find_match(String query, String text){ 
    String regex = "(?:^|\\s)(" + query.replaceAll(".(?!$)", "$0(?:\\\\s*)") + ")"; 
    //System.out.println("Regex -> " + regex); 
    Pattern re = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);  
    return re.matcher(text).find(); 
} 

тестирование этой функции -

public static void main(String []args){   
    String query1 = "cat"; 
    String[] text1 = { 
     "Cat", 
     "caT toy", 
     "This is a CaT", 
     "caTty", 
     "loCation" 
    }; 
    for(String s : text1){ 
     System.out.println("Query -> " + query1 + "\nText -> " + s + "\n" + find_match(query1, s) + "\n"); 
    } 
    String query2 = "luke j"; 
    String query3 = "lukej"; 
    String[] text2 = { 
     "Luke Johnson", 
     "lukejohnson", 
     "Luke  Johson", 
     "This is Luke Johnson", 
     "L ukeJohnson", 
     "L uke Johnson" 
    }; 
    for(String s : text2){ 
     System.out.println("Query -> " + query2 + "\nText -> " + s + "\n" + find_match(query2, s)); 
     System.out.println("Query -> " + query3 + "\nText -> " + s + "\n" + find_match(query3, s) + "\n"); 
    }  
} 

выходе ->

Query -> cat 
Text -> Cat 
true 

Query -> cat 
Text -> caT toy 
true 

Query -> cat 
Text -> This is a CaT 
true 

Query -> cat 
Text -> caTty 
true 

Query -> cat 
Text -> loCation 
false 

Query -> luke j 
Text -> Luke Johnson 
true 
Query -> lukej 
Text -> Luke Johnson 
true 

Query -> luke j 
Text -> lukejohnson 
false 
Query -> lukej 
Text -> lukejohnson 
true 

Query -> luke j 
Text -> Luke  Johson 
true 
Query -> lukej 
Text -> Luke  Johson 
true 

Query -> luke j 
Text -> This is Luke Johnson 
true 
Query -> lukej 
Text -> This is Luke Johnson 
true 

Query -> luke j 
Text -> L ukeJohnson 
false 
Query -> lukej 
Text -> L ukeJohnson 
true 

Query -> luke j 
Text -> L uke Johnson 
true 
Query -> lukej 
Text -> L uke Johnson 
true 

Надеюсь, этот helped-

+0

Это помогло. Не могли бы вы прокомментировать заявление regex. Для запроса = "luke j" он дает regex = (?:^| \ S) (l (?: \ S *) u (?: \ S *) k (?: \ S *) e (?: \ S *) (?: \ s *) j). Я новичок в использовании регулярных выражений и ссылался на [этот учебник] (http://www.vogella.com/tutorials/JavaRegularExpressions/article.html) и не смог найти несколько символов. – GauravPandey

+1

Группировка символов,() и (? :) - это группы захвата и не захвата. Обратитесь к ним [здесь] (http://www.regular-expressions.info/brackets.html). Для остальных символов используйте [this] (http://www.rexegg.com/regex-quickstart.html) – Kamehameha

+1

[This] (http://www.regular-expressions.info/tutorial.html) учебник довольно всеобъемлющий, если вы хотите правильно начать регулярное выражение с нуля – Kamehameha

0

Попробуйте использовать этот метод:

public static boolean match(String text, String query) { 
    text = text.toLowerCase(); 
    query = query.toLowerCase(); 

    String noSpaces = text.replaceAll(" ", ""); 
    String[] tWords = text.split(" "); 

    if (text.startsWith(query) || noSpaces.startsWith(query)) { 
     return true; 
    } 

    for (int i = 0; i < tWords.length; i++) { 
     if (tWords[i].startsWith(query)) { 
      return true; 
     } 
    } 

    return false; 
} 
+0

Очень приятное решение, но если я передам текст = «A Luke Johnston» и query = «luke j», потому что в цикле for он будет терпеть неудачу для i = 2, поскольку он будет сравнивать johnston с luke j. – GauravPandey

0

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

Ваш запрос будет иметь следующий вариант: - < кошка>: Случай, когда кошка между предложением < _cat>: случаем, когда предложение заканчивается с кошкой или последующее, или. или любой символ (вы можете проверить следующий символ с помощью ASCII) : Когда предложение начинается с cat. : Тело - это однословное предложение, которое вы можете использовать для подтверждения функции SIZE. _ называется ПРОСТРАНСТВЕ

Во-первых, вам нужно преобразовать все тело и строку запроса в нижнем или верхнем регистре (или не потому, что он не был указан вопрос о том, операция согласования является чувствительным к регистру или нет)

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