100求算法,一个好像很简单的,但是我想的有点混乱了,求助思路清晰的高手~~

Echone902 2005-05-19 10:14:13
数组a[n]和b[n],a[n]中有一些数字,其中有些是重复的,
现要将数组a中的放入数组b中,但重复的数只能留一个,
如将1,2,3,4,2,3 插入b后 变成 1,2,3,4, 大小顺序不要求~~


...全文
308 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
jp1984 2005-05-24
  • 打赏
  • 举报
回复
要知道hash比stl 中set要快。set的内部查找用二叉搜索树
nlstone 2005-05-24
  • 打赏
  • 举报
回复
最简单的办法是直接使用STL里的set来做,效率有保证...
zhang_jiang 2005-05-24
  • 打赏
  • 举报
回复
/* Delete a key and associated data. The `data' parameter must point to the data associated with an existing key. */
void
htable_delete (struct htable *const table, void *const data)
{
table->slots [*DATA2INDEXPTR (data)].key = DELETED;
free (DATA2INDEXPTR (data));
--table->occupancy;

if (table->occupancy < htable_size [table->size_index] / 5 && table->size_index > 0)
htable_rehash (table, table->size_index - 1);
}



/* Find the data associated with a key. If the key does not exist, a null pointer is returned. */
void *
htable_find (const struct htable *const table, const char *const key)
{
const size_t size = htable_size [table->size_index];
unsigned int hash0, hash1;
size_t increment, i;

hash_string (key, &hash0, &hash1);
increment = hash1 % (size - 2) + 1;
i = hash0 % size;

while (1)
{
if (table->slots [i].key == 0)
return 0;
else if (table->slots [i].key != DELETED && table->slots [i].hash0 == hash0 && table->slots [i].hash1 == hash1
&& strcmp (key, table->slots [i].key) == 0)
return table->slots [i].data;

i = (i + increment) % size;
}
}



/* Copy an existing table into the new one which has a different size. If memory allocation fails, -1 is returned;
otherwise zero is returned. */
static int
htable_rehash (struct htable *const table, const size_t new_size_index)
{
const size_t new_size = htable_size [new_size_index];
struct htable_slot *const new_slots = malloc (new_size * sizeof *new_slots);

if (new_slots == 0)
return -1;

{
size_t i;
for (i = 0; i < new_size; ++i)
new_slots [i].key = 0;
}

{
size_t j;
for (j = 0; j < htable_size [table->size_index]; ++j)
if (table->slots [j].key != 0 && table->slots [j].key != DELETED)
{
const size_t increment = table->slots [j].hash1 % (new_size - 2) + 1;
size_t i = table->slots [j].hash0 % new_size;

while (new_slots [i].key != 0)
i = (i + increment) % new_size;

new_slots [i] = table->slots [j];
*DATA2INDEXPTR (new_slots [i].data) = i;
}
}

free (table->slots);
table->slots = new_slots;
table->size_index = new_size_index;
return 0;
}



/* Calculate two hash values for a given string. Return string length, including the terminating NUL character. */
static size_t
hash_string (const char *str, unsigned int *const hash0, unsigned int *const hash1)
{
size_t len;

*hash0 = 0;
*hash1 = 0xffffffff;

for (len = 1; *str != '\0'; ++str, ++len)
{
*hash0 = (((*hash0 << 7) & 0xffffffff) | (*hash0 >> 25));
*hash0 ^= *(const unsigned char *)str;

*hash1 ^= *(const unsigned char *)str;
*hash1 = (((*hash1 << 5) & 0xffffffff) | (*hash1 >> 27));
}

return len;
}
zhang_jiang 2005-05-24
  • 打赏
  • 举报
回复
hash.c
==============================================================================
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "hash.h"


/* Alignment of the data associated with a key. */
#define ALIGNMENT 16

/* Size of `size_t' rounded up to an integer multiple of `ALIGNMENT'. */
#define SIZEOF_SIZE_T (sizeof (size_t) + (ALIGNMENT - 1) - (sizeof (size_t) - 1) % ALIGNMENT)

/* Get data pointer from pointer to slot index. */
#define INDEXPTR2DATA(index_ptr) ((void *)((char *)(index_ptr) + SIZEOF_SIZE_T))

