是否有.Net集合维护订单并支持搜索匹配顺序的子集。
更新1 :我开发了一种适用于我的方法,并在下面回答了我自己的问题。但是,在我看到是否有人提出更好的方法之前,我不会将其标记为答案。
更新2 :等了几天;交通不多,没有建议,所以我继续前进 并将我的答案标记为我实施的答案。
用例:我有一个特定顺序的对象集合(例如字符串或整数),我需要确定另一个集合是否是超集的确切子集,即顺序问题,ABC与CBA不同
首先请注意我只使用SortedSet来说明我想要完成的内容。它没有做我需要做的事情。所以你可以把它想象成伪代码:
static void Main(string[] args)
{
var fleet = new List<string>();
fleet.Add("MotherShip");
var motherShip = new SortedSet<string>();
var motherArray = new string[7] { "A", "B", "C", "D", "E", "F", "G" };
for (int i = 0; i < motherArray.Length; i++)
{
motherShip.Add(motherArray[i]);
}
var shipOne = new SortedSet<string>();
var shipOneArray = new string[6] { "A", "B", "C", "D", "E", "F" };
for (int i = 0; i < shipOneArray.Length; i++)
{
shipOne.Add(shipOneArray[i]);
}
// shipOne should NOT be added
if (!shipOne.IsProperSubsetOf(motherShip)) fleet.Add("ShipOne");
var shipTwo = new SortedSet<string>();
var shipTwoArray = new string[6] { "B", "C", "D", "E", "F", "G" };
for (int i = 0; i < shipTwoArray.Length; i++)
{
shipTwo.Add(shipTwoArray[i]);
}
// shipTwo should NOT be added
if (!shipTwo.IsProperSubsetOf(motherShip)) fleet.Add("ShipTwo");
var shipThree = new SortedSet<string>();
var shipThreeArray = new string[5] { "E", "B", "C", "D", "A" };
for (int i = 0; i < shipThreeArray.Length; i++)
{
shipThree.Add(shipThreeArray[i]);
}
// shipThree SHOULD BE added
if (!shipThree.IsProperSubsetOf(motherShip)) fleet.Add("ShipThree");
Console.WriteLine("Fleet has {0} ships. Press any key to continue.", fleet.Count);
// Need it to be: Fleet has 2 ships.
Console.ReadLine();
}
答案 0 :(得分:0)
使用SortedSet并不是一个坏主意。
SortedSet SearchedArray = new Sorted { ... } // What you are looking for
SortedSet ExtractArray = MotherArray.GetViewBetween(SearchedArray.Min,SearchedArray.Max) ;
bool found=ExtractArray.Count==SearchedArray.Count;
for (int i=0;i<SearchedArray.count && found; i++) found=ExtractArray[i]==SearchedArray[i] ;
答案 1 :(得分:0)
好的,明白了。回顾一下用例:给定一个数组和一个较小数组的集合,创建一个数组集合,这些数组不是顺序重要的较大数组的子集,即{&#34; A&#34;,&#34; B&# 34;,&#34; C&#34; }!= {&#34; C&#34;,&#34; B&#34;,&#34; A&#34;并且数组值在超集和子集数组中都是连续的索引。
我想有很多方法可以实现这一点,我的方法可能不是最高效的,但我使用的阵列很小,所以这种方法可以完成工作。
这里是控制台应用程序的完整代码:
private static void Main(string[] args)
{
// This is the master list of IDs - no repeats. Hard coded here for the example.
var masterDictionary = new Dictionary<string, int>();
var masterArray = new string[15] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "O", "P" };
for (var i = 0; i < masterArray.Length; i++)
{
masterDictionary.Add(masterArray[i], i);
}
var uniqueArrays = GetUniqueArrays(masterDictionary);
Console.WriteLine("Unique array collection has {0} arrays. Press any key to continue.",
uniqueArrays.Count);
Console.ReadLine();
}
/// <summary>
/// Create a collection of arrays which are not subsets of a larger array where order matters,
/// i.e. { "A", "B", "C" } != { "C", "B", "A" } and the array values are in contiguous
/// indexes in both the superset and subset arrays.
/// </summary>
/// <returns></returns>
private static List<string[]> GetUniqueArrays(Dictionary<string, int> masterDictionary)
{
// This is the list of subsets I'll return
var uniqueArrays = new List<string[]>();
// This the superset of IDs, no repeats. We'll use an ordered dictionary because
// we need to find values in it by index.
var supersetDictionary = new OrderedDictionary();
var supersetArray = new string[7] { "A", "B", "C", "D", "E", "F", "G" };
for (var i = 0; i < supersetArray.Length; i++)
{
var value = 0;
masterDictionary.TryGetValue(supersetArray[i], out value);
supersetDictionary.Add(supersetArray[i], value);
}
// The superset array will always be in the list we return.
uniqueArrays.Add(supersetArray);
// Hard code some subsets and add them to a collection
var subsets = new List<string[]>();
// Is a subset
var subsetOne = new string[6] { "A", "B", "C", "D", "E", "F" };
subsets.Add(subsetOne);
// Is a subset
var subsetTwo = new string[6] { "B", "C", "D", "E", "F", "G" };
subsets.Add(subsetTwo);
// Is a subset
var subsetThree = new string[3] { "B", "C", "D" };
subsets.Add(subsetThree);
// Is NOT a subset
var subsetFour = new string[3] { "D", "C", "B" };
subsets.Add(subsetFour);
// Check if the subsetArray is a subset of the supersetArray. If it is not
// then add it to the list of unique subsets
foreach (var subset in subsets)
{
if (!CheckIsSubset(masterDictionary, supersetDictionary, subset))
uniqueArrays.Add(subset);
}
return uniqueArrays;
}
/// <summary>
/// Determine an array is a subset of a larger array where order matters,
/// i.e. { "A", "B", "C" } != { "C", "B", "A" } and the array values are in
/// contiguous indexes in both the superset and subset arrays.
/// </summary>
/// <param name="masterSet"></param>
/// <param name="superset"></param>
/// <param name="subset"></param>
/// <returns></returns>
private static bool CheckIsSubset(Dictionary<string, int> masterSet,
OrderedDictionary superset, string[] subset)
{
var supersetIndex = -1;
for (var i = 0; i < subset.Length - 1; i++)
{
// Get the masterDictionary value for the first ID in the subsetArray
var idValue = -1;
masterSet.TryGetValue(subset[i], out idValue);
if (idValue >= 0)
{
// Next determine if the first ID in the subset array is in the superset.
if (supersetIndex == -1)
{
for (var j = 0; j < superset.Count; j++)
{
// Get the ID at index j from the superset and compare it to subset ID
var supersetId = superset.Cast<DictionaryEntry>().ElementAt(j).Key.ToString();
var subsetId = subset[i];
if (subsetId == supersetId)
{
// This is the index in the superset from where we want to start our comparison
supersetIndex = j;
break;
}
}
// The first ID is not in the superset so we know the array we're testing is not
// a subset.
if (supersetIndex == -1)
{
return false;
}
}
}
else
{
var error = string.Format("The ID {0} is not in the master list.", idValue);
throw new Exception(error);
}
// We have a match. Next we want to step through the subset array.
// We next test for matches in the adjoining indexes
supersetIndex++;
if (superset.Count >= supersetIndex)
{
// Get the superset value at this index and compare it to the subset value
var supersetKey = superset.Cast<DictionaryEntry>().ElementAt(supersetIndex).Key.ToString();
var subsetValue = subset[i + 1];
if (subsetValue != supersetKey) return false;
}
else
{
// The supersetIndex is at or greater than the length of the superset array
// so our subset is unique.
return false;
}
}
// The array we're examining is a subset of the larger array
return true;
}