欢迎访问我的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


被折叠的 条评论
为什么被折叠?