/* Get pointer to slot index from data pointer. */
#define DATA2INDEXPTR(data) ((size_t *)((char *)(data) - SIZEOF_SIZE_T))

/* Special key to indicate a deleted slot. */
#define DELETED ((char *)(&deleted_key))
static const char deleted_key;



/* Hash table slot. */
struct htable_slot {
char *key; /* Key; null pointer for empty slots; `DELETED' for deleted slots. If this member is
a null pointer or `DELETED', the other members are not valid. */
void *data; /* Data associated with the key. */
unsigned int hash0; /* First hash value. */
unsigned int hash1; /* Second hash value. */
};



/* Possible hash table sizes. The numbers are prime numbers with the greatest possible distance to
exact powers of 2. */
static const size_t htable_size [] = {47, 97, 191, 383, 769, 1531, 3067, 6143, 12289, 24571, 49157, 98299, 196613,
393209, 786431, 1572869, 3145721, 6291449, 12582917, 25165813, 50331653,
100663291, 201326611, 402653189, 805306357, 1610612741};

static int htable_rehash (struct htable *table, size_t new_size_index);
static size_t hash_string (const char *str, unsigned int *hash0, unsigned int *hash1);



/* Create a hash table. On success, zero is returned. If memory allocation fails, -1 is returned. */
int
htable_create (struct htable *const table)
{
struct htable_slot *const slots = malloc (htable_size [0] * sizeof *slots);

if (slots == 0)
return -1;

{
size_t i;
for (i = 0; i < htable_size [0]; ++i)
slots [i].key = 0;
}

table->slots = slots;
table->size_index = 0;
table->occupancy = 0;

return 0;
}



/* Destroy a hash table. Free all associated memory. */
void
htable_destroy (struct htable *const table)
{
size_t i;
for (i = 0; i < htable_size [table->size_index]; ++i)
if (table->slots [i].key != 0 && table->slots [i].key != DELETED)
free (DATA2INDEXPTR (table->slots [i].data));

free (table->slots);
}



/* Insert a new key and associated data into a hash table. The key must be a NUL-terminated string. The data is
copied; the location of the copied data is returned, and if `exists_ptr' is not a null pointer, the integer at
the location pointed to is set to zero. If the key already exists, the location of the data associated with the
existing key data is returned, and if `exists_ptr' is not a null pointer, the integer at the location pointed to
is set to one. If `data_len' is zero, `data' is not evaluated and the returned pointer must not be dereferenced.
If memory allocation fails, a null pointer is returned. */
void *
htable_insert (struct htable *const table, const char *const key, const void *const data, const size_t data_len,
int *const exists_ptr)
{
size_t size = htable_size [table->size_index], key_len, *index_ptr, slot_index;
unsigned int hash0, hash1;


if (table->occupancy > size / 2)
{
if (table->size_index < sizeof htable_size / sizeof *htable_size - 1)
{
if (htable_rehash (table, table->size_index + 1) == -1)
return 0;
}
else if (table->occupancy >= htable_size [sizeof htable_size / sizeof *htable_size - 1] / 5 * 4)
return 0;

size = htable_size [table->size_index];
}

key_len = hash_string (key, &hash0, &hash1);
index_ptr = malloc (SIZEOF_SIZE_T + data_len + key_len);
if (index_ptr == 0)
return 0;

{
const size_t increment = hash1 % (size - 2) + 1;
size_t i = hash0 % size;

slot_index = (size_t)-1;
while (1)
{
if (table->slots [i].key == 0)
{
if (slot_index == (size_t)-1)
slot_index = i;
break;
}
else if (table->slots [i].key == DELETED)
{
if (slot_index == (size_t)-1)
slot_index = i;
}
else if (table->slots [i].hash0 == hash0 && table->slots [i].hash1 == hash1
&& strcmp (key, table->slots [i].key) == 0)
{
if (exists_ptr != 0)
*exists_ptr = 1;
return table->slots [i].data;
}

i = (i + increment) % size;
}
}

table->slots [slot_index].key = (char *)INDEXPTR2DATA (index_ptr) + data_len;
table->slots [slot_index].data = INDEXPTR2DATA (index_ptr);
table->slots [slot_index].hash0 = hash0;
table->slots [slot_index].hash1 = hash1;
++table->occupancy;

*index_ptr = slot_index;
memcpy (table->slots [slot_index].key, key, key_len);
if (data_len > 0)
memcpy (table->slots [slot_index].data, data, data_len);

if (exists_ptr != 0)
*exists_ptr = 0;
return table->slots [slot_index].data;
}
zhang_jiang 2005-05-24
  • 打赏
  • 举报
