JAVA CCF-201509-3 模板生成系统 80分90分的看过来

欢迎访问我的CCF认证解题目录

 

题目描述

 

思路过程

这题提交了3次,第一次80分,第二次90分,第三次100分

 

第一次

这题目最开始想的是:使用string的replaceAll直接替换不就好了?定义一个类或map存储变量和值,然后每行都去遍历一遍规则,如果存在对应的变量名,则替换,最后如果还存在其他的{{ xx }},直接替换为"",输出

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		int n = in.nextInt(), m = in.nextInt();
		ArrayList<String> str = new ArrayList<String>();//字符串
		ArrayList<Regex> regex = new ArrayList<Regex>();//规则
		ArrayList<String> ans = new ArrayList<String>();//结果
		
		in.nextLine();
		for ( int i = 0; i < n; i++ ) str.add(in.nextLine());//读入字符串
		for ( int i = 0; i < m; i++ ) {//读入规则
			String name = in.next(), val = in.nextLine();
			regex.add(new Regex("\\{\\{ "+name+" \\}\\}", val.substring(2, val.length()-1)) );
		}
		
		for (String string : str) {//替换
			for (Regex r : regex) {
				string = string.replaceAll(r.name, r.val);
			}
			string = string.replaceAll("\\{\\{ .* \\}\\}", "");
			ans.add(string);
		}
		
		for (String result : ans) {//输出
			System.out.println(result);
		}
	}

}
class Regex{
	String name, val;//变量名、变量值

	public Regex(String name, String val) {
		this.name = name;
		this.val = val;
	}

	@Override
	public String toString() {
		return "name=" + name + ", val=" + val;
	}
	
}

第二次

很明显,刚才那个思路是错误的,如果变量名对应的值是{{ xx }}类型的话,最后会给替换成"",最开始不知道错在哪,ccf给的提示是"运行错误",不是"错误",害我一直没往测试数据方面想。。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		int n = in.nextInt(), m = in.nextInt();
		ArrayList<String> str = new ArrayList<String>();//字符串
		HashMap<String, String> map = new HashMap<String, String>();
		
		in.nextLine();
		for ( int i = 0; i < n; i++ ) str.add(in.nextLine());//读入字符串
		for ( int i = 0; i < m; i++ ) {//读入规则
			String name = in.next(), val = in.nextLine();
			map.put(name, val.substring(2, val.length()-1));
		}
		
		for (String string : str) {//替换
			Pattern p = Pattern.compile("\\{\\{ (.*?) \\}\\}");
			Matcher mat = p.matcher(string);
			while ( mat.find() ) {
				String temp = mat.group(1);
				if ( map.containsKey(temp) ) {
					string = string.replaceAll("\\{\\{ "+temp+" \\}\\}", map.get(temp));
				} else string = string.replaceAll("\\{\\{ "+temp+" \\}\\}", "");
			}
			System.out.println(string);
		}
	}
}

第三次

这次错误很快就找出了问题所在

对于这个数据就过不了

11 2
<!DOCTYPE html>
<html>
<head>
<title>User {{ name }}</title>
</head>
<body>
<h1>{{ name }}</h1>
<p>Email: <a href="mailto:{{ email }}">{{ name }}</a></p>
<p>Address: {{ address }}</p>
</body>
</html>

name "{{ David Beckham }}"
email "{{ name }}"

 第一次会把{{ email }}替换成{{ name }},而后会把name再次替换掉。所以每次替换后要终止对于前面字符串的操作。

这里我采用递归的方式,重复把剩下的字符串进行递归

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt(), m = in.nextInt();
		ArrayList<String> str = new ArrayList<String>();//字符串
		HashMap<String, String> map = new HashMap<String, String>();
		
		in.nextLine();//处理掉未读完的那一行
		for ( int i = 0; i < n; i++ ) str.add(in.nextLine());//读入字符串
		for ( int i = 0; i < m; i++ ) {//读入规则
			String name = in.next(), val = in.nextLine();
			map.put(name, val.substring(2, val.length()-1));
		}
		
		for (String string : str) {//替换
			DFS(string, map);
			System.out.println();
		}
	}
	/**
	 * 用于匹配输出,例如:<p>Email: <a href="mailto:{{ email }}">{{ email }}</a></p>
	 * 1.根据正则,会找到{{ email }},然后输出<p>Email: <a href="mailto:
	 * 2.接着查找email是否存在映射中,如果有,输出对应的val
	 * 3.将">{{ email }}</a></p>继续递归
	 * 4.重复123,直到find()函数为false
	 */
	public static void DFS( String string, HashMap<String, String> map ) {
		Pattern p = Pattern.compile("\\{\\{ (.*?) \\}\\}");//正则,找到{{ xx }},非贪婪模式,括号用于找到变量名
		Matcher mat = p.matcher(string);
		if ( mat.find() ) {//找到{{ xx }}
			int start = mat.start(), end = mat.end();
			String temp = mat.group(1);//获取捕获组,即变量名
			System.out.print(string.substring(0, start));//输出"{{"前面的内容
			if ( map.containsKey(temp) ) System.out.print(map.get(temp));//如果有对应的key
			DFS(string.substring(end), map);//递归"}}"后面的内容
		}else System.out.print(string);//找不到时直接输出
	}
}

 

为自己的另一篇博客打个广告o(* ̄▽ ̄*)o

不会使用正则?链接:https://blog.csdn.net/weixin_43732798/article/details/100081039

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值