C# 将多行字符串旋转90度-行变为列
假设我有一根像C# 将多行字符串旋转90度-行变为列,c#,string,unicode,C#,String,Unicode,假设我有一根像 Line 1 Line 2 我想把这根绳子顺时针转90度,这样它就可以 LL ii nn ee 12 旋转只需要执行一次,这样实际上就是“将行变成列”。执行两次应该会得到原始字符串。(如果它确实旋转了90度,则必须重复四次才能返回原始字符串。)它将需要添加前导空格(即原始字符串中较短行之前的列)。此方法为您提供了一个使其可见的选项(fillChar-作为常量提供的多个选项。) 另外,如果您想要旋转90度,那么附加的ReverseLineOrder方法会反转线条顺序,从而反转
Line 1
Line 2
我想把这根绳子顺时针转90度,这样它就可以
LL
ii
nn
ee
12
旋转只需要执行一次,这样实际上就是“将行变成列”。执行两次应该会得到原始字符串。(如果它确实旋转了90度,则必须重复四次才能返回原始字符串。)它将需要添加前导空格(即原始字符串中较短行之前的列)。此方法为您提供了一个使其可见的选项(
fillChar
-作为常量提供的多个选项。)
另外,如果您想要旋转90度,那么附加的ReverseLineOrder
方法会反转线条顺序,从而反转所有线条
using System;
using System.Globalization;
using System.Text;
namespace Library.Text
{
public static class TextRotate
{
public const char Space = ' ';
public const char MiddleDot = '\u00b7';
public const char Circle = '\u25cb';
public const char BlackSquare = '\u25a0';
public const char NoBreakSpace = '\u00a0';
public static string LinesToColumns(string s, char fillChar = Space)
{
// A line feed at the end of the text is not seen as content.
// However, if the text ends in a line feed, we make sure the output ends in one, too.
bool endsWithNewline = s.EndsWith(Environment.NewLine);
string[] linesIn = s.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
int[][] textElements = new int[linesIn.Length][];
int longestLine_chars = 0;
int longestLine_elems = 0; // The longest line, in text elements
for (int l = 0; l < linesIn.Length; l++)
{
string line = linesIn[l];
if (line.Length > longestLine_chars)
{
longestLine_chars = line.Length;
}
var elems = StringInfo.ParseCombiningCharacters(line); // Gets indices of surrogate pairs, combining characters etc.
if (elems.Length > longestLine_elems)
{
longestLine_elems = elems.Length;
}
textElements[l] = elems;
}
// Go through columns (columns in the input text, and columns in terms of text elements - NOT chars)
string[] columns = new string[longestLine_elems];
var builder = new StringBuilder(longestLine_chars * linesIn.Length + Math.Max(longestLine_chars, linesIn.Length) * Environment.NewLine.Length);
for (int column = 0; column < longestLine_elems; column++)
{
builder.Clear();
System.Diagnostics.Debug.Assert(builder.Length == 0);
int cutoff = 0;
for (int l = 0; l < linesIn.Length; l++)
{
// Is the line long enough to reach to this column?
int[] lineTextElements = textElements[l];
int textElementsInLine = lineTextElements.Length;
if (textElementsInLine > column)
{
int firstCharIndex = lineTextElements[column];
if (column + 1 < textElementsInLine)
{
int nrOfChars = lineTextElements[column + 1] - firstCharIndex;
builder.Append(linesIn[l], firstCharIndex, nrOfChars);
}
else
{
builder.Append(linesIn[l], firstCharIndex, linesIn[l].Length - firstCharIndex);
}
cutoff = builder.Length;
}
else
{
builder.Append(fillChar);
}
}
// Trim the fill char off line endings (for when rotating back)
while (cutoff > 0 && builder[cutoff - 1] == fillChar)
{
cutoff--;
}
// Resulting column
columns[column] = builder.ToString(0, cutoff);
}
// Turn the columns into lines
builder.Clear();
foreach (var c in columns)
{
builder.AppendLine(c);
}
if (!endsWithNewline && builder.Length > 0)
{
builder.Length -= Environment.NewLine.Length;
}
return builder.ToString();
}
public static string ReverseLineOrder(string s)
{
// A line feed at the end of the text is not seen as content.
// However, if the text ends in a line feed, we make sure the output ends in one, too.
bool endsWithNewline = s.EndsWith(Environment.NewLine);
string[] linesIn = s.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
var builder = new StringBuilder(s.Length);
for (int l = linesIn.Length - (endsWithNewline ? 2 : 1); l >= 0; l--)
{
builder.AppendLine(linesIn[l]);
}
if (!endsWithNewline && builder.Length > 0)
{
builder.Length -= Environment.NewLine.Length;
}
return builder.ToString();
}
}
}
使用系统;
利用制度全球化;
使用系统文本;
名称空间库.Text
{
公共静态类TextRotate
{
public const char Space='';
public const char MiddleDot='\u00b7';
public const char Circle='\u25cb';
公共常量char BlackSquare='\u25a0';
public const char NoBreakSpace='\u00a0';
公共静态字符串LinesToColumns(字符串s,char fillChar=Space)
{
//文本末尾的换行不视为内容。
//但是,如果文本以换行符结尾,我们也会确保输出以换行符结尾。
bool endsWithNewline=s.EndsWith(Environment.NewLine);
string[]linesIn=s.Split(新字符串[]{Environment.NewLine},StringSplitOptions.None);
int[][]textElements=新的int[linesIn.Length][];
int longestLine_chars=0;
int longestLine_elems=0;//文本元素中最长的一行
对于(int l=0;l最长直线长度)
{
longestLine_chars=直线长度;
}
var elems=StringInfo.ParseCombiningCharacters(行);//获取代理项对、组合字符等的索引。
如果(元素长度>最长线元素)
{
longestLine_elems=元素长度;
}
textElements[l]=元素;
}
//浏览列(输入文本中的列,以及文本元素方面的列-而不是字符)
string[]columns=新字符串[longestLine_elems];
var builder=new StringBuilder(longestLine\u chars*linesIn.Length+Math.Max(longestLine\u chars,linesIn.Length)*Environment.NewLine.Length);
for(int column=0;column列)
{
int firstCharIndex=lineTextElements[列];
if(第+1列0&&builder[cutoff-1]==fillChar)
{
截止--;
}
//结果列
columns[column]=builder.ToString(0,截断);
}
//将列转换为行
builder.Clear();
foreach(列中的var c)
{
建筑商。附录(c);
}
如果(!endsWithNewline&&builder.Length>0)
{
builder.Length-=Environment.NewLine.Length;
}
返回builder.ToString();
}
公共静态字符串反转顺序(字符串s)
{
//文本末尾的换行不视为内容。
//但是,如果文本以换行符结尾,我们也会确保输出以换行符结尾。
bool endsWithNewline=s.EndsWith(Environment.NewLine);
string[]linesIn=s.Split(新字符串[]{Environment.NewLine},StringSplitOptions.None);
var builder=新的StringBuilder(s.Length);
对于(int l=linesIn.Length-(endsWithNewline?2:1);l>=0;l--)
{
建筑商。附录(第[l]行);
}
如果(!endsWithNewline&&builder.Length>0)
{
builder.Length-=Environment.NewLine.Length;
}
返回builder.ToString();
}
}
}
注意,这几乎假设字符串的长度都相同。调整它以使用最长的字符串长度是很简单的
使用
StringBuilder
会更有效率,但是,除非您使用大量非常长的字符串,否则您永远不会看到性能上的差异。这是一个有趣的尝试和编写过程。我没有把时间花在验证和定性上
using System;
using System.Collections;
using System.Collections.Generic;
namespace rotateString
{
class Program
{
static void Main(string[] args)
{
var strings = new string[] { "Line 1", "Line 2" };
var lines = new List<string>();
var done = false;
var j = 0;
do
{
var line = "";
for (var i = 0; i < strings.Length; ++i)
{
var s = strings[i];
if (j >= s.Length)
{
done = true;
break;
}
line += s[j];
}
lines.Add(line);
++j;
} while (!done);
for(int i=0; i < lines.Count; ++i)
{
Console.WriteLine(string.Format("{0} : '{1}'", i, lines[i]));
}
}
}
}
0 : 'LL'
1 : 'ii'
2 : 'nn'
3 : 'ee'
4 : ' '
5 : '12'
6 : ''