C# 数据设计模式的可比合并
在以下场景中,是否有比较数据的模式或最佳实践: 在我的例子中,每个字母代表一块数据XMLC# 数据设计模式的可比合并,c#,algorithm,design-patterns,C#,Algorithm,Design Patterns,在以下场景中,是否有比较数据的模式或最佳实践: 在我的例子中,每个字母代表一块数据XML a+b+c+d 这些被合并为一个并返回。如果我事先合并了a+b+c,那么识别这个“包”然后添加d将非常简单。但是如果我缓存了呢 a+c+d 然后对a+b+c+d的请求出现了,通过所有这些可能的组合来确定将b添加到a+c+d包中会得到期望的结果,最好的方法是什么 合并数据的顺序并不重要。虽然这可能不会对答案产生任何影响,但代码是用C#4.0编写的 编辑再举一个例子: 可能的元素:a、b、c、d、e、f 假
a+b+c+d
这些被合并为一个并返回。如果我事先合并了a+b+c,那么识别这个“包”然后添加d将非常简单。但是如果我缓存了呢
a+c+d
然后对a+b+c+d的请求出现了,通过所有这些可能的组合来确定将b添加到a+c+d包中会得到期望的结果,最好的方法是什么
合并数据的顺序并不重要。虽然这可能不会对答案产生任何影响,但代码是用C#4.0编写的
编辑再举一个例子:
可能的元素:a、b、c、d、e、f
假设我得到一个请求:a+c+d+e
意味着一个数组具有0=a,1=c,2=d,3=e
在我的“缓存”中,我有以下内容:c+d+e
已合并
然后,根据请求,我必须找到一种方法来执行以下操作:
if(cache.Contains(request.elements[0]+request.elements[1] etc...))
else(cache.Contains(request.elements[1] + request.elements[2] etc...))
它可能需要某种递归for循环,但在我的例子中,由于可能的元素最终位于2-5000范围内,因此它需要尽可能快且高效。根据这一点:
“然后,对a+b+c+d的请求出现了,通过所有这些可能的组合来确定将b添加到a+c+d包中会得到期望的结果,最好的方法是什么?”
我假设顺序无关紧要,因此如果您想要“abcd”,可以将“b”与“acd”合并。唯一重要的是包含哪些元素
现在,我不知道XML使用了什么,也不知道如何合并它,所以我用合并字符串编写了这篇文章,通过简单地连接字符串来合并。您必须重写Merge
方法来执行您想执行的任何操作(并将string
随处更改为您正在使用的任何操作)。我还使用了整数而不是a,b,c,因为我假设这些数字比字母表中的字母多得多
此外,例如,当您正在查找a+b+c+d+e+f+g
,并且缓存中的最佳匹配是c+e+g+f
,那么它还将在缓存中查找其余部分的最佳匹配,a+b+d
,以此类推,以进一步减少合并的数量。如果您不想这样做(如果使用xml,您无法将a+b
与c+d
合并到a+b+c+d
),您可以轻松地重写它,但它平均会进行更多的合并
这应该很快。查看main函数中的注释,了解它的作用
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication17
{
class CachedMerger
{
private Dictionary<HashSet<int>, string> _cache = new Dictionary<HashSet<int>, string>();
private Dictionary<int, string> _items = new Dictionary<int, string>();
public void AddItem(int index, string item)
{
_items[index] = item;
}
public void RemoveItem(int index)
{
_items.Remove(index);
}
private string Merge(string a, string b)
{
return a + b;
}
private string Merge(HashSet<int> list)
{
var sb = new StringBuilder();
foreach (var index in list)
{
if (!_items.ContainsKey(index))
return null;
else
sb.Append(_items[index]);
}
return sb.ToString();
}
public string Get(HashSet<int> query)
{
var bestMatchKey = BestMatchKey(query);
if (bestMatchKey == null)
{
var result = Merge(query);
if (result == null)
throw new Exception("Requested item not found in the item list.");
_cache[query] = result;
return result;
}
else
{
if (bestMatchKey.Count == query.Count)
return _cache[bestMatchKey];
var missing = new HashSet<int>();
foreach (var index in query)
if (!bestMatchKey.Contains(index))
missing.Add(index);
return Merge(_cache[bestMatchKey], Get(missing));
}
}
private HashSet<int> BestMatchKey(HashSet<int> set)
{
int bestCount = 0;
HashSet<int> bestKey = null;
foreach (var entry in _cache)
{
var key = entry.Key;
int count = 0;
bool fail = false;
foreach (var i in key)
{
if (set.Contains(i))
{
count++;
}
else
{
fail = true;
break;
}
}
if (!fail && count > bestCount)
{
bestKey = key;
bestCount = count;
}
}
return bestKey;
}
}
class Program
{
static void Main(string[] args)
{
var cm = new CachedMerger();
// Add all the base parts
cm.AddItem(0, "sjkdlajkld");
cm.AddItem(1, "dffdfdfdf");
cm.AddItem(2, "qwqwqw");
cm.AddItem(3, "yuyuyuyy");
cm.AddItem(4, "kjkjkjkjkj");
cm.AddItem(5, "oioyuyiyui");
// This will merge 0 + 1 + 3 + 4 since the cache is empty
Console.WriteLine(cm.Get(new HashSet<int> { 0, 1, 3, 4 }));
// This will merge 2 + 5 as there is no match in the cache
Console.WriteLine(cm.Get(new HashSet<int> { 2, 5 }));
// This will merge (2 + 5) from the cache with 3
Console.WriteLine(cm.Get(new HashSet<int> { 2, 3, 5 }));
// This will merge (0 + 1 + 3 + 4) from the cache with (2 + 5) from the cache
Console.WriteLine(cm.Get(new HashSet<int> { 0, 1, 2, 3, 4, 5 }));
Console.Read();
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
命名空间控制台应用程序17
{
类CachedMerger
{
私有字典_cache=新字典();
专用词典_items=新词典();
公共void附加项(整数索引,字符串项)
{
_项目[索引]=项目;
}
公共void removietem(int索引)
{
_项目。删除(索引);
}
私有字符串合并(字符串a、字符串b)
{
返回a+b;
}
私有字符串合并(哈希集列表)
{
var sb=新的StringBuilder();
foreach(列表中的var索引)
{
如果(!\u项包含索引))
返回null;
其他的
sb.附加(_项[索引]);
}
使某人返回字符串();
}
公共字符串获取(哈希集查询)
{
var bestMatchKey=bestMatchKey(查询);
if(bestMatchKey==null)
{
var结果=合并(查询);
如果(结果==null)
抛出新异常(“在项目列表中找不到请求的项目”);
_cache[query]=结果;
返回结果;
}
其他的
{
if(bestMatchKey.Count==query.Count)
返回_缓存[bestMatchKey];
var missing=新HashSet();
foreach(查询中的var索引)
如果(!bestMatchKey.Contains(索引))
缺少。添加(索引);
返回合并(_缓存[bestMatchKey],Get(缺少));
}
}
私有哈希集BestMatchKey(哈希集)
{
int-bestCount=0;
HashSet-bestKey=null;
foreach(缓存中的var条目)
{
var key=entry.key;
整数计数=0;
布尔失败=错误;
foreach(键中的var i)
{
如果(集合包含(i))
{
计数++;
}
其他的
{
失败=正确;
打破
}
}
如果(!fail&&count>bestCount)
{
最佳键=键;
最佳计数=计数;
}
}
返回最佳密钥;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var cm=新的CachedMerger();
//添加所有基础零件
cm.AddItem(0,“sjkdlajkld”);
cm.补充条款(1,“DFF”);
cm.补充条款(2,“qwqwqw”);
cm.增补项(3,“Yuyyy”);
cm.补充项(4,“KJKJ”);
cm.补充条款(5,“oioyuyiyui”);
//这将合并0+1+3+4,因为缓存为空
WriteLine(cm.Get(新HashSet{0,1,3,4}));
//这将合并2+5,因为缓存中没有匹配项
WriteLine(cm.Get(新HashSet{2,5}));
//这将合并(2)+