包含N个对象的数组A1。另一个包含表示第一个数组中索引的数字的数组A2。您需要从A2中删除A2中的索引所在的元素并生成压缩数组。例如:
A1 = [ a, b, c, d, e, f, g ] // N elements and N is large
A2 = [ 5, 1 ] // k elements and k is small (and constant)
Answer = [ a, c, d, e, g, _, _ ]
我写了C#代码,如:
public class CompactingArray
{
private Compact(array A1 , array A2)
{
var hash = new Hashset<int>(A2);
foreach(int c in hash)
{
A1.remove(c,1);
}
Console.WriteLine(A1);
}
}
我需要O(n)复杂度代码而不使用任何内置函数。请在不使用任何内置函数的情况下建议使用C#代码。
答案 0 :(得分:5)
这是解决方案。
Char[] A1 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
int[] A2 = { 5, 1 };
int k = A2.Length;
int N = A1.Length;
for (int i = 0; i < k; i++)
{
A1[A2[i]] = '\0'; // place null charcater here
}
Char[] copy = new char[N];
for (int i = 0,j=0; i < N; i++) // place all values in sorted order
{
if (A1[i] != '\0')
copy[j++] = A1[i];
}
for (int i = (N-k); i < N;i++ )
{
copy[i] = '-';
}
Console.WriteLine(copy);
答案 1 :(得分:0)
结果数组的顺序是否重要?如果没有,你可以做一些事情:
char[] a = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
int[] z = { 5, 1 };
int zlen = z.Length;
int amax = a.Length - 1;
for (int i = 0; i < zlen; i++)
a[z[i]] = a[amax - i];
最后,您必须调整生成的数组(a
本身)的大小,以便从数组的末尾删除zlen
个元素。该解决方案只是将要移除的元素冒泡到数组的末尾。无需顺序删除。添加正确的索引边界检查等。
答案 2 :(得分:-2)
O(n)
被排序,则 A2
复杂性是可能的,因为那样你只需要一个循环就可以分别为每个数组编制索引:
var A1 = new string[] { "a", "b", "c", "d", "e", "f", "g" }; // N elements and N is large
var A2 = new int[] { 1, 5 }; // k elements and k is small (and constant)
A2 = A2.OrderBy(x => x).ToArray();
var A3 = new string[A1.Length];
int m = 0; // To check it runs only n times.
int leftItemCount = A1.Length - A2.Length;
for (int i = 0, j = 0, k = 0, l = leftItemCount; i < leftItemCount || m < items.Length; i++)
{
m++;
if (j < A2.Length && k == A2[j])
{
j++;
k++;
A3[l++] = "_";
i--;
continue;
}
A3[i] = A1[k];
k++;
}
// Answer = [ a, c, d, e, g, _, _ ] for { 1, 5 }
// Answer = [ a, d, e, g, _, _, _ ] for { 1, 2, 5 }
测试代码:
static void ArrayTests()
{
// Item array lengths.
for (int i = 45; i < 256; i++)
{
var items = Enumerable.Range(0, i).Select(x => x.ToString()).ToArray();
// Number of tests per array.
for (int j = 0; j < 100; j++)
{
// Items to remove.
Random rnd = new Random(DateTime.Now.Millisecond);
var remove = new int[rnd.Next(1, i)];
HashSet<int> indexes = new HashSet<int>();
for (int k = 0; k < remove.Length; k++)
{
int index = 0;
do
{
index = rnd.Next(0, i);
} while (indexes.Contains(index));
indexes.Add(index);
remove[k] = index;
}
remove = remove.OrderBy(x => x).ToArray();
var result = ArrayTest(items, remove);
}
}
}
static string[] ArrayTest(string[] items, int[] remove)
{
var A3 = new string[items.Length];
int m = 0;
int leftItemCount = items.Length - remove.Length;
for (int i = 0, j = 0, k = 0, l = leftItemCount; i < leftItemCount || m < items.Length; i++)
{
m++;
if (j < remove.Length && k == remove[j])
{
j++;
k++;
A3[l++] = "_";
i--;
continue;
}
A3[i] = items[k];
k++;
}
Debug.Assert(m == items.Length);
return A3;
}