CCF201703-3 Markdown(JAVA)

問題描述:

問題描述

  Markdown 是一種很流行的輕量級標記語言(lightweight markup language),廣泛用於撰寫帶格式的文檔。例如以下這段文本就是用 Markdown 的語法寫成的:



  這些用 Markdown 寫成的文本,儘管本身是純文本格式,然而讀者可以很容易地看出它的文檔結構。同時,還有很多工具可以自動把 Markdown 文本轉換成 HTML 甚至 Word、PDF 等格式,取得更好的排版效果。例如上面這段文本通過轉化得到的 HTML 代碼如下所示:



  本題要求由你來編寫一個 Markdown 的轉換工具,完成 Markdown 文本到 HTML 代碼的轉換工作。簡化起見,本題定義的 Markdown 語法規則和轉換規則描述如下:
  ●區塊:區塊是文檔的頂級結構。本題的 Markdown 語法有 3 種區塊格式。在輸入中,相鄰兩個區塊之間用一個或多個空行分隔。輸出時刪除所有分隔區塊的空行。
  ○段落:一般情況下,連續多行輸入構成一個段落。段落的轉換規則是在段落的第一行行首插入 `<p>`,在最後一行行末插入 `</p>`。
  ○標題:每個標題區塊只有一行,由若干個 `#` 開頭,接着一個或多個空格,然後是標題內容,直到行末。`#` 的個數決定了標題的等級。轉換時,`# Heading` 轉換爲 `<h1>Heading</h1>`,`## Heading` 轉換爲 `<h2>Heading</h2>`,以此類推。標題等級最深爲 6。
  ○無序列表:無序列表由若干行組成,每行由 `*` 開頭,接着一個或多個空格,然後是列表項目的文字,直到行末。轉換時,在最開始插入一行 `<ul>`,最後插入一行 `</ul>`;對於每行,`* Item` 轉換爲 `<li>Item</li>`。本題中的無序列表只有一層,不會出現縮進的情況。
  ●行內:對於區塊中的內容,有以下兩種行內結構。
  ○強調:`_Text_` 轉換爲 `<em>Text</em>`。強調不會出現嵌套,每行中 `_` 的個數一定是偶數,且不會連續相鄰。注意 `_Text_` 的前後不一定是空格字符。
  ○超級鏈接:`[Text](Link)` 轉換爲 `<a href="Link">Text</a>`。超級鏈接和強調可以相互嵌套,但每種格式不會超過一層。

輸入格式

  輸入由若干行組成,表示一個用本題規定的 Markdown 語法撰寫的文檔。

輸出格式

  輸出由若干行組成,表示輸入的 Markdown 文檔轉換成產生的 HTML 代碼。

樣例輸入

# Hello

Hello, world!

樣例輸出

<h1>Hello</h1>
<p>Hello, world!</p>

評測用例規模與約定

  本題的測試點滿足以下條件:
  ●本題每個測試點的輸入數據所包含的行數都不超過100,每行字符的個數(包括行末換行符)都不超過100。
  ●除了換行符之外,所有字符都是 ASCII 碼 32 至 126 的可打印字符。
  ●每行行首和行末都不會出現空格字符。
  ●輸入數據除了 Markdown 語法所需,內容中不會出現 `#`、`*`、`_`、`[`、`]`、`(`、`)`、`<`、`>`、`&` 這些字符。
  ●所有測試點均符合題目所規定的 Markdown 語法,你的程序不需要考慮語法錯誤的情況。
  每個測試點包含的語法規則如下表所示,其中“√”表示包含,“×”表示不包含。
測試點編號 段落 標題 無序列表 強調 超級鏈接
1 × × × ×
2 × × ×
3 × × ×
4 × × ×
5 × × ×
6 × ×
7 × ×
8 × ×
9 × ×
10

提示

  由於本題要將輸入數據當做一個文本文件來處理,要逐行讀取直到文件結束,C/C++、Java 語言的用戶可以參考以下代碼片段來讀取輸入內容。


解題思路:採用集合嵌套的方式來對數據進行存儲。

對於角色屬性:外層採用HashMap集合的方式,將對應角色的名稱作爲鍵,再嵌套一個HashMap作爲值存儲相應的權限及等級(權限名爲鍵,權限等級爲值)。

對於用戶屬性 :與角色屬性結構相似,外層用對應角色名稱作爲鍵,內層複製其擁有的角色的最高級權限名稱與等級。

對於查詢:優先判斷權限,角色,用戶是否存在,然後判斷權限本身是否分級,查詢需求是否分級,從存儲的用戶HashMap中按照權限名稱查找該權限即可。

