我不确定问这个问题的最好方法是什么,所以请多包涵。
我有一个旧平台,该平台具有2个100个varchar字段,用于保存定界的电子邮件地址。
我想拿一个List<String>
并将其分配到两个字段中,以便可以增加最大数量的项目。显然,电子邮件地址的长度是不同的,必须在条目之间添加定界符“; MAPI:”。顺序无关紧要,并且field2的唯一要求是field1至少具有单个条目。
当用户尝试向列表中添加新地址时,将调用此新方法,因此,完全有可能新项目无法以任何方式放置,在这种情况下,我只想告诉用户该字段可以不接受该长度的地址。
我尝试按长度排序,然后将项目添加到field1中直到填满,然后将其余部分添加到field2中,但这不是“最优”的,因为如果我为field2保留了一个或多个短条目,那么长条目可能会更好填写field1
答案 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:";
}