《算法导论》15-3:编辑距离


(1)初始化:

cost[i][0] =deleteCost * i

cost[0][j] =insertCost * i


(2)递推公式:


(3)kill操作


public class EditDistance {
	private String src;            //源文本串
	private String dst;			   //目标字符串
	//6种转换操作的代价
	private int[] opCost;
	//opCost[0] copy代价
	//opCost[1] replace代价
	//opCost[2] delete代价
	//opCost[3] insert代价
	//opCost[4] exchange代价
	//opCost[5] kill代价
	
	private int[][] cost;
	
	public EditDistance(String src, String dst, int[] opCost){
		this.src = src;
		this.dst = dst;
		this.opCost = opCost;
		
		this.cost = new int[src.length() + 1][dst.length() + 1];
	}
	
	public int getMinCost(){
		int i = 0, j = 0 , k = 0;
		int[] currentCost = new int[opCost.length - 1];
		
		for(i = 0; i <= src.length(); i++){
			cost[i][0] = i * opCost[2];
		}
		
		for(j = 0; j <= dst.length(); j++){
			cost[0][j] = j * opCost[3];
		}
		
		for(i = 1 ; i <= src.length(); i++){
			for(j = 1; j <= dst.length(); j++){
				for(k = 0; k < opCost.length - 1; k++){
					currentCost[k] = Integer.MAX_VALUE;
				}
				//use copy operation
				if(src.charAt(i-1) == dst.charAt(j-1)){
					currentCost[0] = opCost[0] + cost[i - 1][j - 1];
				}else{
					//use replace operation
					currentCost[1] = opCost[1] + cost[i - 1][j - 1];
					
					//use delete operation
					currentCost[2] = opCost[2] + cost[i - 1][j];
					
					//use exchange operation
					if(i >= 2 && j >= 2 && 
					   src.charAt(i - 1) == dst.charAt(j - 2) && 
					   src.charAt(i - 2) == dst.charAt(j - 1)){
						currentCost[4] = opCost[4] + cost[i - 2][j - 2];
					}
				}
				//use insert operation
				currentCost[3] = opCost[3] + cost[i][j - 1];
				//choose the min Cost of the 5 operation as the current cost
				cost[i][j] = min(currentCost);
			}
		}
		
		int minCost = cost[src.length()][dst.length()];
		for(k = 1; k < src.length(); k++){
			if(cost[k][src.length()] + opCost[5] < minCost){
				minCost = cost[k][dst.length()] + opCost[5];
			}
		}
		
		return minCost;
	}
	
	private int min(int[] array){
		int minValue = Integer.MAX_VALUE;
		for(int i = 0; i < array.length; i++){
			if(array[i] < minValue) minValue = array[i];
		}
		return minValue;
	}
	
	public static void main(String[] args){
		String src = "algorithm";
		String dst = "altruistic";
		int[] opCost = {1, 2, 3, 3, 2, 5};
		EditDistance ED = new EditDistance(src, dst, opCost);
		System.out.println(ED.getMinCost());
	}
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个最短路径问题,可以使用Dijkstra算法或者Floyd算法进行求解。以下是使用Dijkstra算法的示例代码: ```python import heapq # 构建有向图 graph = { 'S': {'A1': 6, 'A3': 3}, 'A1': {'S': 6, 'A2': 3, 'A3': 6, 'B1': 5, 'B2': 4}, 'A2': {'A1': 3, 'B1': 6, 'B2': 6, 'C1': 7, 'C2': 8, 'T': 3}, 'A3': {'S': 3, 'A1': 6, 'B1': 7, 'B2': 4}, 'B1': {'A1': 5, 'A2': 6, 'A3': 7, 'B2': 7, 'C1': 7, 'C2': 8}, 'B2': {'A1': 4, 'A2': 6, 'A3': 4, 'B1': 7, 'C1': 8, 'C2': 9}, 'C1': {'B1': 7, 'B2': 8, 'A2': 7, 'C2': 5, 'T': 5}, 'C2': {'B1': 8, 'B2': 9, 'A2': 8, 'C1': 5, 'T': 6}, 'T': {'A2': 3, 'C1': 5, 'C2': 6} } def dijkstra(graph, start, end): # 初始化距离列表和堆 distances = {node: float('inf') for node in graph} distances[start] = 0 heap = [(0, start)] # 初始化前驱节点列表 previous_nodes = {node: None for node in graph} while heap: # 弹出堆中距离最小的节点 (distance, current_node) = heapq.heappop(heap) # 如果该节点已经访问过,则跳过 if distance > distances[current_node]: continue # 遍历该节点的所有邻居 for neighbor, weight in graph[current_node].items(): new_distance = distance + weight # 如果新的距离比之前的距离更小,则更新距离和前驱节点 if new_distance < distances[neighbor]: distances[neighbor] = new_distance previous_nodes[neighbor] = current_node heapq.heappush(heap, (new_distance, neighbor)) # 构建路径 path = [] current_node = end while current_node is not None: path.insert(0, current_node) current_node = previous_nodes[current_node] return distances[end], path start = 'S' end = 'T' distance, path = dijkstra(graph, start, end) print(f'最短路径为:{" -> ".join(path)},长度为:{distance}') ``` 在上述代码中,我们首先构建了一个有向图,然后使用Dijkstra算法求解经过指定节点的最短路径。其中,使用了堆来维护当前距离最小的节点,以提高算法的效率。最后,输出了最短路径及其长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值