给定一个字符串列表,分配给两个100个字符的字段

时间:2018-07-13 13:22:05

标签: c# algorithm

我不确定问这个问题的最好方法是什么,所以请多包涵。

我有一个旧平台,该平台具有2个100个varchar字段,用于保存定界的电子邮件地址。

我想拿一个List<String>并将其分配到两个字段中,以便可以增加最大数量的项目。显然,电子邮件地址的长度是不同的,必须在条目之间添加定界符“; MAPI:”。顺序无关紧要,并且field2的唯一要求是field1至少具有单个条目。

当用户尝试向列表中添加新地址时,将调用此新方法,因此,完全有可能新项目无法以任何方式放置,在这种情况下,我只想告诉用户该字段可以不接受该长度的地址。

我尝试按长度排序,然后将项目添加到field1中直到填满,然后将其余部分添加到field2中,但这不是“最优”的,因为如果我为field2保留了一个或多个短条目,那么长条目可能会更好填写field1

3 个答案:

答案 0 :(得分:2)

按长度排序,从大到大,将它们添加到A和B之间的列表中。

答案 1 :(得分:2)

这是一维NP问题,难于解决NP问题,因此您只能通过有效时间(例如,使用动态编程)来优化解决方案。 https://en.wikipedia.org/wiki/Knapsack_problem

答案 2 :(得分:1)

如果有帮助,我实现了Isitar的算法。

public static void Main()
{
    string form1 = String.Empty, form2 = String.Empty;
    var emails = new List<string> { "biglongemail@email.com", "short@email.com", "mediumsized@email.com"};

    FillForms(ref form1, ref form2, emails);

    Console.WriteLine("form1: " + form1 + "\nform2: " + form2);
}

private static bool HasRoom(string form, string email) {
    return (form + email).Count() <= 100;
}   

private static void FillForms(ref string form1, ref string form2, List<string> inputEmails)
{
    List<string> emails = inputEmails.OrderBy(email => email.Count()).ToList();

    string delim = String.Empty;
    bool full = false;
    int i = 0;
    while (i < emails.Count && !full)
    {
        full = true;

        if (HasRoom(form1, emails[i]))
        {
            form1 += delim + emails[i];
            full = false;
            i++;
            if (i >= emails.Count()) break;
        }


        if (HasRoom(form2, emails[i]))
        {
            form2 += delim + emails[i];             
            full = false;
            i++;
        }   


        delim = ";MAPI:";
    }

Dotnetfiddle