C# 按Linq对字符串排序

C# 按Linq对字符串排序,c#,string,linq,C#,String,Linq,假设我有以下输入: string input = "123456789"; 并期望得到以下输出: string output = "741852963"; 逻辑是一个正方形,需要向右旋转90度,但没有换行符 // squares //INPUT OUTPUT // 123 ══╗ 741 // 456 V 852 // 789 963 宽度应该是动态的,并且始终保持不变 int width = (int)Math.Sqrt(input.Length);

假设我有以下输入:

string input = "123456789";
并期望得到以下输出:

string output = "741852963";
逻辑是一个正方形,需要向右旋转90度,但没有换行符

//  squares
//INPUT     OUTPUT
// 123  ══╗  741
// 456    V  852
// 789       963
宽度应该是动态的,并且始终保持不变

int width = (int)Math.Sqrt(input.Length);

有没有一种简单的方法可以解决这个问题?

我个人更喜欢
for
循环,但也有
Linq
解决方案

印刷品

C840D951EA62FB73
那么:

void Main()
{
    var input = "123456789";
    var size = (int)Math.Sqrt(input.Length);
    var table = new char[size, size];

    for (var i = 0; i < input.Length; ++i)
    {
        table[i / size, i % size] = input[i];
    }

    var result = new StringBuilder();

    for (var i = 0; i < size; ++i)
    {
        for (var j = size - 1; j >= 0; --j)
        {
            result.Append(table[j, i]);
        }
    }

    Console.WriteLine(result.ToString());
}
void Main()
{
var input=“123456789”;
var size=(int)Math.Sqrt(input.Length);
var table=新字符[大小,大小];
对于(变量i=0;i=0;--j)
{
结果.追加(表[j,i]);
}
}
Console.WriteLine(result.ToString());
}

好吧,我玩得很开心:

const string input = "123456789";
string toFill = "";
int offset = 0;
int upTo = (int) Math.Sqrt(input.Length);
while (offset < upTo )
{
    string temp = "";

    for (int i = 0; i < input.Length; i = i + upTo)
    {
        temp += input[i + offset];
    }
    offset++;
    toFill += new string(temp.Reverse().ToArray()); ;
}
const string input=“123456789”;
字符串toFill=“”;
整数偏移=0;
int upTo=(int)Math.Sqrt(input.Length);
while(偏移量<最多)
{
字符串temp=“”;
for(int i=0;i
它可以工作,但不使用linq:(

提供的排序是完美的,没有什么可添加的

但是有一个有趣的说法是“这更像是一个映射而不是一种排序”,所以让我们来试试

我们这里的是

int length = input.Length;
int width = (int)Math.Sqrt(length);
int height = (length + width - 1) / width;
对于范围
[0,length-1]
中的每个索引
i1
,我们定义了到同一范围内另一个索引
i2
的转换,如下所示

int x1 = i1 % width;
int y1 = i1 / width;
int x2 = height - 1 - y1;
int y2 = x1;
int i2 = y2 * height + x2;
现在让我们对上面的内容进行逆变换

int x2 = i2 % height;
int y2 = i2 / height;
int x1 = y2;
int y1 = height - 1 - x2;
int i1 = width * y1 + x1;
在替换之后变成

int i1 = width * (height - 1 - i2 % height) + i2 / height;
考虑到所有这些,以下是“映射”Linq解决方案:

string input = "123456789";
int length = input.Length;
int width = (int)Math.Sqrt(length);
int height = (length + width - 1) / width;
var output = new string(
    Enumerable.Range(0, length)
    .Select(i => input[width * (height - 1 - i % height) + i / height])
    .ToArray());
当然,LINQ在这里毫无意义,我们可以避免引入闭包,并使用相同或更少的“正常”代码行来实现闭包,而且还可以像上面那样选择使用逆变换

var result = new char[length];
for (int i = 0; i < result.Length; i++)
    result[i] = input[width * (height - 1 - i % height) + i / height];
var output = new string(result);
var result=新字符[长度];
for(int i=0;i
或直接转换(替换和简化后)

for(int i=0;i
Define“easy”。使用for循环将非常“容易”。我假设您正在寻找一个“优雅”(而不是“容易”)的Linq解决方案……我花了很长时间才理解它。很有趣。但Linq并没有真正的帮助。太好了!左转将是
。OrderByDescending(a=>a.Col)。然后by(a=>a.Row)
@Byyo,
.OrderByDescending(a=>a.Col)
就足够了。默认情况下,行将按升序排列:)
var result = new char[length];
for (int i = 0; i < result.Length; i++)
    result[i] = input[width * (height - 1 - i % height) + i / height];
var output = new string(result);
for (int i = 0; i < result.Length; i++)
    result[height * (i % width + 1) - (i / width + 1)] = input[i];