从数组中删除精确的子数组值
本文关键字:数组 删除 | 更新日期: 2023-09-27 18:15:08
我在数组方面遇到了问题,主要是我在寻找一种从数组中删除子数组的方法,但要使用精确的序列。例如:
int[] greaterArray = {8, 3, 4, 5, 9, 12, 6, 3, 5}
int[] lesserArray = {3, 4, 5}
结果是:
int[] resultArray = {8, 9, 12, 6, 3, 5}
因此,正如您所看到的,它将只删除{3,4,5}作为一个序列,而不是一个单独的值,值3,5保留在一个更大的数组中。
我已经完成了到字符串的转换和剪切子字符串,但可能有一种更简单、更优雅的方法。
private static int[] RemoveSubArray()
{
int[] greaterArray = {8, 3, 4, 5, 9, 12, 6, 3, 5, 3, 4, 5};
int[] lesserArray = {3,4,5};
if (lesserArray == null || lesserArray.Length == 0)
{
return greaterArray;
}
int[] allIndex = greaterArray.Select((b,i) => b == lesserArray[0] ? i : -1).Where(i => i != -1).ToArray();
for (int index = 0; index < allIndex.Length; index++)
{
int count = 0;
for (int x = 1; x < allIndex.Length; x++)
{
if (greaterArray[allIndex[index] + x] == lesserArray[x])
{
count++;
}
}
if (count == allIndex.Length - 1)
{
for (int inner = 0; inner < allIndex.Length; inner++)
{
greaterArray[allIndex[index] + inner] = 0;
}
}
}
return greaterArray = greaterArray.Where(i => i != 0).ToArray();
}
首先存储greaterArray具有lesserArray的第一个元素的所有不精确。然后检查next和next-to-next,直到allIndex的长度。如果所有这些值顺序地等于lesserArray值,那么我们将把greaterArray中这些索引的值设置为0。最后,我们将从greaterArray中删除所有的0。
static int[] Run(int[] greaterArray, int[] lesserArray)
{
int[] result = new int[greaterArray.Length];
int k = 0;
for (int i = 0; i < greaterArray.Length; )
{
if (greaterArray.Skip(i).Take(lesserArray.Length).SequenceEqual(lesserArray))
{
i += lesserArray.Length;
}
else
{
result[k] = greaterArray[i];
i++;
k++;
}
}
return result;
}
Nadeem上面的回答只删除了一次模式。尽管这给出了正确的答案,但索引逻辑可以被更优雅的东西取代。
这正是您想要的,并且适用于所有数据类型数组。
/// <summary>
/// Removes all occurrences of the specified collection from the referenced array.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array"></param>
/// <param name="collection"></param>
public static void RemoveAll<T>(ref T[] array, T[] collection)
{
T[] result = { };
for (int i = 0; i < array.Length; i++)
{
T[] chunk = new T[collection.Length];
for (int j = 0; j < chunk.Length; j++)
if (!((i + j) >= array.Length))
chunk[j] = array[i + j];
bool match = true;
for (int j = 0; j < chunk.Length; j++) { if (!Equals(chunk[j], collection[j])) { match = false; break; } }
if (!match) {
Array.Resize(ref result, result.Length + 1);
result[result.Length - 1] = chunk[0];
}
else i += collection.Length - 1;
}
array = result;
}
或
/// <summary>
/// Removes a collection of the specified index count at the specified index from the referenced array.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array"></param>
/// <param name="size"></param>
/// <param name="index"></param>
public static void Remove<T>(ref T[] array, int count, int index)
{
if (index + count >= array.Length || index >= array.Length || count > array.Length) { throw new ArgumentOutOfRangeException(); }
for (int i = 0; i < array.Length; i++) { if (i == index) i += count - 1; else if (i - count >= 0) array[i - count] = array[i]; }
Array.Resize(ref array, array.Length - count);
}
我为您提供了一个简单的解决方案。它不是一个很好的优化。但你可以接受它的想法。
static int[] Run(int[] greaterArray, int[] lesserArray)
{
for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
{
if (greaterArray.Skip(i).Take(lesserArray.Length).SequenceEqual(lesserArray))
{
return greaterArray.Take(i).Concat(greaterArray.Skip(i + lesserArray.Length)).ToArray();
}
}
return greaterArray;
}
我只针对两个数组之间的差异进行迭代。则我跳过CCD_ 1,然后取第二阵列的长度。如果它们相等。它将采用第一个数组的第一个元素,并连接到第一个数组中的其余元素。
您可以增强此方法的性能。希望你明白。
尝试这个
int[] greaterArray = { 8, 3, 4, 5, 9, 12, 6, 3, 5 };
int[] lesserArray = { 3, 4, 5 };
int[] resultArray = string.Join(",", greaterArray).Replace(string.Join(",", lesserArray), "").Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(p => Convert.ToInt32(p)).ToArray();
您可以使用ArraySegment更好地了解您的算法:
static void Main(string[] args)
{
int[] array = {8, 3, 4, 5, 9, 12, 6, 3, 5};
int[] subArray = {3, 4, 5};
int arrayLength = array.Length;
int subArrayLength = subArray.Length;
ArraySegment<int> segment = new ArraySegment<int>();
bool found = false;
for (int i = 0; i < arrayLength - subArrayLength; i++)
{
segment = new ArraySegment<int>(array, i, subArrayLength);
// look for sub array
int nbFound = 0;
for (int j = 0; j < subArrayLength; j++)
{
if (segment.Array[segment.Offset + j] == subArray[j])
++nbFound;
else
break;
}
// sub array found
if (nbFound == subArrayLength)
{
found = true;
break;
}
}
if (found)
{
int[] result = new int [arrayLength - subArrayLength];
Array.Copy(array, 0, result, 0, segment.Offset + 1);
Array.Copy(array, segment.Offset + subArrayLength, result, segment.Offset + 1, arrayLength - 1 - segment.Offset - subArrayLength);
Console.WriteLine($"Result : {string.Join(", ", result)}");
}
else
{
Console.WriteLine($"Result : {string.Join(", ", array)}");
}
Console.ReadKey();
}