回复
hash.h
=========================================================================
/* This file is part of an open-address hash table implementation.
Copyright (C) 2005 Martin Dickopp

This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this file; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
USA. */

#ifndef HDR_HASH
#define HDR_HASH 1


/* Hash table. The members should not be accessed directly. */
struct htable {
struct htable_slot *slots;
size_t size_index;
size_t occupancy;
};


/* Create a hash table. On success, zero is returned. If memory allocation fails, -1 is returned. */
extern int htable_create (struct htable *table);

/* Destroy a hash table. Free all associated memory. */
extern void htable_destroy (struct htable *table);

/* Insert a new key and associated data into a hash table. The key must be a NUL-terminated string. The data is
copied; the location of the copied data is returned, and if `exists_ptr' is not a null pointer, the integer at
the location pointed to is set to zero. If the key already exists, the location of the data associated with the
existing key data is returned, and if `exists_ptr' is not a null pointer, the integer at the location pointed to
is set to one. If `data_len' is zero, `data' is not evaluated and the returned pointer must not be dereferenced.
If memory allocation fails, a null pointer is returned. */
extern void *htable_insert (struct htable *table, const char *key, const void *data, size_t data_len,
int *exists_ptr);

/* Delete a key and associated data. The `data' parameter must point to the data associated with an existing key. */
extern void htable_delete (struct htable *table, void *data);

/* Find the data associated with a key. If the key does not exist, a null pointer is returned. */
extern void *htable_find (const struct htable *table, const char *key);


#endif
gladiatorcn 2005-05-23
  • 打赏
  • 举报
回复
hash sort!
不停插入就可以,只要不准许重复就行。最后再处理掉中间可能存在的空格。
h(x)选k%n就可以。
MagicCarmack 2005-05-23
  • 打赏
  • 举报
回复
学习。。。。。。。。。。。。。。
constantine 2005-05-22
  • 打赏
  • 举报
回复
hash,速度也比较快
jp1984 2005-05-22
  • 打赏
  • 举报
回复
最简单的方法就是两次遍力啊。 复杂度O(n^2).
Echone902 2005-05-22
  • 打赏
  • 举报
回复
其实我是做一些重复网址的踢除,

原网址是由正则表达式得来的,在一个类似数组的东西里,

踢除后的网址存在队列里~~

主要是时间上的要求~

c版的一些高手也给了我不少建议,说可以排下字典序或者用hash~~,无奈我都怎么会用,现在我是差不多是用了类似yanghy2013(混子杨)的这种方法,这速度实在是不敢恭维:(
yelling 2005-05-22
  • 打赏
  • 举报
回复
你定一下范围,可以马上给你代码
yanghy2013 2005-05-22
  • 打赏
  • 举报
回复
从A中取一个元素在插入B之前到B里面搜索看有没有此元素,如果有的话就插入,否则A往下移一位。
blue_sky007 2005-05-21
  • 打赏
  • 举报
回复
hash确实比较好.
也可以用stl里面的set.
寻开心 2005-05-20
  • 打赏
  • 举报
回复
最直观的解决方案就是插入排序方法
http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.2.1.1.htm
galois_godel 2005-05-20
  • 打赏
  • 举报
回复
做法有很多拉,你要保证时间快还是空间小啊
时间快的话,去搞个hash表或者搜索树都可以
空间小的话么,就线性表搜索,
Zephyrzzz 2005-05-20
  • 打赏
  • 举报
回复
hash,用取模做哈希函数就行了.
或者先直接排个序(用快排就行了),然后检查相邻元素是否重复,记录不同的元素,速度也挺快的.
  • 打赏
  • 举报
回复
先把a数组,简化成一个不重复的c数组再插入就是了
xiaohaiyan 2005-05-20
  • 打赏
  • 举报
回复
如果对空间要求不高,而且数组中的值在一个合理的界内(要求有点苛刻,:),可以考虑使用一个数组来记录该数是否已经加入b[n],时间效率是线性的,

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