c# - 字符串连接/缩短算法

标签 c# string algorithm

我想在 Twitter 上为我们的客户发布服务器消息。
不幸的是,Twitter 只允许发布 140 个字符或更少。这是一种耻辱。

现在,我必须编写一个算法,将来自服务器的不同消息连接在一起,但将它们缩短到最多 140 个字符。

这很棘手。


代码

static string concatinateStringsWithLength(string[] strings, int length, string separator) {
    // This is the maximum number of chars for the strings
    // We have to subtract the separators
    int maxLengthOfAllStrings = length - ((strings.Length - 1) * separator.Length);

    // Here we save all shortenedStrings
    string[] cutStrings = new string[strings.Length];

    // This is the average length of all the strings
    int averageStringLenght = maxLengthOfAllStrings / strings.Length;

    // Now we check how many strings are longer than the average string
    int longerStrings = 0;
    foreach (string singleString in strings)
    {
        if (singleString.Length > averageStringLenght)
        {
            longerStrings++;
        }
    }

    // If a string is smaller than the average string, we can more characters to the longer strings
    int maxStringLength = averageStringLenght;
    foreach (string singleString in strings)
    {
        if (averageStringLenght > singleString.Length)
        {
            maxStringLength += (int)((averageStringLenght - singleString.Length) * (1.0 / longerStrings));
        }
    }

    // Finally we shorten the strings and save them to the array
    int i = 0;
    foreach (string singleString in strings)
    {
        string shortenedString = singleString;
        if (singleString.Length > maxStringLength)
        {
            shortenedString = singleString.Remove(maxStringLength);
        }

        cutStrings[i] = shortenedString;
        i++;
    }


    return String.Join(separator, cutStrings);
}

这个有问题

此算法有效,但不是很优化。 它使用的字符比实际少。

这个的主要问题是变量 longerStrings 是相对于 maxStringLength 的,并且是倒退的。

这意味着如果我更改 longerStringsmaxStringLength 就会更改,依此类推。 我必须创建一个 while 循环并执行此操作,直到没有任何更改为止,但我认为对于这种简单的情况没有必要这样做。

你能告诉我如何继续吗?

或者也许已经存在类似的东西?

谢谢!


编辑

我从服务器得到的消息是这样的:

  • 留言
    • 主题
    • 日期
    • 正文
  • 留言
    • 主题
    • 日期
    • 正文

等等。

我想要的是用分隔符连接字符串,在本例中是分号。
应该有一个最大长度。应先缩短长字符串。

例子

这是一个主题
这是本体,有点长……
25.02.2013

这是一个...
这是……
25.02.2013

我想你明白了 ;)

最佳答案

比你的慢五倍(在我们的简单示例中)但应该使用最大可用空间(不检查临界值):

static string Concatenate(string[] strings, int maxLength, string separator)
{
    var totalLength = strings.Sum(s => s.Length);
    var requiredLength = totalLength - (strings.Length - 1)*separator.Length;

    // Return if there is enough place.
    if (requiredLength <= maxLength)
        return String.Concat(strings.Take(strings.Length - 1).Select(s => s + separator).Concat(new[] {strings.Last()}));

    // The problem...
    var helpers = new ConcatenateInternal[strings.Length];
    for (var i = 0; i < helpers.Length; i++)
        helpers[i] = new ConcatenateInternal(strings[i].Length);

    var avaliableLength = maxLength - (strings.Length - 1)*separator.Length;
    var charsInserted = 0;
    var currentIndex = 0;

    while (charsInserted != avaliableLength)
    {
        for (var i = 0; i < strings.Length; i++)
        {
            if (charsInserted == avaliableLength)
                break;

            if (currentIndex >= strings[i].Length)
            {
                helpers[i].Finished = true;
                continue;
            }

            helpers[i].StringBuilder.Append(strings[i][currentIndex]);
            charsInserted++;
        }
        currentIndex++;
    }

    var unified = new StringBuilder(avaliableLength);
    for (var i = 0; i < strings.Length; i++)
    {
        if (!helpers[i].Finished)
        {
            unified.Append(helpers[i].StringBuilder.ToString(0, helpers[i].StringBuilder.Length - 3));
            unified.Append("...");
        }
        else
        {
            unified.Append(helpers[i].StringBuilder.ToString());
        }

        if (i < strings.Length - 1)
        {
            unified.Append(separator);
        }
    }

    return unified.ToString();
}

ConcatenateInternal:

class ConcatenateInternal
{
    public StringBuilder StringBuilder { get; private set; }
    public bool Finished { get; set; }

    public ConcatenateInternal(int capacity)
    {
        StringBuilder = new StringBuilder(capacity);
    }
}

关于c# - 字符串连接/缩短算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15066833/

相关文章:

java - 关于将 com 端口字符串转换为整数数组

algorithm - Neo4j 运行总计

algorithm - 哪种方法更好

java - 递归确定是否存在与给定 int 参数匹配的正 int 数组的子集和?

c# - 将 Enum 转换为 uint

c# - 在 XNA 中钳制 TextureAddressMode

c# - Visual Studio 程序集中缺少 Driveraccess.dll

c# - 如何使用 ServerManager 从类库中读取 IIS 站点,而不是 IIS Express,或者提升的进程如何处理类库?

Javascript\x 转义

c++ - 具有可变浮点精度的 CString.Format