我需要为一个类创建一个高效的数据结构,该类存储大小从50,000到100,000的值的Collection。
class TypeData
{
public string Name { get; set; }
public Collection<double> Data{ get; set; }
}
现在,用户想要对此数据执行某些操作,然后操作将集合中的实际值替换为“0”。例如
Before operation:
3.4
5.6
66.71
101.44
3.567
345.09
After operation:
3.4
0.0
0.0
101.44
0.0
345.09
现在,用户想要恢复该操作。然后我必须删除所有0.0并且必须将原始值放在集合中的那些索引上。
问题1: 如何跟踪更改的索引?我是否需要保留包含所有已更改索引的另一个列表? 问题2: 如何改进这个类的数据结构,以便它可以容纳数千个实例,即
List<TypeData> dataList = new List<TypeData>();
//此列表的大小可以增长到5000
答案 0 :(得分:1)
如果您只需要撤消操作一次,那么保留Tim Schmelter的有效/实际值的解决方案是正确的。
如果您需要多个撤消,则必须实施历史记录。同样,您也可以提供 redo 的可能性。
通过一些假设撤消实际上非常容易。如果未更改撤消之间列表中的项目数,则可以将所有更改保存在历史记录(基本上是另一个列表)index
和value
中。撤消操作将遍历历史记录,获取索引并恢复该值。
如果项目数量将被更改,那么最简单的方法是通过制作副本来保存完整的州数据。但是,这是耗费内存的操作,但如果您考虑使用数据库或文件来保存这些状态,仍然可以实现。
其他解决方案是实施操作,您可以将其保存在历史记录中。您仍然需要保存状态,但它只是那个大小,需要操作(例如,如果删除项目,则不需要存储整个列表,只删除项目的索引和值)。在这种情况下,撤消将看起来像是从历史记录上一次操作中读取并向后执行(或者您可以从启动开始倒置历史记录,准备撤消,例如,在删除项目的情况下,您可以保存插入操作)。在列表操作的情况下,可能的操作的基本列表可以是:清除,插入,删除,更改值。
答案 1 :(得分:0)
问题1:如何跟踪已更改的索引?我需要保持一个 另一个包含所有已更改索引的列表?
我不会存储Collection<double>
而是Collection<CustomType>
存储值,临时状态和历史记录(如果有的话)。
例如:
public class TypeData
{
public string Name { get; set; }
public List<Data> Data { get; set; }
}
public class Data
{
public enum State
{
Unassigned,
Original,
Modified
}
private double _Value = 0.0d;
public double Value
{
get { return _Value; }
set
{
if (CurrentState == State.Unassigned)
CurrentState = State.Original;
else
CurrentState = State.Modified;
_Value = value;
_ValueHistory.Add(value);
if (_ValueHistory.Count > MaxHistoryCount)
ClearValueHistory();
}
}
private List<double> _ValueHistory = new List<double> { 0.0d };
private List<double> ValueHistory
{
get { return _ValueHistory; }
set { _ValueHistory = value; }
}
private int _MaxHistoryCount = int.MaxValue;
public int MaxHistoryCount
{
get { return _MaxHistoryCount; }
set { _MaxHistoryCount = value; }
}
public void ClearValueHistory()
{
if (_ValueHistory.Count > 1)
_ValueHistory.RemoveRange(0, _ValueHistory.Count - 1); // keep last
}
private State _CurrentState = State.Unassigned;
public State CurrentState
{
get { return _CurrentState; }
private set { _CurrentState = value; }
}
public void RevertOperation(int numRevertCount = 1)
{
int newRevisionIndex = _ValueHistory.Count - 1 - numRevertCount;
if (newRevisionIndex < 0) newRevisionIndex = 0;
double val = _ValueHistory[newRevisionIndex];
_ValueHistory.RemoveRange(newRevisionIndex + 1, _ValueHistory.Count - 1 - newRevisionIndex);
this._Value = val;
}
public override string ToString()
{
return Value.ToString();
}
}
以下是样本数据和示例性反向操作:
var listOfData = new List<TypeData>{
new TypeData {
Name = "TestData",
Data = new List<Data>
{
new Data { Value = 1.5 }, new Data { Value = 2.4 }, new Data { Value = 1.2 }, new Data(),
new Data { Value = 0.7 }, new Data { Value = -4.7 }, new Data { Value = 0.0 }, new Data { Value = 4711}
}
}
};
foreach (var td in listOfData)
{
foreach (var data in td.Data.Take(10))
{
data.Value = 4711.4711;
}
}
foreach (var td in listOfData)
{
foreach (var data in td.Data.Take(10))
{
data.RevertOperation();
}
}
问题2:如何改进这个类的数据结构 可容纳数千个实例,即
为什么需要改进它?我会保持原样。我怀疑它需要太多的记忆。否则你应该决定是否购买更多内存,或者你应该使用数据库。