我现在有一个可行的解决方案,但是对于这么简单(看起来)简单的事情来说似乎很难看。
我尝试在添加单词超过中间标记时打破它,添加单词之前和之后均会拆分,但是根据单词的长度,它可能不平衡于第一行或第二行。
在复杂的修复之前,我最初遇到的样本输入是:
输入"Macaroni Cheese"
和"Cheese Macaroni"
应该分别输出"Macaroni<br/> Cheese"
和"Cheese<br/> Macaroni"
。
但是,更简单的解决方案要么在第一个上起作用,但在第二个上却不起作用,或者相反。
因此,这就是我的工作方式,但我想知道是否有更优雅的方法可以做到这一点。
public string Get2LineDisplayText(string original)
{
string[] words = original.Split(new[] {' ', '\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
//Degenerate case with only 1 word
if (words.Length <= 1)
{
return original;
}
StringBuilder builder = new StringBuilder();
builder.Append(words[0]); //Add first word without prepending space
bool addedBr = false;
foreach (string word in words.Skip(1))
{
if (builder.Length + word.Length < original.Length / 2) //Word fits on the first line without passing halfway mark
{
builder.Append(' ' + word);
}
else if (!addedBr) //Adding word goes over half, need to see if it's more balanced on the 1st or 2nd line
{
int diffOnLine1 = Math.Abs((builder.Length + word.Length) - (original.Length - builder.Length - word.Length));
int diffOnLine2 = Math.Abs((builder.Length) - (original.Length - builder.Length));
if (diffOnLine1 < diffOnLine2)
{
builder.Append(' ' + word);
builder.Append("<br/>");
}
else
{
builder.Append("<br/>");
builder.Append(' ' + word);
}
addedBr = true;
}
else //Past halfway and already added linebreak, just append
{
builder.Append(' ' + word);
}
}
return builder.ToString();
}
样本输入/输出:
最佳答案
这是我想出的:
public static string Get2Lines(string input)
{
//Degenerate case with only 1 word
if (input.IndexOf(' ') == -1)
{
return input;
}
int mid = input.Length / 2;
int first_index_after = input.Substring(mid).IndexOf(' ') + mid;
int first_index_before = input.Substring(0, mid).LastIndexOf(' ');
if (first_index_after - mid < mid - first_index_before)
return input.Insert(first_index_after, "<BR />");
else
return input.Insert(first_index_before, "<BR />");
}
关于c# - 在字边界上将字符串分成2个字符串以最小化长度差异的绝佳方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3680346/