自动换行问题(word wrap problem )几种解法之比较
来源:互联网 发布:电话数据统计 编辑:程序博客网 时间:2024/06/07 07:59
问题描述:
给定一个单词序列和一个每行最做可放多少个字符的限制。需要把这个单词序列按限制行宽摆放完,使得每行剩余的空间的成本和最小。
在同一行不同单词见的空格符不计入剩余的空间。假定某行的剩余空间是N,则其成本是N*N,举例说明之:
假定给定序列为:"Geeks for Geeks presents word wrap problem", 每行宽度限制为15,
则最优的摆放为:
Geeks for Geeks presents word wrap problem
剩余空间的成本之和为: 0 + 2 * 2 + 3 * 3;
具体问题的描述可见(www.geeksforgeeks.org)
问题解法:
下面用三种解法给出答案,分别为
1. 暴力搜索;
2. 递归解法;
3. 动态规划;(注:本文的动态规划解法直接来自geeksforgeeks,笔者目前还没找到更简单的动态规划实现)
1,2仅能给出次优解法,他们的策略为贪婪策略;
解决代码:
#ifndef _WORD_WRAP_H_#define _WORD_WRAP_H_#include <stdlib.h>#include <stdio.h>/** The implementation of the method of brute force search for word wrap problem**/int WordWrapBrute( const int words[], int size, int width ){int len = width;int cost = 0;for( int i = 0; i < size; i++ ) // loop each word{if( len > words[i] ){len -= words[i] + 1;}else if( len == words[i] ){len -= words[i];}else if( len < words[i] ){if( len > 0 )cost += ( len + 1 ) * ( len + 1 );len = width;len -= words[i] + 1;}}return cost;}/** The implementation of recursive method for word wrap problem**/int WordWrapRecur( const int words[], int size, int cur, int rowIdx, int curWidth, int width ){if( cur == size ){return 0;}for( int i = cur; i < size; i++ ){if( curWidth - words[i] >= 0 ){return WordWrapRecur( words, size, i + 1, rowIdx, curWidth - words[i] - 1, width );}else{rowIdx++;if( curWidth != 0 ){return ( curWidth + 1) * ( curWidth + 1) +WordWrapRecur( words, size, i + 1, rowIdx, width - words[i] - 1, width );}else{return WordWrapRecur( words, size, i + 1, rowIdx, width - words[i] - 1, width );}}}}/** Output solution when apply to dynamic programming method**/int OutputSolution( int record[], int size ){int k = -1;if( 1 == record[size] ){k = 1;}else{k = OutputSolution( record, record[size] - 1 ) + 1;}printf ("Line number %d: From word no. %d to %d \n", k, record[size], size);return k;}/** The implementation of dynamic programming for word wrap problem**/int WordWrapDP( const int words[], int size, int width ){// construct table can be used to record the remainder space when from i to j in single rowint** table = new int*[size + 1];assert( table );for( int i = 0; i <= size; i++ ){table[i] = new int[ width + 1 ];assert( table[i] );}// calculate i to j remainder space in single rowfor( int i = 1; i <= size; i++ ){table[i][i] = width - words[i - 1];for( int j = i + 1; j <= size; j++ ){table[i][j] = table[i][j - 1] - words[j-1] - 1;}}// construct cost arrayint** cost = new int*[size + 1];assert( cost );for( int i = 0; i <= size; i++ ){cost[i] = new int[ width + 1 ];memset( cost[i], 0x00, sizeof(int)*( width + 1) );assert( cost[i] );}for( int i = 1; i <= size; i++ ){for( int j = i; j <= size; j++ ){if( table[i][j] < 0 ){cost[i][j] = INT_MAX;}else if( size == j && table[i][j] >= 0 ){cost[i][j] = 0;}else{cost[i][j] = table[i][j] * table[i][j];}}}int* result = new int[size + 1];int* record = new int[size + 1];memset( record, 0x00, sizeof(int)*(size + 1) );result[0] = 0;for( int j = 1; j <= size; j++ ){result[j] = INT_MAX;for( int i = 1; i <= j; i++ ){if( result[i - 1] != INT_MAX && cost[i][j] != INT_MAX && result[i - 1] + table[i][j] < result[j] ){result[j] = result[i - 1] + table[i][j];record[j] = i;}}} OutputSolution( record, size );for( int i = 0; i <= size; i++ ){delete [] table[i];delete [] cost[i];}delete [] table;delete [] cost;return 0;}void TestWordWrap(){int words[] = {3, 2, 2, 5};int size = sizeof(words)/sizeof(words[0]);int width = 6;int cost = WordWrapRecur( words, size, 0, 1, 6, 6 );int newCost = WordWrapBrute( words, size, width );WordWrapDP( words, size, width );getchar();}#endif
0 0
- 自动换行问题(word wrap problem )几种解法之比较
- DP19 自动换行问题 Word Wrap Problem @geeksforgeeks
- 字符串分割单词(word break problem)问题几种解法之比较
- 段落自动换行问题: word-wrap: break-word;
- CSS3之文本换行word-wrap
- 过长文字自动换行的技巧 Word-Break Word-Wrap
- 自动换行word-break和word-wrap的区别
- word-wrap 文本换行
- 单词太长导致自动换行,出现空白区域。——word-wrap和word-break(英文单词换行)
- word-wrap同word-break的区别,字符串换行问题
- Sublime Text 2 自动开启换行 Word Wrap
- css换行(white-space、word-wrap、word-break)
- 自动换行word-break:break-all和word-wrap:break-word的区别
- 自动换行word-break:break-all和word-wrap:break-word的区别
- CSS 自动换行 word-break:break-all和word-wrap:break-word
- 自动换行word-break:break-all和word-wrap:break-word的区别
- 自动换行word-break:break-all和word-wrap:break-word的区别
- div自动换行word-break:break-all和word-wrap:break-word的区别
- 修改jtree的节点图标
- Could not create the view: An unexpected exception was thrown. 电脑突然断电,myeclipse非正常关闭,出现错误
- 黑马程序员——学习日记18 java网络编程
- Android开发学习之Service详解二
- POJ-3630 Phone List 字典树
- 自动换行问题(word wrap problem )几种解法之比较
- 快排存档
- DoG角点检测
- 合成润滑油优点
- C++实现单例模式
- ICPC Score Totalizer Software 2309
- Android之内存泄漏调试学习与总结
- 谈Objective-C Block的实现
- XCode 5安装旧版iOS SDK