问题描述:

问题描述

  Markdown 是一种很流行的轻量级标记语言(lightweight markup language),广泛用于撰写带格式的文档。例如以下这段文本就是用 Markdown 的语法写成的:
CCF201703 Markdown(JAVA)


  这些用 Markdown 写成的文本,尽管本身是纯文本格式,然而读者可以很容易地看出它的文档结构。同时,还有很多工具可以自动把 Markdown 文本转换成 HTML 甚至 Word、PDF 等格式,取得更好的排版效果。例如上面这段文本通过转化得到的 HTML 代码如下所示:
CCF201703 Markdown(JAVA)


  本题要求由你来编写一个 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 语言的用户可以参考以下代码片段来读取输入内容。
CCF201703 Markdown(JAVA)
CCF201703 Markdown(JAVA)
CCF201703 Markdown(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));
			}
			
		}
	}

}

 

相关文章: