Recursive之String Parsing(Trie的运用之一)

本文提供了一种解决CC150第17章最后一题的方法,利用Trie数据结构辅助进行字符串解析,通过递归算法实现字符串到句子的有效转换,并给出了解析过程的具体代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Topic:面经

题目:

CC150上面的17章最后一题,将一个去掉标点空格大写字母变小写的字符串,根据给定的字典,算出解析后的句子。


Code:

class Test{
    public static void main(String[] args){
		Test test = new Test();
		Trie<Integer> dic = new Trie<Integer>();
		dic.put("i", 1);
		dic.put("love", 2);
		dic.put("you", 3);
		dic.put("cinderella", 4);
		
		String str = "iloveyoucinderella";
		HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();			//<WordStart, Minimum...>
		test.parseString(str, hm, dic, 0, 0);
		for(Integer key : hm.keySet()){
			System.out.println(key + " : " + hm.get(key));
		}
    }
	
	public int parseString(String str, HashMap<Integer, Integer> hm, Trie<Integer> dic, int start, int end){
		if(end >= str.length()) return end - start;
		if(hm.containsKey(start)) return hm.get(start);
		String cur = str.substring(start, end+1);
		int bestExact = parseString(str, hm, dic, start+1, end+1), bestExtend = Integer.MAX_VALUE;
		if(!dic.containPart(cur)) bestExact += cur.length();
		else bestExtend = parseString(str, hm, dic, start, end+1);
		int res = Math.min(bestExact, bestExtend);
		hm.put(start, res);
		return res;
	}
}

class Trie<Value>{
	public static int acs = 256;
	Node root = new Node();
	private static class Node{
		Object value;
		Node[] next = new Node[acs]; 
	}
	
	//递归插入
	public void put(String key, Value value){
		put(root, key, value, 0);
	}
	private Node put(Node x, String key, Value value, int pos){
		if(x==null) x = new Node();
		if(pos == key.length()){
			x.value = value;
			return x;
		}
		char c = key.charAt(pos);
		x.next[c] = put(x.next[c], key, value, pos+1);
		return x;
	}
	
	
	//递归搜索
	public Value get(String key){
		return get(root, key, 0);
	}
	private Value get(Node x, String key, int pos){
		if(x == null) return null;
		if(pos == key.length()) return (Value)x.value;
		char c = key.charAt(pos);
		return get(x.next[c], key, pos+1);
	}
	
	
	/* 
	
	//非递归插入
	public void put(String key, Value value){
		int i = 0;
		Node cur = root;
		while(i < key.length()){
			char c = key.charAt(i);
			if(cur.next[c] == null){
				Node x = new Node();
				cur.next[c] = x;
			}
			cur = cur.next[c];
			i++;
		}
		if(i == key.length()) cur.value = value;
	}
	
	//非递归搜索
	public Value get(String key){
		int i = 0;
		Node cur = root;
		while(i < key.length()){
			char c = key.charAt(i);
			cur = cur.next[c];
			if(cur == null) return null;
			i++;
		}
		return (Value)cur.value;
	}
	
	*/
	
	//contain part判断给定的key是否是trie结构中的一部分
	public boolean containPart(String key){
		Node cur = root;
		int i = 0;
		while(i < key.length()){
			char c = key.charAt(i);
			cur = cur.next[c];
			if(cur == null) return false;
			i++;
		}
		return true;
	}
	

	//contains方法
	public boolean contains(String key){
		return get(key)!=null;
	}
}

总结:

解析方法是个递归,还没弄得很明白。另一个重点,这是第一次Trie的运用,以后还将有一道搜索引擎相关的应用。


补充:

经过两天的断断续续的思考,对着道题的递归解析有了进一步的认识,下面是改良版。

class Test{
    public static void main(String[] args){
		Test test = new Test();
		Trie<Integer> dic = new Trie<Integer>();
		// dic.put("i", 1);
		dic.put("love", 2);
		dic.put("you", 3);
		// dic.put("cinderella", 4);
		
		String str = "iloveyoucinderella";
		HashMap<Integer, Result> hm = new HashMap<Integer, Result>();			//<WordStart, Minimum...>
		System.out.println(test.parse(0, 0, hm, dic, str).parsed);
    }
	
	public Result parse(int start, int end, HashMap<Integer, Result> hm, Trie<Integer> dic, String str){
		if(end >= str.length()){
			return new Result(end-start, str.substring(start).toUpperCase());
		}
		if(hm.containsKey(start)) return hm.get(start).clone();
		
		String cur = str.substring(start, end+1);
		Result bestExact = parse(end+1, end+1, hm, dic, str);
		if(!dic.contains(cur)){
			bestExact.invalid += cur.length();
			bestExact.parsed = cur.toUpperCase() + " " + bestExact.parsed;
		}
		else{
			bestExact.parsed = cur + " " + bestExact.parsed;
		}
		
		Result bestExtend = null;
		if(dic.containPart(cur)){
			bestExtend = parse(start, end+1, hm, dic, str);
		}
		
		Result res = Result.min(bestExact, bestExtend);
		hm.put(start, res.clone());
		return res;
	}
}

class Result{
	int invalid = Integer.MAX_VALUE;
	String parsed = "";
	Result(int invalid, String parsed){
		this.invalid = invalid;
		this.parsed = parsed;
	}
	
	public Result clone(){
		return new Result(this.invalid, this.parsed);
	}
	
	public static Result min(Result r1, Result r2){
		if(r1 == null) return r2;
		if(r2 == null) return r1;
		return r1.invalid < r2.invalid ? r1 : r2;
	}
}

class Trie<Value>{
	public static int acs = 256;
	Node root = new Node();
	private static class Node{
		Object value;
		Node[] next = new Node[acs]; 
	}
	
	//递归插入
	public void put(String key, Value value){
		put(root, key, value, 0);
	}
	private Node put(Node x, String key, Value value, int pos){
		if(x==null) x = new Node();
		if(pos == key.length()){
			x.value = value;
			return x;
		}
		char c = key.charAt(pos);
		x.next[c] = put(x.next[c], key, value, pos+1);
		return x;
	}
	
	
	//递归搜索
	public Value get(String key){
		return get(root, key, 0);
	}
	private Value get(Node x, String key, int pos){
		if(x == null) return null;
		if(pos == key.length()) return (Value)x.value;
		char c = key.charAt(pos);
		return get(x.next[c], key, pos+1);
	}
	
	
	/* 
	
	//非递归插入
	public void put(String key, Value value){
		int i = 0;
		Node cur = root;
		while(i < key.length()){
			char c = key.charAt(i);
			if(cur.next[c] == null){
				Node x = new Node();
				cur.next[c] = x;
			}
			cur = cur.next[c];
			i++;
		}
		if(i == key.length()) cur.value = value;
	}
	
	//非递归搜索
	public Value get(String key){
		int i = 0;
		Node cur = root;
		while(i < key.length()){
			char c = key.charAt(i);
			cur = cur.next[c];
			if(cur == null) return null;
			i++;
		}
		return (Value)cur.value;
	}
	
	*/
	
	//contain part判断给定的key是否是trie结构中的一部分
	public boolean containPart(String key){
		Node cur = root;
		int i = 0;
		while(i < key.length()){
			char c = key.charAt(i);
			cur = cur.next[c];
			if(cur == null) return false;
			i++;
		}
		return true;
	}
	

	//contains方法
	public boolean contains(String key){
		return get(key)!=null;
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值