Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据设计模式的可比合并_C#_Algorithm_Design Patterns - Fatal编程技术网

C# 数据设计模式的可比合并

C# 数据设计模式的可比合并,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 假

在以下场景中,是否有比较数据的模式或最佳实践:

在我的例子中,每个字母代表一块数据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+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)+