一、字符串数组去重复
字符串数组去重复是指在一个字符串数组中,去掉重复的元素,使得数组中的元素唯一。字符串数组去重复是一个常见的问题,因为在实际的开发中,我们经常需要对一个字符串数组进行去重操作。下面我们就来看一下字符串数组去重的一些方法和原理。
二、字符串数组去重算法
常见的字符串数组去重算法有两种,分别是:哈希表法和双重循环法。
1、哈希表法
std::unordered_set
unique_set;
for (auto str: str_array)
{
unique_set.insert(str);
}
std::vector
unique_str_array(unique_set.begin(), unique_set.end());
哈希表法的实现原理是创建一个哈希表,将字符串数组中的每个元素都插入到哈希表中。由于哈希表中不能存在相同的元素,所以最终得到的哈希表中就是去重后的字符串数组。在C++中,可以使用std::unordered_set实现哈希表。
2、双重循环法
for (int i = 0; i < str_array.size(); ++i)
{
bool flag = false;
for (int j = 0; j < i; ++j)
{
if (str_array[i] == str_array[j])
{
flag = true;
break;
}
}
if (flag == false)
{
unique_str_array.push_back(str_array[i]);
}
}
双重循环法的实现原理是,使用两个循环遍历整个字符串数组,对于每个元素,判断它前面是否已经出现过。如果已经出现过,则标记为重复元素,否则添加到新的数组中。该方法的时间复杂度为O(N^2)。
三、字符串数组去重c语言代码
在C语言中,可以使用hash表实现字符串数组去重。
// 哈希表大小
#define HAVEHT_SIZE 100
// 哈希表结构体
typedef struct _haveht
{
char* val; // 值
struct _haveht* next; // 链表指针
} haveht;
// 哈希表
haveht* hashTable[HASH_SIZE];
void cleanHashTable()
{
memset(hashTable, 0, sizeof(hashTable));
}
int hash(const char* str)
{
int hash = 0;
int len = strlen(str);
for (int i = 0; i < len; i++)
{
hash = hash * 31 + str[i];
}
return (hash & 0x7fffffff) % HAVEHT_SIZE;
}
void addHashtable(const char* str)
{
int key = hash(str);
haveht* node = hashTable[key];
while (node != NULL)
{
if (strcmp(node->val, str) == 0)
{
return;
}
node = node->next;
}
haveht* new_node = (haveht*)malloc(sizeof(haveht));
new_node->val = str;
new_node->next = hashTable[key];
hashTable[key] = new_node;
}
//去重函数
int unique(char* a[], int n)
{
cleanHashTable();
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (strlen(a[i]) == 0)
{
continue;
}
int key = hash(a[i]);
haveht* node = hashTable[key];
while (node != NULL)
{
if (strcmp(node->val, a[i]) == 0)
{
a[i][0] = 0;
break;
}
node = node->next;
}
if (strlen(a[i]) != 0)
{
addHashtable(a[i]);
cnt++;
}
}
return cnt;
}
四、前端字符串数组去重
在前端的开发中,我们同样需要对字符串数组进行去重。下面我们就来介绍几种前端去重的方式。
1、ES6 Set去重法
const arr = ['aaa', 'bbb', 'ccc', 'aaa', 'bbb'];
function unique(arr) {
return [...new Set(arr)];
}
const uniqueArr = unique(arr); // ['aaa', 'bbb', 'ccc']
ES6中提供了Set数据结构,Set可以自动去重。结合ES6的解构语法,就可以使用一行代码实现字符串数组的去重操作。
2、reduce去重法
const arr = ['aaa', 'bbb', 'ccc', 'aaa', 'bbb'];
function unique(arr) {
return arr.reduce((res, cur) => {
return res.includes(cur) ? res : [...res, cur];
}, []);
}
const uniqueArr = unique(arr); // ['aaa', 'bbb', 'ccc']
reduce函数是JS中非常常用的函数,通常用于将一个数组中的元素按照某种方式进行聚合。在去重时,我们可以通过reduce函数来依次遍历数组中的每个元素,将不同的元素保存到res数组中,从而实现去重操作。这种方法的时间复杂度为O(N)。
3、filter去重法
const arr = ['aaa', 'bbb', 'ccc', 'aaa', 'bbb'];
function unique(arr) {
return arr.filter((el, index, arr) => {
return arr.indexOf(el) === index;
});
}
const uniqueArr = unique(arr); // ['aaa', 'bbb', 'ccc']
filter函数通常用于过滤数组中的元素,从而得到一个新的符合条件的数组。在去重时,我们可以通过filter函数来过滤掉重复的元素,从而得到一个新的数组。这种方法的时间复杂度为O(N^2)。
五、定义字符串数组
定义字符串数组,需要使用类型为char*的指针数组即可。例如,可以使用以下方式来定义一个长度为3的字符串数组:
char* str_array[3] = {"aaa", "bbb", "ccc"};
六、字符串和数组的区别
字符串和数组都是C/C++/JS中经常使用的数据结构,它们都有相似的定义和使用方式,但是它们之间存在一些区别。
1、内存存储方式不同
数组的元素是连续存储的,而字符串的元素是在内存中分散存储的。数组的元素存储在一个数据块中,通过索引可以直接访问到元素。而字符串的元素存储在不同的内存块中,需要使用指针来访问。
2、定义方式不同
在定义一个数组时,需要指定数组的大小,在定义字符串时,可以根据字符串的长度自动分配内存空间。
3、字符串具有特殊的终止符
字符串在内存中有一个特殊的终止符,即'\0',用来标识字符串的结尾,而数组没有这个终止符。
七、字符串数组重排
字符串数组重排指的是将一个字符串数组按照指定的顺序重新排列。下面我们介绍两种常见的字符串数组重排方式。
1、快速排序法
void quickSort(char **str_array, int left, int right)
{
if (left >= right) {
return;
}
char* pivot = *(str_array + left);
int i = left + 1, j = right;
while (true)
{
while (i <= j && strcmp(*(str_array + i), pivot) < 0)
{
i++;
}
while (i <= j && strcmp(*(str_array + j), pivot) >= 0)
{
j--;
}
if (i > j)
{
break;
}
char* temp = *(str_array + i);
*(str_array + i) = *(str_array + j);
*(str_array + j) = temp;
}
*(str_array + left) = *(str_array + j);
*(str_array + j) = pivot;
quickSort(str_array, left, j - 1);
quickSort(str_array, j + 1, right);
}
快速排序法是一种高效的排序算法,时间复杂度为O(NlogN)。在对字符串数组重排时,我们可以使用快速排序法将数组中的元素按照一定的顺序进行排序。例如,下面的代码可以对字符串数组按照字典序进行排序:
char* str_array[5] = {"hello", "world", "apple", "banana", "cat"};
quickSort(str_array, 0, 4);
for (int i = 0; i < 5; ++i)
{
printf("%s ", *(str_array + i));
}
2、STL中的sort函数
#include
bool compareFunc (const char* a, const char* b)
{
return strcmp(a,b) < 0;
}
int main()
{
char* str_array[5] = {"hello", "world", "apple", "banana", "cat"};
std::sort(str_array, str_array + 5, compareFunc);
for(int i = 0; i < 5; ++i)
{
printf("%s ", *(str_array + i));
}
return 0;
}
在C++ STL中,提供了sort函数,可以通过指定比较函数来对数组进行排序。比较函数需要返回一个bool类型的值,表示两个元素的比较结果。下面的代码可以对字符串数组按照字典序进行排序:
八、字符串去重的方法
下面我们总结一下字符串去重的五种方法。
1、哈希表法
哈希表法的实现原理是创建一个哈希表,将字符串数组中的每个元素都插入到哈希表中。由于哈希表中不能存在相同的元素,所以最终得到的哈希表中就是去重后的字符串数组。实现语言包括C++,Python等。
2、双重循环法
双重循环法的实现原理是,使用两个循环遍历整个字符串数组,对于每个元素,判断它前面是否已经出现过。如果已经出现过,则标记为重复元素,否则添加到新的数组中。该方法的时间复杂度为O(N^2)。实现语言包括C++,Java等。
3、ES6 Set去重法
ES6中提供了Set数据结构,Set可以自动去重。结合ES6的解构语法,就可以使用一行代码实现字符串数组的去重操作。实现语言为JS。
4、reduce去重法
reduce函数是JS中非常常用的函数,通常用于将一个数组中的元素按照某种方式进行聚合。在去重时,我们可以通过reduce函数来依次遍历数组中的每个元素,将不同的元素保存到res数组中,从而实现去重操作。该方法的时间复杂度为O(N)。实现语言为JS。
5、filter去重法
filter函数通常用于过滤数组中的元素,从而得