C# 使用第X/Y页计算每行字符串的正确长度

C# 使用第X/Y页计算每行字符串的正确长度,c#,data-paging,C#,Data Paging,我被问到一个问题,现在我为自己不能得出准确/正确的结果而自责 假设我们有一个函数,可以将字符串拆分为多行,但在“拆分”到新行之前,每行必须有x个字符: private string[] GetPagedMessages(string input, int maxCharsPerLine) { ... } 对于每一行,我们需要在行“x/y”的末尾合并,基本上是1/4、2/4等。。。 现在,分页机制也必须是每行长度限制的一部分 我一直工作过度,思考过度,在事情上绊倒,这似乎很直截了当,但就我的一生

我被问到一个问题,现在我为自己不能得出准确/正确的结果而自责

假设我们有一个函数,可以将字符串拆分为多行,但在“拆分”到新行之前,每行必须有x个字符:

private string[] GetPagedMessages(string input, int maxCharsPerLine) { ... }
对于每一行,我们需要在行“x/y”的末尾合并,基本上是1/4、2/4等。。。 现在,分页机制也必须是每行长度限制的一部分

我一直工作过度,思考过度,在事情上绊倒,这似乎很直截了当,但就我的一生而言,我无法理解!我没有得到什么

我对什么感兴趣?计算和部分逻辑,但主要是根据每行的最大字符数(也需要包括x/y)计算分割输入所需的行数

请记住:x/y可以有多个一位数(即:不仅是1/4,还有10/17或99/200)

样本:

input=“这是一条很长的消息”

maxCharsPerLine=10

输出:

This i 1/4 // << Max 10 chars
s a lo 2/4 // << Max 10 chars
ng mes 3/4 // << Max 10 chars
sage 4/4 // << Max 10 chars

这种i 1/4/简单的方法是开始计算行长度减去“寻呼机”的大小,直到行计数的大小发生变化(“1/9”比“1/10”短,比“11/20”短,依此类推):


想法:首先,找出行数的位数:

(n = input.Length, maxCharsPerLine = 10)
if n <= 9*(10-4)  ==> 1 digit
if n <= 9*(10-5) + 90*(10-6)  ==> 2 digits
if n <= 9*(10-6) + 90*(10-7) + 900*(10-8)  ==> 3 digits
if n <= 9*(10-7) + 90*(10-8) + 900*(10-9) + 9000*(10-10)  ==> No solution
(n=input.Length,maxCharsPerLine=10)
如果n为1位
如果n为2位
如果n为3位
如果没有解决方案
然后,减去备用行数。解决方案:

    private static int GetNumberOfLines(string input, int maxCharsPerLine)
    {
        int n = input.Length;
        int x = maxCharsPerLine;

        for (int i = 4; i < x; i++)
        {
            int j, sum = 0, d = 9, numberOfLines = 0;

            for (j = i; j <= i + i - 4; j++)
            {
                if (x - j <= 0)
                    return -1;   // No solution

                sum += d * (x - j);
                numberOfLines += d;
                d *= 10;
            }
            if (n <= sum)
                return numberOfLines - (sum - n) / (x - j + 1);
        }
        return -2;   // Invalid
    }