易錯點:角色屬性可能擁有兩個相同的名稱而等級不同的權限,應取等級最高值

 

package permissionQuery;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
	//存儲權限各類型名稱及最高層級
	public static Map<String, Integer> perm=new HashMap<>();
	//存儲該角色名及所擁有權限及最高等級
	public static Map<String,HashMap<String,Integer>> roles=new HashMap<>();
	//存儲該用戶名及所擁有權限及最高等級
	public static Map<String,HashMap<String,Integer>> users=new HashMap<>();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		
		int p=sc.nextInt();//權限類型數目
		for(int i=0;i<p;i++)
		{
			String[] temp=sc.next().split(":");
			if(temp.length==1)
				perm.put(temp[0],-1);//無權限等級則設爲-1
			else
				perm.put(temp[0],Integer.valueOf(temp[1]));
		}
		
		int r=sc.nextInt();//角色類型數目
		for(int i=0;i<r;i++)
		{
			//存儲該角色所擁有的權限名稱及權限最高等級
			HashMap<String,Integer> perms=new HashMap<>();
			String roleName=sc.next();//角色名稱
			int permsNum=sc.nextInt();
			for(int t=0;t<permsNum;t++)
			{
				String[] temp=sc.next().split(":");//temp2下標0權限名,下標1該權限等級
				if(temp.length==1)//判斷權限是否含有等級
					perms.put(temp[0],-1);//權限名,該權限等級,無等級爲-1
				else
				{
					if(perms.containsKey(temp[0]))//若存在該權限則取該權限的最高等級進行存儲
					{
						if(perms.get(temp[0])<Integer.valueOf(temp[1]))//比較權限等級大小
							perms.put(temp[0], Integer.valueOf(temp[1]));
					}
					else
						perms.put(temp[0], Integer.valueOf(temp[1]));
				}
			}
			roles.put(roleName, perms);
		}
		
		int u=sc.nextInt();//用戶數目
		for(int i=0;i<u;i++)
		{
			String userName=sc.next();//用戶名稱
			//存儲該用戶所擁有的權限名稱及權限最高等級
			HashMap<String,Integer> perms=new HashMap<>();
			//將所擁有的角色類型中所擁有的權限轉存儲至用戶的perms中
			int rolesNum=sc.nextInt();
			for(int t=0;t<rolesNum;t++)//彙總所擁有的全部角色權限
			{
				//由角色名得到該角色所有權限名及等級
				for(Map.Entry<String, Integer> m:roles.get(sc.next()).entrySet())
				{
					String key=m.getKey();
					int value=m.getValue();
					if(perms.containsKey(key))//若存在該權限則取該權限的最高等級進行存儲
					{
						if(perms.get(key)<value)//比較權限等級大小
							perms.put(key, value);
					}
					else
						perms.put(key, value);
				}
			}
			users.put(userName, perms);
		}
		
		int q=sc.nextInt();//查詢語句數目
		String[] result=new String[q];
		Query:for(int i=0;i<q;i++)//執行查詢
		{
			String squeryName=sc.next();//待查詢用戶名
			String[] temp=sc.next().split(":");//下標0爲待查詢權限名,若存在下標1則爲權限等級
			if(!users.containsKey(squeryName))//判斷用戶是否存在
			{
				result[i]="false";
				continue Query;
			}
			else if(!perm.containsKey(temp[0]))//判斷權限是否存在
			{
				result[i]="false";
				continue Query;
			}
			else if(temp.length==1)//查詢權限不分等級
			{
				result[i]=queryResult(squeryName,temp[0],-1);
			}
			else {//查詢權限分等級
				result[i]=queryResult(squeryName,temp[0],Integer.valueOf(temp[1]));
			}
		}
		for(String s:result)
			System.out.println(s);
	}
	//執行權限查詢並返回結果,參數待查詢用戶名,待查詢權限名,所需查詢該權限的等級
	public static String queryResult(String userName,String permName,int queryLevel)
	{
		if(!users.get(userName).containsKey(permName))//判斷該用戶是否具有該權限
		{
			return "false";
		}
		else//判斷該用戶該權限等級是否匹配
		{
			if(queryLevel!=-1)//查詢分等級
			{
				//判斷用戶所擁有權限是否大於所需查詢權限
				if(users.get(userName).get(permName)>=queryLevel)
					return "true";
				else
					return "false";
			}
			else//查詢不分等級
			{
				if(perm.get(permName)==-1)//權限本身不分級,返回True/False
					return "true";
				else//權限本身分級,返回最高級別
					return String.valueOf(users.get(userName).get(permName));
			}
			
		}
	}

}

 

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