CCF-URL映射 Java 201803-3 (100)

問題描述

試題編號: 201803-3
試題名稱: URL映射
時間限制: 1.0s
內存限制: 256.0MB
問題描述:

問題描述

  URL 映射是諸如 Django、Ruby on Rails 等網頁框架 (web frameworks) 的一個重要組件。對於從瀏覽器發來的 HTTP 請求,URL 映射模塊會解析請求中的 URL 地址,並將其分派給相應的處理代碼。現在,請你來實現一個簡單的 URL 映射功能。
  本題中 URL 映射功能的配置由若干條 URL 映射規則組成。當一個請求到達時,URL 映射功能會將請求中的 URL 地址按照配置的先後順序逐一與這些規則進行匹配。當遇到第一條完全匹配的規則時,匹配成功,得到匹配的規則以及匹配的參數。若不能匹配任何一條規則,則匹配失敗。
  本題輸入的 URL 地址是以斜槓 / 作爲分隔符的路徑,保證以斜槓開頭。其他合法字符還包括大小寫英文字母、阿拉伯數字、減號 -、下劃線 _ 和小數點 .。例如,/person/123/ 是一個合法的 URL 地址,而 /person/123? 則不合法(存在不合法的字符問號 ?)。另外,英文字母區分大小寫,因此 /case/ 和 /CAse/ 是不同的 URL 地址。
  對於 URL 映射規則,同樣是以斜槓開始。除了可以是正常的 URL 地址外,還可以包含參數,有以下 3 種:
  字符串 <str>:用於匹配一段字符串,注意字符串裏不能包含斜槓。例如,abcde0123。
  整數 <int>:用於匹配一個不帶符號的整數,全部由阿拉伯數字組成。例如,01234。
  路徑 <path>:用於匹配一段字符串,字符串可以包含斜槓。例如,abcd/0123/。
  以上 3 種參數都必須匹配非空的字符串。簡便起見,題目規定規則中 <str> 和 <int> 前面一定是斜槓,後面要麼是斜槓,要麼是規則的結束(也就是該參數是規則的最後一部分)。而 <path> 的前面一定是斜槓,後面一定是規則的結束。無論是 URL 地址還是規則,都不會出現連續的斜槓。

輸入格式

  輸入第一行是兩個正整數 n 和 m,分別表示 URL 映射的規則條數和待處理的 URL 地址個數,中間用一個空格字符分隔。
  第 2 行至第 n+1 行按匹配的先後順序描述 URL 映射規則的配置信息。第 i+1 行包含兩個字符串 pi 和 ri,其中 pi 表示 URL 匹配的規則,ri 表示這條 URL 匹配的名字。兩個字符串都非空,且不包含空格字符,兩者中間用一個空格字符分隔。
  第 n+2 行至第 n+m+1 行描述待處理的 URL 地址。第 n+1+i 行包含一個字符串 qi,表示待處理的 URL 地址,字符串中不包含空格字符。

輸出格式

  輸入共 m 行,第 i 行表示 qi 的匹配結果。如果匹配成功,設匹配了規則 pj ,則輸出對應的 rj。同時,如果規則中有參數,則在同一行內依次輸出匹配後的參數。注意整數參數輸出時要把前導零去掉。相鄰兩項之間用一個空格字符分隔。如果匹配失敗,則輸出 404。

樣例輸入

5 4
/articles/2003/ special_case_2003
/articles/<int>/ year_archive
/articles/<int>/<int>/ month_archive
/articles/<int>/<int>/<str>/ article_detail
/static/<path> static_serve
/articles/2004/
/articles/1985/09/aloha/
/articles/hello/
/static/js/jquery.js

樣例輸出

year_archive 2004
article_detail 1985 9 aloha
404
static_serve js/jquery.js

樣例說明

  對於第 1 個地址 /articles/2004/,無法匹配第 1 條規則,可以匹配第 2 條規則,參數爲 2004。
  對於第 2 個地址 /articles/1985/09/aloha/,只能匹配第 4 條規則,參數依次爲 1985、9(已經去掉前導零)和 aloha。
  對於第 3 個地址 /articles/hello/,無法匹配任何一條規則。
  對於第 4 個地址 /static/js/jquery.js,可以匹配最後一條規則,參數爲 js/jquery.js。

數據規模和約定

  1 ≤ n ≤ 100,1 ≤ m ≤ 100。
  所有輸入行的長度不超過 100 個字符(不包含換行符)。
  保證輸入的規則都是合法的。

 

 

 

 

import java.util.Scanner;
/**
 * 想法:把原串裏面的<int> <str> <path> 替換成正則,
 * 然後遍歷判斷,如果符合其中一條在進行劃分輸出
 */

public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String intString = "[0-9]+";
		String strString = "[a-zA-Z0-9-_.]+";
		String pathString = "[a-zA-Z0-9-_./]+";
		int n = sc.nextInt();
		int m = sc.nextInt();
		sc.nextLine();
		String[][] patten = new String[n][3];
		String[] path = new String[n];
		for (int i = 0; i < n; i++) {
			String str = sc.nextLine();
			// i,0爲url名稱
			patten[i][0] = str.split(" ")[1];
			// i,1 爲 url匹配規則
			patten[i][1] = str.split(" ")[0];
			// System.out.println(str.indexOf(' '));
			// i,2爲原字符串
			patten[i][2] = str.substring(0, str.indexOf(' '));
			// 將這些字符用正則表達式進行替換
			patten[i][1] = patten[i][1].replace("<int>", intString);
			patten[i][1] = patten[i][1].replace("<str>", strString);
			patten[i][1] = patten[i][1].replace("<path>", pathString);

		}
		for (int i = 0; i < m; i++) {
			path[i] = sc.nextLine();
		}
		for (int i = 0; i < m; i++) {
			boolean ff = false;
			for (int j = 0; j < n; j++) {
				if (path[i].matches(patten[j][1])) {
					ff = true;
					// 如果匹配成功,劃分兩條字符串
					String[] pat = patten[j][2].split("/");
					String[] url = path[i].split("/");
					// 判斷路徑是否有兩個'//'在一起,連在一起進行下一次
					if (patten[j][2].contains("<path>")) {
						boolean flag = false;
						for (int k = 0; k < url.length - 1; k++) {
							if (path[i].charAt(k) == '/' && path[i].charAt(k) == path[i].charAt(k + 1)) {
								flag = true;
								break;
							}
						}
						if (flag) {
							ff = false;
							continue;
						}
					}
					// 輸出名稱
					System.out.print(patten[j][0] + " ");
					for (int k = 0; k < pat.length; k++) {
						// 如果爲int
						if (pat[k].equals("<int>")) {
							// 去掉前導0
							while (url[k].startsWith("0")) {
								url[k] = url[k].substring(1);
							}
							System.out.print(url[k] + " ");
						} else if (pat[k].equals("<str>")) {
							// 如果爲 str
							System.out.print(url[k] + " ");
						} else if (pat[k].equals("<path>")) {
							for (int z = k; z < url.length; z++) {
								if (z == url.length - 1) {
									System.out.print(url[z]);
								} else {
									System.out.print(url[z] + "/");
								}
							}
							break;
						}
					}
					System.out.println();
					break;
				}
			}
			if (!ff) {
				System.out.println("404");
			}

		}
		// String string = sc.nextLine();
		// System.out.println(string.matches("string"));
		// System.out.println(string.matches("/articles/[0-9]+/[a-zA-Z-_.]+"));

	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章