C#,文字排版的折行问题(Word-wrap problem)的算法与源代码

1、英文的折行问题

给定一个单词序列,以及一行中可以输入的字符数限制(线宽)。

在给定的顺序中放置换行符,以便打印整齐。

假设每个单词的长度小于线宽。

像MS word这样的文字处理程序负责放置换行符。

这个想法是要有平衡的线条。

换句话说,不是只有几行有很多额外空间,有些行有少量额外空间。

2、中文的处理

文字断行完成后,需要进行行内排版。

文档行中各个字符的宽度之和不大可能正好等于文档容器的客户区宽度。两者会有空白差。

由于中文字符和英文字符宽度不一样,对于不等宽字体,各个英文字符、数字字符等宽度还不一样。使得各个文本行的字符宽度之和是不一样的,使得各个文档行右边缘是参差不齐的。这样比较严重的影响美观。

为此需要将文档行的宽度拉长成文档容器客户区宽度,由此会额外的制造出不少空白,此时需要将这些空白比较均匀的分摊到各个字符上。此处是比较均匀的分摊,但不是完全均匀,是有一定的分布算法的。

同一行中,字符不是相对孤立的,而且从逻辑上分为一组一组的,对于汉字和标点符号,它们是各自为政,自己组成一组。对于连续的英文字母字符和阿拉伯数字,它们逻辑上是同一组的,一起构成一个完整的单词,因此同一组之间的字符之间应该是紧密连接在一起,不得拆开。[袁永福版权所有]

为此要分摊由于文字两边对齐而造成的额外空间时,首先要对文档行的字符进行分组,然后将额外的空白平均分摊到字符组上。

3 源程序

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
	public static partial class Algorithm_Gallery
	{
		public static int WordWrap_Solve(int[] nums, int k)
		{
			int[,] memo = new int[nums.Length, k + 1];
			for (int i = 0; i < memo.GetLength(0); i++)
			{
				for (int j = 0; j < memo.GetLength(1); j++)
				{
					memo[i, j] = -1;
				}
			}
			return WordWrap_Solve_UsingMemo(nums, nums.Length, k, 0, k, memo);
		}

		private static int WordWrap_Solve_Utility(int[] words, int n, int length, int wordIndex, int remLength, int[,] memo)
		{
			if (wordIndex == n - 1)
			{
				memo[wordIndex, remLength] = words[wordIndex] < remLength ? 0 : Square(remLength);
				return memo[wordIndex, remLength];
			}

			int currWord = words[wordIndex];

			if (currWord < remLength)
			{
				int sa = WordWrap_Solve_UsingMemo(words, n, length, wordIndex + 1, (remLength == length) ? (remLength - currWord) : (remLength - currWord - 1), memo);
				int sb = Square(remLength) + WordWrap_Solve_UsingMemo(words, n, length, wordIndex + 1, length - currWord, memo);
				return Math.Min(sa, sb);
			}
			else
			{
				return Square(remLength) + WordWrap_Solve_UsingMemo(words, n, length, wordIndex + 1, length - currWord, memo);
			}
		}

		private static int WordWrap_Solve_UsingMemo(int[] words, int n, int length, int wordIndex, int remLength, int[,] memo)
		{
			if (memo[wordIndex, remLength] != -1)
			{
				return memo[wordIndex, remLength];
			}

			memo[wordIndex, remLength] = WordWrap_Solve_Utility(words, n, length, wordIndex, remLength, memo);
			return memo[wordIndex, remLength];
		}

		private static int Square(int n)
		{
			return n * n;
		}


		private static List<string> solution = new List<string>();

		public static int WWP_Solution(int[] p, int n)
		{
			int k;
			if (p[n] == 1)
			{
				k = 1;
			}
			else
			{
				k = WWP_Solution(p, p[n] - 1) + 1;
			}
			solution.Add("Line number " + k + ": From word no. " + p[n] + " to " + n);
			return k;
		}

		public static void WordWrap_Solve(int[] sentence, int n, int M)
		{
			int[,] extras = new int[n + 1, n + 1];
			int[,] lc = new int[n + 1, n + 1];
			int[] c = new int[n + 1];
			int[] p = new int[n + 1];

			for (int i = 1; i <= n; i++)
			{
				extras[i, i] = M - sentence[i - 1];

				for (int j = i + 1; j <= n; j++)
				{
					extras[i, j] = extras[i, j - 1] - sentence[j - 1] - 1;
				}
			}
			for (int i = 1; i <= n; i++)
			{
				for (int j = i; j <= n; j++)
				{
					if (extras[i, j] < 0)
					{
						lc[i, j] = int.MaxValue;
					}
					else if (j == n && extras[i, j] >= 0)
					{
						lc[i, j] = 0;
					}
					else
					{
						lc[i, j] = extras[i, j] * extras[i, j];
					}
				}
			}
			c[0] = 0;
			for (int j = 1; j <= n; j++)
			{
				c[j] = int.MaxValue;
				for (int i = 1; i <= j; i++)
				{
					if (c[i - 1] != int.MaxValue && lc[i, j] != int.MaxValue && (c[i - 1] + lc[i, j] < c[j]))
					{
						c[j] = c[i - 1] + lc[i, j];
						p[j] = i;
					}
				}
			}

			solution.Clear();
			WWP_Solution(p, n);
		}
	}
}
相关推荐
爱思德学术13 分钟前
中国计算机学会(CCF)推荐学术会议-B(交叉/综合/新兴):BIBM 2025
算法
冰糖猕猴桃24 分钟前
【Python】进阶 - 数据结构与算法
开发语言·数据结构·python·算法·时间复杂度、空间复杂度·树、二叉树·堆、图
lifallen37 分钟前
Paimon vs. HBase:全链路开销对比
java·大数据·数据结构·数据库·算法·flink·hbase
liujing102329291 小时前
Day04_刷题niuke20250703
java·开发语言·算法
2401_881244402 小时前
Treap树
数据结构·算法
乌萨奇也要立志学C++2 小时前
二叉树OJ题(单值树、相同树、找子树、构建和遍历)
数据结构·算法
网安INF2 小时前
深度学习中的逻辑回归:从原理到Python实现
人工智能·python·深度学习·算法·逻辑回归
wsxqaz2 小时前
浏览器原生控件上传PDF导致hash值不同
算法·pdf·哈希算法
NAGNIP3 小时前
Transformer注意力机制——MHA&MQA&GQA
人工智能·算法
摘星编程3 小时前
多模态AI Agent技术栈解析:视觉-语言-决策融合的算法原理与实践
人工智能·算法·多模态ai·视觉语言融合·ai决策算法