0

0

C++中如何用指针实现数组去重 双指针算法与原地操作技巧

P粉602998670

P粉602998670

发布时间:2025-08-18 11:49:01

|

931人浏览过

|

来源于php中文网

原创

c++++中利用指针进行数组去重的核心在于通过双指针实现原地修改和高效遍历。1. 使用 slow 和 fast 两个指针,slow 指向去重后的末尾,fast 遍历数组;2. 当 fast 指向的元素与 slow 不同时,将其复制到 slow+1 的位置并移动 slow;3. 对于未排序数组,可先排序再用双指针,或使用哈希表记录已出现元素以实现 o(n) 时间复杂度;4. 可借助 std::unique 和 std::erase 实现简洁但效率较低的去重方法;5. 对象或结构体数组需重载 == 运算符或提供自定义比较函数;6. 原地操作虽节省内存但会修改原始数组,必要时应创建副本或采用替代方案如哈希表、外部排序。

C++中如何用指针实现数组去重 双指针算法与原地操作技巧

C++中利用指针进行数组去重的核心在于,通过指针操作实现高效的遍历和原地修改,避免额外的内存开销。双指针算法是关键,一个指针用于遍历数组,另一个指针指向去重后的数组的末尾。

C++中如何用指针实现数组去重 双指针算法与原地操作技巧

解决方案

核心思路是使用两个指针:

slow
fast
fast
指针遍历整个数组,
slow
指针指向去重后数组的末尾。如果
fast
指针指向的元素与
slow
指针指向的元素不同,则将
fast
指针指向的元素复制到
slow + 1
的位置,并将
slow
指针向后移动一位。

立即学习C++免费学习笔记(深入)”;

C++中如何用指针实现数组去重 双指针算法与原地操作技巧

以下是一个示例代码:

#include 
#include 

int* removeDuplicates(int* arr, int size) {
    if (size == 0) {
        return arr; // 空数组,无需去重
    }

    int* slow = arr;
    int* fast = arr + 1;

    while (fast < arr + size) {
        if (*fast != *slow) {
            *(++slow) = *fast; // 先移动 slow 指针,再赋值
        }
        ++fast;
    }

    return arr; // 返回原始数组的指针,但数组已被修改
}


int main() {
    int arr[] = {1, 1, 2, 2, 3, 4, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);

    removeDuplicates(arr, size);

    // 输出去重后的数组(实际长度需要单独计算)
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    // 计算去重后的数组的实际长度
    int* last = arr;
    while(*(last+1) != 5 && last < arr + size - 1){
        last++;
    }

    std::cout << "去重后的数组长度: " << last - arr + 1 << std::endl;

    return 0;
}

这段代码直接修改了原始数组。注意,虽然数组的内容被修改了,但数组的大小并没有改变。你需要单独记录去重后数组的实际长度,例如通过计算

slow
指针指向的最后一个有效元素的索引。

C++中如何用指针实现数组去重 双指针算法与原地操作技巧

如何处理未排序的数组去重?

如果数组未排序,一种方法是先对其进行排序,然后再使用双指针算法。排序可以使用

std::sort
函数。但是,排序的时间复杂度为 O(n log n),所以对于未排序数组,如果对性能要求较高,可以考虑使用哈希表(
std::unordered_set
)来记录已经出现的元素,这样可以在 O(n) 的时间复杂度内完成去重,但会占用额外的内存空间。 例如:

Lifetoon
Lifetoon

免费的AI漫画创作平台

下载
#include 
#include 
#include 

int removeDuplicatesUnsorted(int* arr, int size) {
    if (size == 0) {
        return 0;
    }

    std::unordered_set seen;
    int j = 0;
    for (int i = 0; i < size; ++i) {
        if (seen.find(arr[i]) == seen.end()) {
            seen.insert(arr[i]);
            arr[j++] = arr[i];
        }
    }
    return j; // 返回去重后的数组长度
}

int main() {
    int arr[] = {5, 2, 1, 2, 3, 4, 1, 5};
    int size = sizeof(arr) / sizeof(arr[0]);

    int newSize = removeDuplicatesUnsorted(arr, size);

    // 输出去重后的数组
    for (int i = 0; i < newSize; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    std::cout << "去重后的数组长度: " << newSize << std::endl;

    return 0;
}

使用
std::unique
std::erase
进行去重的优缺点?

C++ 标准库提供了

std::unique
函数,它可以将数组中相邻的重复元素移动到数组的末尾,并返回指向去重后数组末尾的迭代器。然后,可以使用
std::erase
函数删除这些重复元素。这种方法的优点是简洁易懂,缺点是效率相对较低,因为它需要移动元素和删除元素。

#include 
#include 
#include 

int main() {
    std::vector arr = {1, 1, 2, 2, 3, 4, 4, 5};

    // 使用 std::unique 将重复元素移动到末尾
    auto it = std::unique(arr.begin(), arr.end());

    // 使用 std::erase 删除重复元素
    arr.erase(it, arr.end());

    // 输出去重后的数组
    for (int i = 0; i < arr.size(); ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    std::cout << "去重后的数组长度: " << arr.size() << std::endl;

    return 0;
}

std::unique
只能作用于连续内存空间,例如
std::vector
。 对于原始数组,需要先将其复制到
std::vector
中。

如何处理包含对象或结构体的数组去重?

如果数组包含的是对象或结构体,你需要定义一个比较函数,用于判断两个对象是否相等。然后,可以将这个比较函数传递给

std::unique
函数。或者,重载
==
运算符。

例如:

#include 
#include 
#include 

struct Point {
    int x;
    int y;

    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
};

int main() {
    std::vector arr = {{1, 2}, {1, 2}, {3, 4}, {5, 6}, {5, 6}};

    auto it = std::unique(arr.begin(), arr.end());
    arr.erase(it, arr.end());

    for (const auto& p : arr) {
        std::cout << "(" << p.x << ", " << p.y << ") ";
    }
    std::cout << std::endl;

    std::cout << "去重后的数组长度: " << arr.size() << std::endl;

    return 0;
}

如果对象或结构体没有重载

==
运算符,则需要提供一个自定义的比较函数,并将其传递给
std::unique

#include 
#include 
#include 

struct Point {
    int x;
    int y;
};

bool comparePoints(const Point& a, const Point& b) {
    return a.x == b.x && a.y == b.y;
}

int main() {
    std::vector arr = {{1, 2}, {1, 2}, {3, 4}, {5, 6}, {5, 6}};

    auto it = std::unique(arr.begin(), arr.end(), comparePoints);
    arr.erase(it, arr.end());

    for (const auto& p : arr) {
        std::cout << "(" << p.x << ", " << p.y << ") ";
    }
    std::cout << std::endl;

    std::cout << "去重后的数组长度: " << arr.size() << std::endl;

    return 0;
}

原地操作的局限性与替代方案

原地操作虽然节省了内存,但它直接修改了原始数组,这在某些情况下可能不合适。如果需要保留原始数组,可以先创建一个副本,然后在副本上进行去重操作。此外,如果数组非常大,原地操作可能会导致性能问题,因为需要频繁地移动元素。在这种情况下,可以考虑使用其他算法,例如哈希表,或者使用外部排序。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

224

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

85

2025.10.17

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

379

2023.09.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

186

2025.07.04

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

389

2023.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

44

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.7万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号