private static int GetNumberOfLines(字符串输入,int-maxCharsPerLine)
{
int n=输入长度;
int x=maxCharsPerLine;
对于(int i=4;i对于(j=i;j如果忽略x/y部分的可能长度,我想你必须首先计算出你有多少行。基于此,你可以确定x/y部分的长度,然后再次检查这是否会改变总行数。重复,直到你有一个稳定的结果。你使用固定宽度字体吗?如果不是,计算字符数rs不会表示任何字符串的实际显示长度。我不太理解它。考虑到
input=“这是一条长消息”,maxCharsPerLine=10应拆分为4行
和另一行
input=“123456”,maxCharsPerLine=6
为什么后者应该分为3行而不仅仅是1行?这3行是从哪里来的?它可以分为6到1行之间的任何一行,而且maxCharsPerLine@Fabjan可以考虑SMS消息。您希望在其限制范围内最大限度地填充消息,以便发送尽可能少的消息,但要附加一个pag呃,让接收者知道还有更多的信息。因此,您的6个字符的信息,限制为6个字符,发送方式为“12 1/3”、“34 2/3”、“56 3/3”。是的,我收到的短信字面上是“。(3/3)”,所以这并不像看上去那么简单。@Codemaster感谢您的解释。我忽略了一点,分页也是消息的一部分,6个字符的限制也包括在内,而像“1234561/1”这样的smth实际上会使其长9个字符。当整个输入进入一行时,它不会打印“1/1”最后,因此不能正确拆分。例如:input=“123456”,maxCharsPerLine=6应该分为3行,而不是一行。此外,当不存在解决方案时,它会进入一个无限循环。第一种情况在代码中进行注释,后一种情况我在发布后想到,但还没有时间修复。我喜欢数学,但我发现代码不可读。同意。代码不可读且未注释。我为什么要从4?为什么d=9开始?为什么要乘以10?我不明白。你是对的。我专注于算法而不是可读性。主要解释在我的第一段。看第一行:
如果n 1位
第一行末尾有额外的4个字符:“x/y”。这就是为什么“i”以4开头。“d”以9开头表示前9行1-9。然后*10表示90行10-99。然后*10表示900行100-999,等等。此外,“知道行数后,很容易拆分为行。”-再次拆分输入时,您必须重复部分计算,必须再次跟踪行长度和寻呼机大小。@CodeCaster不一定。查看“我的编辑”了解用法。
This  1/20
is a  2/20
long  3/20
strin 4/20
g tha 5/20
t wil 6/20
l spa 7/20
n mor 8/20
e tha 9/20
n te 10/20
n li 11/20
nes  12/20
beca 13/20
use  14/20
of i 15/20
ts e 16/20
norm 17/20
ous  18/20
leng 19/20
th 20/20
(n = input.Length, maxCharsPerLine = 10)
if n <= 9*(10-4)  ==> 1 digit
if n <= 9*(10-5) + 90*(10-6)  ==> 2 digits
if n <= 9*(10-6) + 90*(10-7) + 900*(10-8)  ==> 3 digits
if n <= 9*(10-7) + 90*(10-8) + 900*(10-9) + 9000*(10-10)  ==> No solution
    private static int GetNumberOfLines(string input, int maxCharsPerLine)
    {
        int n = input.Length;
        int x = maxCharsPerLine;

        for (int i = 4; i < x; i++)
        {
            int j, sum = 0, d = 9, numberOfLines = 0;

            for (j = i; j <= i + i - 4; j++)
            {
                if (x - j <= 0)
                    return -1;   // No solution

                sum += d * (x - j);
                numberOfLines += d;
                d *= 10;
            }
            if (n <= sum)
                return numberOfLines - (sum - n) / (x - j + 1);
        }
        return -2;   // Invalid
    }
    private static string[] GetPagedMessages(string input, int maxCharsPerLine)
    {
        int numberOfLines = GetNumberOfLines(input, maxCharsPerLine);
        if (numberOfLines < 0)
            return null;

        string[] result = new string[numberOfLines];

        int spaceLeftForLine = maxCharsPerLine - numberOfLines.ToString().Length - 2;  // Remove the chars of " x/y" except the incremental 'x'
        int inputPosition = 0;
        for (int line = 1; line < numberOfLines; line++)
        {
            int charsInLine = spaceLeftForLine - line.ToString().Length;
            result[line - 1] = input.Substring(inputPosition, charsInLine) + $" {line}/{numberOfLines}";
            inputPosition += charsInLine;
        }
        result[numberOfLines-1] = input.Substring(inputPosition) + $" {numberOfLines}/{numberOfLines}";
        return result;
    }