开源夏令营之foldcolumn工具及解决方案(三)表格列超长自动换行实现
2014-07-24 23:34
513 查看
常用自动换行算法
参见WIKI关于自动换行算法的介绍链接自动换行是一个最优化问题,因不同的需求有不同的解决办法,下面是两种常用的算法。
最小长度
这种方法是实现自动换行的一个简单方法,属于贪心算法:尽可能多的单词放进一行里,直到所有的单词都已经放进去为止。这是很多现代文字处理软件的做法,如Microsoft Word和Open Office 。这个算法在追求最少行数的目标上能够达到最优化。下面是该算法的伪代码实现:SpaceLeft = LineWidth for each Word in Text if Width(Word) > SpaceLeft insert line break before Word in Text SpaceLeft = LineWidth - Width(Word) else SpaceLeft = SpaceLeft - (Width(Word) + SpaceWidth)
LineWidth指一行的宽度,SpaceLeft指一行中剩余的空格,SpaceWidth是一个空格的宽度,Text是输入的文本,Word是文本中的一个单词。
注意:实现中,对于连续不能换行长度大于表格列宽的字符串(如长单词)直接从下一行开始输出。
最小破损度
在TeX中使用的,则是另一个算法,旨在将行尾空格数的平方最小化,以产生一个更加美观的结果。以上的最小长度算法不能完成这一目标,为了解决这个问题,我们需要定义一个惩罚函数c(i, j),用于计算包含单词Word[i]到单词Word[j]的一行的代价:其中P通常为2或3。另外,有一些特殊的情况值得考虑:如果结果为负(即单词串不能全部放在一行里),惩罚函数需要反映跟踪或压缩文本以适应一行的代价;如果这是不可能的,则返回无穷大。最优解的代价可以用以下的递归式定义:
这种方法的时间与空间代价是值得考虑的:当利用动态规划来实现,时间和空间复杂度均为O(N^2)。
foldcolumn自动换行实现
算法选择
foldcolumn采用上面的最小长度方法实现自动换行,而不采用最小破损度的方法,下面分析原因:(1)从命令行管道等读入数据,不能提前读入数据,所以不适合最小破损度的方法;
(2)从文件读入数据时,可以使用最小破损度的方法,但是这种算法的复杂度不适合本项目,一是空间复杂度较高,二是需要多次读入数据来确定列宽。
算法实现
循环读入一行数据,按列分隔符分列,对每列循环使用最小长度算法进行输出,这里和上面的算法描述不同的是,不是按单词来处理,而是按连续不能断行的字符串来处理。其中借助libunibreak的liblinebreak库判读某个字符后面是否可以断行,liblinebreak的使用方法如下:liblinebreak/libunibreak提供了简单明了的函数接口,使我们能对Annex 14/29等不是很了解的情况下,能根据其返回信息,决定该如何换行、断单词。如使用时,先init初始化,再根据编码调用set_linebreaks_utf32(const
utf32_t*s, size_t len, const char *lang, char *brks)等相应函数,获得一段数据的必须换行、允许换行、不可换行等信息并存储在brks,然后我们根据brks再结合实际需求选择某些可以断行位置实现断行输出。具体实现参见foldcolumn/libfoldcolumn/src/foldcolumn.c foco_dumpOneLineOfColumn函数。
效果展示
不包含连续不可断行的长字符串
包含连续不可断行的长字符串
参考
自动换行实现链接libunibreak链接
相关文章推荐
- 开源夏令营之foldcolumn工具及解决方案(二)确定表格属性、绘制表格
- 开源夏令营之foldcolumn工具及解决方案(五)数值精度处理实现
- 开源夏令营之foldcolumn工具及解决方案之box-drawing character
- 开源夏令营之foldcolumn工具及解决方案(一)
- 开源夏令营之foldcolumn工具及解决方案之中期总结
- 开源夏令营之foldcolumn工具及解决方案之获取终端宽度
- 开源夏令营之foldcolumn工具及解决方案--学习制作manpage
- 开源夏令营之foldcolumn工具及解决方案(七)测试与总结
- 开源夏令营之foldcolumn工具及解决方案(六)制作manpage与Makefile
- 开源夏令营之foldcolumn工具及解决方案(四)数值精度与对齐方式处理
- Table表格内容超长时:自动截取、自动换行
- GridView实现自动编号;GridView实现自定义时间货币等字符串格式;GridView实现用“...”代替超长字符串;GridView一般换行与强制换行;GridView显示隐藏某一列;
- XSL中实现HTML的表格自动换行
- Table表格内容超长时:自动截取、自动换行
- XSL中实现HTML的表格自动换行
- CSS 实现表格中文字不换行,超长部分显示省略号
- 表格中如何控制自动换行问题
- 让英文字符串超出表格宽度自动换行
- JS+ASP 实现超长文章自动分页
- CSS网页制作时实现自动换行的小技巧