C 算法:从数组中删除重复整数的有效方法
我在接受微软采访时遇到了这个问题 给定一个随机整数数组, 用C编写一个算法来删除 复制数字并返回原始数字中的唯一数字 数组 例如输入:C 算法:从数组中删除重复整数的有效方法,c,algorithm,arrays,duplicates,C,Algorithm,Arrays,Duplicates,我在接受微软采访时遇到了这个问题 给定一个随机整数数组, 用C编写一个算法来删除 复制数字并返回原始数字中的唯一数字 数组 例如输入:{4,8,4,1,1,2,9}输出:{4,8,1,2,9,,?} 需要注意的是,预期的算法不应要求首先对数组进行排序。当一个元素被移除时,下列元素也必须向前移动。无论如何,数组尾部元素向前移动的元素值可以忽略不计 更新:结果必须在原始数组中返回,并且不应使用助手数据结构(例如哈希表)。然而,我想订单保存是没有必要的 更新2:对于那些想知道为什么这些不切实际的约束的
{4,8,4,1,1,2,9}
输出:{4,8,1,2,9,,?}
需要注意的是,预期的算法不应要求首先对数组进行排序。当一个元素被移除时,下列元素也必须向前移动。无论如何,数组尾部元素向前移动的元素值可以忽略不计 更新:结果必须在原始数组中返回,并且不应使用助手数据结构(例如哈希表)。然而,我想订单保存是没有必要的
更新2:对于那些想知道为什么这些不切实际的约束的人来说,这是一个采访问题,在思考过程中讨论了所有这些约束,以了解我如何提出不同的想法。如果您正在寻找更优的O表示法,则使用O(n log n)排序对数组排序,然后执行O(n)穿越可能是最好的路线。如果不进行排序,您将看到O(n^2)
编辑:如果你只是做整数,那么你也可以做基数排序来得到O(n)。一个数组显然应该从右到左“遍历”,以避免不必要的值来回复制 如果内存不受限制,可以为
sizeof(数组中元素的类型)/8字节分配一个位数组,使每个位表示是否已经遇到相应的值
如果您不这样做,我想不出比遍历数组并将每个值与后面的值进行比较更好的方法,然后如果发现重复,则将这些值全部删除。这是在O(n^2)(或O((n^2-n)/2)附近的某个地方
IBM有一个非常接近的主题。嗯,它的基本实现非常简单。检查所有元素,检查剩余元素中是否有重复元素,并将其余元素移到它们上面
这是非常低效的,您可以通过一个用于输出或排序/二叉树的助手数组来加快速度,但这似乎是不允许的。如果愿意牺牲内存,您可以在一次遍历中完成这项工作。您可以简单地统计是否在哈希/关联数组中看到整数。如果您已经看到一个数字,请在移动时将其删除,或者更好的做法是,将未看到的数字移动到新数组中,避免在原始数组中发生任何移动
在Perl中:
foreach $i (@myary) {
if(!defined $seen{$i}) {
$seen{$i} = 1;
push @newary, $i;
}
}
让我们看看:
- O(N)通过查找最小/最大分配
- 找到的位数组
- O(N)将交换重复项传递到末尾
如果允许使用C++,调用<代码> STD::排序< /COD>,然后调用<代码> STD::唯一的< /Cord>将给出答案。排序的时间复杂度为O(N logn),唯一遍历的时间复杂度为O(N)
<如果> C++没有表,没有任何东西可以阻止这些相同的算法被写在C.< P>中。如果你有一个好的数据结构,可以很快地判断它是否包含整数,那么它会很酷。也许是某种树
DataStructure elementsSeen = new DataStructure();
int elementsRemoved = 0;
for(int i=0;i<array.Length;i++){
if(elementsSeen.Contains(array[i])
elementsRemoved++;
else
array[i-elementsRemoved] = array[i];
}
array.Length = array.Length - elementsRemoved;
DataStructure elementsSeen=newdatastructure();
int elementsRemoved=0;
对于(int i=0;i这可以在单次传递中完成,输入中整数的数量为O(N)次
列表,并以O(N)存储唯一整数的个数
从前到后浏览列表,使用两个指针“dst”和
“src”初始化为第一项。从空哈希表开始
如果src处的整数不在散列中,
将其写入dst处的插槽并递增dst。在src处添加整数
到散列,然后递增src。重复,直到src通过
输入列表。如何:
void rmdup(int *array, int length)
{
int *current , *end = array + length - 1;
for ( current = array + 1; array < end; array++, current = array + 1 )
{
while ( current <= end )
{
if ( *current == *array )
{
*current = *end--;
}
else
{
current++;
}
}
}
}
void rmdup(int*数组,int长度)
{
int*当前,*结束=数组+长度-1;
用于(当前=阵列+1;阵列 而(当前我女朋友建议的解决方案是合并排序的一种变体。唯一的修改是在合并步骤中,忽略重复的值。此解决方案也是O(n log n)。在这种方法中,排序/重复删除是结合在一起的。但是,我不确定这是否有任何区别。一个更有效的实现
int i, j;
/* new length of modified array */
int NewLength = 1;
for(i=1; i< Length; i++){
for(j=0; j< NewLength ; j++)
{
if(array[i] == array[j])
break;
}
/* if none of the values in index[0..j] of array is not same as array[i],
then copy the current value to corresponding new position in array */
if (j==NewLength )
array[NewLength++] = array[i];
}
inti,j;
/*修正数组的新长度*/
int NewLength=1;
对于(i=1;i
在这个实现中,不需要对数组进行排序。
此外,如果发现重复的元素,则不需要将该元素之后的所有元素移动一个位置
此代码的输出是大小为NewLength的数组[]
在这里,我们从数组中的第二个元素开始,并将其与数组中直到该数组的所有元素进行比较。
我们持有一个额外的索引变量“NewLength”,用于修改输入数组。
NewLength variabel已初始化为0
数组[1]中的元素将与数组[0]进行比较。
如果它们不同,则将使用数组[1]和增量NewLength修改数组[NewLength]中的值。
如果它们相同,则不会修改NewLength
如果我们有一个数组[1,2,1,3,1],
然后
在“j”循环的第一个过程中,将数组[1](2)与数组0进行比较,然后将2写入数组[NewLength]=array[1]
因为NewLength=2,所以数组将是[12]
在“j”循环的第二个过程中,数组[2](1)将与数组0和数组1进行比较。这里,由于数组[2](1)和数组0是相同的,因此循环将b
int length = array.length;
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length; j++)
{
if (array[i] == array[j])
{
int k, j;
for (k = j + 1, l = j; k < length; k++, l++)
{
if (array[k] != array[i])
{
array[l] = array[k];
}
else
{
l--;
}
}
length = l;
}
}
}
void uniqueInPlace(T)(ref T[] dataIn) {
uniqueInPlaceImpl(dataIn, 0);
}
void uniqueInPlaceImpl(T)(ref T[] dataIn, size_t start) {
if(dataIn.length - start < 2)
return;
invariant T sentinel = dataIn[start];
T[] data = dataIn[start + 1..$];
static hash_t getHash(T elem) {
static if(is(T == uint) || is(T == int)) {
return cast(hash_t) elem;
} else static if(__traits(compiles, elem.toHash)) {
return elem.toHash;
} else {
static auto ti = typeid(typeof(elem));
return ti.getHash(&elem);
}
}
for(size_t index = 0; index < data.length;) {
if(data[index] == sentinel) {
index++;
continue;
}
auto hash = getHash(data[index]) % data.length;
if(index == hash) {
index++;
continue;
}
if(data[index] == data[hash]) {
data[index] = sentinel;
index++;
continue;
}
if(data[hash] == sentinel) {
swap(data[hash], data[index]);
index++;
continue;
}
auto hashHash = getHash(data[hash]) % data.length;
if(hashHash != hash) {
swap(data[index], data[hash]);
if(hash < index)
index++;
} else {
index++;
}
}
size_t swapPos = 0;
foreach(i; 0..data.length) {
if(data[i] != sentinel && i == getHash(data[i]) % data.length) {
swap(data[i], data[swapPos++]);
}
}
size_t sentinelPos = data.length;
for(size_t i = swapPos; i < sentinelPos;) {
if(data[i] == sentinel) {
swap(data[i], data[--sentinelPos]);
} else {
i++;
}
}
dataIn = dataIn[0..sentinelPos + start + 1];
uniqueInPlaceImpl(dataIn, start + swapPos + 1);
}
int algorithm(int[] a, int n)
{
int i, j;
for (j = 0, i = 1; i < n; i++)
{
// Insert a[i] into the heap a[0...j]
if (heapInsert(a, j, a[i]))
j++;
}
return j;
}
bool heapInsert(a[], int n, int val)
{
// Insert val into heap a[0...n]
...code omitted for brevity...
if (duplicate element a[k] == val)
return false;
a[k] = val;
return true;
}
int* temp = malloc(sizeof(int)*len);
int count = 0;
int x =0;
int y =0;
for(x=0;x<len;x++)
{
for(y=0;y<count;y++)
{
if(*(temp+y)==*(array+x))
{
break;
}
}
if(y==count)
{
*(temp+count) = *(array+x);
count++;
}
}
memcpy(array, temp, sizeof(int)*len);
var
A: Array of Integer;
I,J,C,K, P: Integer;
begin
C:=10;
SetLength(A,10);
A[0]:=1; A[1]:=4; A[2]:=2; A[3]:=6; A[4]:=3; A[5]:=4;
A[6]:=3; A[7]:=4; A[8]:=2; A[9]:=5;
for I := 0 to C-1 do
begin
for J := I+1 to C-1 do
if A[I]=A[J] then
begin
for K := C-1 Downto J do
if A[J]<>A[k] then
begin
P:=A[K];
A[K]:=0;
A[J]:=P;
C:=K;
break;
end
else
begin
A[K]:=0;
C:=K;
end;
end;
end;
//tructate array
setlength(A,C);
end;
int[] removeDuplicate(int[] input){
int arrayLen = input.length;
for(int i=0;i<arrayLen;i++){
for(int j = i+1; j< arrayLen ; j++){
if(((input[i]^input[j]) == 0)){
input[j] = 0;
}
if((input[j]==0) && j<arrayLen-1){
input[j] = input[j+1];
input[j+1] = 0;
}
}
}
return input;
}
def check_dump(x):
if not x in t:
t.append(x)
return True
t=[]
output = filter(check_dump, input)
print(output)
True
Integer[] arrayInteger = {1,2,3,4,3,2,4,6,7,8,9,9,10};
String value ="";
for(Integer i:arrayInteger)
{
if(!value.contains(Integer.toString(i))){
value +=Integer.toString(i)+",";
}
}
String[] arraySplitToString = value.split(",");
Integer[] arrayIntResult = new Integer[arraySplitToString.length];
for(int i = 0 ; i < arraySplitToString.length ; i++){
arrayIntResult[i] = Integer.parseInt(arraySplitToString[i]);
}
///// find duplicates in an array and remove them
void unique(int* input, int n)
{
merge_sort(input, 0, n) ;
int prev = 0 ;
for(int i = 1 ; i < n ; i++)
{
if(input[i] != input[prev])
if(prev < i-1)
input[prev++] = input[i] ;
}
}
#include <stdio.h>
#include <stdlib.h>
size_t rmdup(int *arr, size_t len)
{
size_t prev = 0;
size_t curr = 1;
size_t last = len - 1;
while (curr <= last) {
for (prev = 0; prev < curr && arr[curr] != arr[prev]; ++prev);
if (prev == curr) {
++curr;
} else {
arr[curr] = arr[last];
--last;
}
}
return curr;
}
void print_array(int *arr, size_t len)
{
printf("{");
size_t curr = 0;
for (curr = 0; curr < len; ++curr) {
if (curr > 0) printf(", ");
printf("%d", arr[curr]);
}
printf("}");
}
int main()
{
int arr[] = {4, 8, 4, 1, 1, 2, 9};
printf("Before: ");
size_t len = sizeof (arr) / sizeof (arr[0]);
print_array(arr, len);
len = rmdup(arr, len);
printf("\nAfter: ");
print_array(arr, len);
printf("\n");
return 0;
}
import java.util.ArrayList;
public class C {
public static void main(String[] args) {
int arr[] = {2,5,5,5,9,11,11,23,34,34,34,45,45};
ArrayList<Integer> arr1 = new ArrayList<Integer>();
for(int i=0;i<arr.length-1;i++){
if(arr[i] == arr[i+1]){
arr[i] = 99999;
}
}
for(int i=0;i<arr.length;i++){
if(arr[i] != 99999){
arr1.add(arr[i]);
}
}
System.out.println(arr1);
}
}
#include <stdio.h>
#include <stdlib.h>
int numbers[] = {4, 8, 4, 1, 1, 2, 9};
#define COUNT (sizeof numbers / sizeof numbers[0])
size_t undup_it(int array[], size_t len)
{
size_t src,dst;
/* an array of size=1 cannot contain duplicate values */
if (len <2) return len;
/* an array of size>1 will cannot at least one unique value */
for (src=dst=1; src < len; src++) {
size_t cur;
for (cur=0; cur < dst; cur++ ) {
if (array[cur] == array[src]) break;
}
if (cur != dst) continue; /* found a duplicate */
/* array[src] must be new: add it to the list of non-duplicates */
if (dst < src) array[dst] = array[src]; /* avoid copy-to-self */
dst++;
}
return dst; /* number of valid alements in new array */
}
void print_it(int array[], size_t len)
{
size_t idx;
for (idx=0; idx < len; idx++) {
printf("%c %d", (idx) ? ',' :'{' , array[idx] );
}
printf("}\n" );
}
int main(void) {
size_t cnt = COUNT;
printf("Before undup:" );
print_it(numbers, cnt);
cnt = undup_it(numbers,cnt);
printf("After undup:" );
print_it(numbers, cnt);
return 0;
}
{
if (check[arr[i]] != 1) {
arr[i] = 0;
}
else {
check[arr[i]] = 0;
}
}
Algorithm delete_duplicates (a[1....n])
//Remove duplicates from the given array
//input parameters :a[1:n], an array of n elements.
{
temp[1:n]; //an array of n elements.
temp[i]=a[i];for i=1 to n
temp[i].value=a[i]
temp[i].key=i
//based on 'value' sort the array temp.
//based on 'value' delete duplicate elements from temp.
//based on 'key' sort the array temp.//construct an array p using temp.
p[i]=temp[i]value
return p.
#include <stdio.h>
int main(void){
int x,n,myvar=0;
printf("Enter a number: \t");
scanf("%d",&n);
int arr[n],changedarr[n];
for(x=0;x<n;x++){
printf("Enter a number for array[%d]: ",x);
scanf("%d",&arr[x]);
}
printf("\nOriginal Number in an array\n");
for(x=0;x<n;x++){
printf("%d\t",arr[x]);
}
int i=0,j=0;
// printf("i\tj\tarr\tchanged\n");
for (int i = 0; i < n; i++)
{
// printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
for (int j = 0; j <n; j++)
{
if (i==j)
{
continue;
}
else if(arr[i]==arr[j]){
changedarr[j]=0;
}
else{
changedarr[i]=arr[i];
}
// printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
}
myvar+=1;
}
// printf("\n\nmyvar=%d\n",myvar);
int count=0;
printf("\nThe unique items:\n");
for (int i = 0; i < myvar; i++)
{
if(changedarr[i]!=0){
count+=1;
printf("%d\t",changedarr[i]);
}
}
printf("\n");
}