< Buff行情>
例如,从步骤2开始:
2013年1234
bcad密件抄送
< /块引用>
因为您只能添加和删除--不能插入元素或添加/删除范围--我认为您不能保留任何顺序子段
other than
in order segment from 0的现有顺序。这就是为什么在步骤4中删除所有其他元素的原因。因为您不必在删除后立即添加这些元素(基于您的示例),所以我假设可以将它们存储在某个地方。那么,为什么不将它们存储在可排序列表中,并根据分配的“订单号”进行排序以确定添加的顺序呢?
除非我误解了您的问题,否则您对添加/删除操作的顺序感兴趣,因此您不关心实际转换列表(因为您已经转换了列表);您需要创建转换列表的步骤。因此,每次在算法中添加或删除时,都会将“operation”添加到操作(例如
operations.add(“remove(a)”)
)的列表(队列)中。然后算法返回此操作列表。
我用C编写了一个可能的实现。我做了一点测试(下面的屏幕截图),它似乎起作用了。然而,它也可能不是有人可以编写的最佳实现。
公共静态IEnumerable<string>DetermineTransformOrder<t>。(
IEnumerable<t>原始,需要IEnumerable<t>)
{
//立即处理简单的案例
if(原始序列相等(所需)
{
返回新列表<string>();
}
list<keyValuePair<int,t>>workingOriginal=新列表<keyValuePair<int,t>>();
list<t>workingDesired=desired.tolist();
list<string>operations=new list<string>();//使用队列也可以
//加载WorkingOriginal
foreach(原始的t元素)
workingOriginal.add(new keyValuePair<int,t>(workingDesired.indexof(element),element));
//1。从原始列表中删除不在所需列表中的所有元素;
//将每个移除操作添加到操作列表中。
var tempworking=新列表<keyValuePair<int,t>>(WorkingOriginal);
foreach(模板中的var元素)
{
如果(!)工作所需。包含(element.value)
{
WorkingOriginal.Remove(元素);
operations.add(“remove(+element.value.toString()+”);
}
}
/ / 2。向缺少的工作添加任何元素;
//将每个添加操作添加到操作列表中。
tempworking=新列表<keyValuePair<int,t>>(WorkingOriginal);
foreach(所需工作中的t元素)
{
如果(!WorkingOriginal.exists(x=>x.Value.Equals(element)))
{
workingOriginal.add(new keyValuePair<int,t>(workingDesired.indexof(element),element));
operations.add(“添加(+element+”);
}
}
/ / 3。为原始列表的每个元素分配一个“订单号”
//所需列表中的模拟位置。
//注意:已经完成了。本来可以在这里做的,但是
//keyValuePair.key是只读的。
/ / 4。找到第一个元素(0在原始的[1]处),然后
//按顺序排列的最后一个元素(原始[2]处为1)。
int indexoffirstelement=workingoriginal.findindex(x=>x.key==0);
int indexoflastelement=indexoffirstelement;
//移到最后一个有序元素的索引
对于(int i=indexoflastelement+1;
I<WorkingOriginal.Count&
workingoriginal[i-1].key+1==workingoriginal[i].key;
i++,indexoflastelement++);
//5。移除此范围之外位置的所有元素,并将它们放入一些
//其他临时列表;将每个移除操作添加到操作列表中。
list<keyValuePair<int,t>>temporary=新列表<keyValuePair<int,t>>();
var inorderences=WorkingOriginal.getRange(
耐火指数,
lastelement的indexoffirstelement+1);
var outoforderements=新列表<keyValuePair<int,t>。(
除(无序)外,工作原始;
foreach(无序中的var元素)
{
WorkingOriginal.Remove(元素);
临时添加(元素);
operations.add(“remove(+element.value.toString()+”);
}
//6。根据“订单号”对临时列表进行排序。
temporary.sort((x,y)=>返回x.key.compareto(y.key););
/ / 7。从临时列表中按顺序添加元素;
//将每个添加操作添加到操作列表中。
foreach(临时变量元素)
{
workingoriginal.add(元素);
operations.add(“add(+element.value.toString()+”);
}
/ / 8。验证此新转换的列表是否与所需的列表匹配。
var newlytransformed=workingoriginal.convertall<t>(x=>返回x.value;);
如果(!)newlyTransformed.SequenceEqual(所需)
{
//这不应该发生
引发新的StackOverflowException(“失败”);
}
/ / 9。返回操作列表。
返回操作;
}
< /代码>
从不在所需列表中的原始列表中添加;将每个移除操作添加到操作列表中。
Add
缺少的任何工作元素;将每个添加操作添加到操作列表中。
为原始列表的每个元素分配一个“订单号”,即其模拟在所需列表中的位置。(请参见下面的代码段。)
查找第一个元素(0在原始1)最后一个元素按顺序排列(1个在原始2)
删除
位于该范围之外位置的所有元素,并将它们放入其他临时列表中;将每个移除操作添加到操作列表中。
根据“订单号”对临时列表进行排序。
添加
从临时列表中按顺序排列的元素;将每个添加操作添加到操作列表中。
验证此新转换的列表是否与所需的列表匹配。
返回操作列表。
例如,从步骤2开始:
2013 1234
ABCD BCAD
因为您只能添加和删除——不能插入元素或添加/删除范围——我认为您不能保持任何按顺序子段的现有顺序。以外从0开始的顺序段。这就是为什么在步骤4中删除所有其他元素的原因。因为您不必在删除后立即添加这些元素(基于您的示例),所以我假设可以将它们存储在某个地方。那么,为什么不将它们存储在可排序列表中,并根据分配的“订单号”进行排序以确定添加的顺序呢?
除非我误解了您的问题,否则您对添加/删除操作的顺序感兴趣,因此您不关心实际转换列表(因为您已经转换了列表);您需要创建转换列表的步骤。因此,每次在算法中添加或删除时,都要将“操作”添加到操作列表(队列)中(例如operations.Add("remove(a)")
)然后,该算法返回该操作列表。
我用C编写了一个可能的实现。我做了一点测试(下面的屏幕截图),它似乎起作用了。然而,它也可能不是有人可以编写的最佳实现。
public static IEnumerable<string> DetermineTransformOrder<T>(
IEnumerable<T> original, IEnumerable<T> desired)
{
// handle the easy case immediately
if (original.SequenceEqual(desired))
{
return new List<string>();
}
List<KeyValuePair<int,T>> workingOriginal = new List<KeyValuePair<int,T>>();
List<T> workingDesired = desired.ToList();
List<string> operations = new List<string>(); //using Queue<> is ok too
// load workingOriginal
foreach(T element in original)
workingOriginal.Add(new KeyValuePair<int, T>(workingDesired.IndexOf(element), element));
//1. Remove all elements from the original that are not in the desired list;
// add each remove operation to the list of operations.
var tempWorking = new List<KeyValuePair<int,T>>(workingOriginal);
foreach (var element in tempWorking)
{
if (!workingDesired.Contains(element.Value))
{
workingOriginal.Remove(element);
operations.Add("remove(" + element.Value.ToString() + ")");
}
}
//2. Add any elements to working that are missing;
// add each add operation to the list of operations.
tempWorking = new List<KeyValuePair<int,T>>(workingOriginal);
foreach(T element in workingDesired)
{
if(!workingOriginal.Exists(x=>x.Value.Equals(element)))
{
workingOriginal.Add(new KeyValuePair<int, T>(workingDesired.IndexOf(element), element));
operations.Add("add("+element+")");
}
}
//3. Assign to each element of the original list a "order number"
// which is the position of its analog in the desired list.
// note: already done above. would have done it here, but
// KeyValuePair.Key is read-only.
//4. Find the first element (0 at original[1]) and the
// last element in order from there (1 at original[2]).
int indexOfFirstElement = workingOriginal.FindIndex(x => x.Key == 0);
int indexOfLastElement = indexOfFirstElement;
// move to index of last in-order element
for (int i = indexOfLastElement + 1;
i < workingOriginal.Count &&
workingOriginal[i - 1].Key + 1 == workingOriginal[i].Key;
i++, indexOfLastElement++) ;
//5. Remove all elements at positions outside of this range and put them in some
// other temporary list; add each remove operation to the list of operations.
List<KeyValuePair<int, T>> temporary = new List<KeyValuePair<int, T>>();
var inOrderElements = workingOriginal.GetRange(
indexOfFirstElement,
indexOfLastElement - indexOfFirstElement + 1);
var outOfOrderElements = new List<KeyValuePair<int, T>>(
workingOriginal.Except(inOrderElements));
foreach (var element in outOfOrderElements)
{
workingOriginal.Remove(element);
temporary.Add(element);
operations.Add("remove(" + element.Value.ToString() + ")");
}
//6. Sort the temporary list based on the "order number".
temporary.Sort((x, y) => { return x.Key.CompareTo(y.Key); });
//7. Add the elements in order from the temporary list;
// add each add operation to the list of operations.
foreach (var element in temporary)
{
workingOriginal.Add(element);
operations.Add("add(" + element.Value.ToString() + ")");
}
//8. Verify that this newly transformed list matches the desired list.
var newlyTransformed = workingOriginal.ConvertAll<T>(x => { return x.Value; });
if (!newlyTransformed.SequenceEqual(desired))
{
// this should never happen
throw new StackOverflowException("FAILED");
}
//9. Return the list of operations.
return operations;
}