You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++实现:查找Route数组中出现频率最高的5个Address

解决思路:统计并排序Address出现频率

要找出Route数组中出现频率最高的5个Address,核心步骤是统计每个Address的出现次数,然后按频率排序取前5。下面一步步拆解实现方法:

1. 先确保Address可以被正确比较(关键前提)

因为我们需要把Address作为键存入哈希表或有序map来计数,所以必须让C++能够判断两个Address是否相等,以及(如果用std::map的话)比较两个Address的大小。

我们需要给Address和Location类重载必要的运算符:

  • 重载==:判断两个Address是否相同(通常要比较包含的Location以及其他地址属性,比如街道、城市等)
  • 重载<:如果用std::map的话需要,用来排序键;如果用std::unordered_map,则需要自定义哈希函数(后面会给出两种方案)

2. 遍历所有Route,统计Address出现次数

创建一个计数容器(比如std::map<Address, int>或者std::unordered_map<Address, int>),然后遍历每个Route里的每一个Address,每遇到一次就把对应计数加1。

3. 将统计结果排序,取前5个

把计数容器里的键值对转换成std::vector<std::pair<Address, int>>,然后自定义排序规则,按计数从大到小排序。最后取前5个元素即可。


完整代码示例

先补全你的类定义,然后实现统计逻辑:

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <string>

// Location类:包含经纬度等位置信息
class Location {
public:
    double lat;
    double lng;

    Location(double lat_, double lng_) : lat(lat_), lng(lng_) {}

    // 重载==,判断两个Location是否相同
    bool operator==(const Location& other) const {
        // 考虑浮点数精度,这里简化直接比较,实际项目可以加误差范围(比如1e-9)
        return lat == other.lat && lng == other.lng;
    }

    // 重载<,用于std::map的排序
    bool operator<(const Location& other) const {
        if (lat != other.lat) return lat < other.lat;
        return lng < other.lng;
    }
};

// Address类:包含Location和其他地址属性
class Address {
public:
    Location loc;
    std::string street;
    std::string city;

    Address(Location loc_, std::string street_, std::string city_)
        : loc(loc_), street(street_), city(city_) {}

    // 重载==,判断两个Address是否相同
    bool operator==(const Address& other) const {
        return loc == other.loc && street == other.street && city == other.city;
    }

    // 重载<,用于std::map的排序
    bool operator<(const Address& other) const {
        if (!(loc == other.loc)) return loc < other.loc;
        if (street != other.street) return street < other.street;
        return city < other.city;
    }
};

// Route类:包含Address数组(这里用vector更灵活)
class Route {
public:
    std::vector<Address> addresses;

    Route(std::vector<Address> addrs_) : addresses(addrs_) {}
};

int main() {
    // 测试数据:创建几个Route对象
    Location loc1(39.9042, 116.4074); // 北京天安门
    Location loc2(31.2304, 121.4737); // 上海外滩
    Address addr1(loc1, "天安门广场", "北京市");
    Address addr2(loc2, "中山东一路", "上海市");
    Address addr3(loc1, "东长安街", "北京市");

    Route route1({addr1, addr2, addr1});
    Route route2({addr2, addr3, addr1, addr2});
    Route route3({addr3, addr1, addr2, addr3});

    std::vector<Route> routes = {route1, route2, route3};

    // 步骤1:统计每个Address的出现次数
    std::map<Address, int> addrCount;
    for (const auto& route : routes) {
        for (const auto& addr : route.addresses) {
            addrCount[addr]++;
        }
    }

    // 步骤2:将统计结果转换为vector并排序
    std::vector<std::pair<Address, int>> countVec(addrCount.begin(), addrCount.end());
    // 按出现次数从高到低排序,如果次数相同,按Address排序(可选)
    std::sort(countVec.begin(), countVec.end(), [](const auto& a, const auto& b) {
        if (a.second != b.second) {
            return a.second > b.second;
        }
        return a.first < b.first;
    });

    // 步骤3:输出前5个频率最高的Address
    std::cout << "出现频率最高的5个Address:\n";
    int take = std::min(5, (int)countVec.size());
    for (int i = 0; i < take; ++i) {
        const auto& pair = countVec[i];
        std::cout << "Address: " << pair.first.street << ", " << pair.first.city 
                  << " | 出现次数: " << pair.second << "\n";
    }

    return 0;
}

可选:用std::unordered_map优化性能

如果你的Address数量很大,std::unordered_map的查找和插入效率更高,但需要自定义哈希函数。可以给Address添加哈希特化:

#include <functional>

// 为Location自定义哈希
namespace std {
    template<> struct hash<Location> {
        size_t operator()(const Location& loc) const {
            // 组合lat和lng的哈希值,这里用简单的方法,实际可以用更稳健的哈希组合
            size_t h1 = hash<double>()(loc.lat);
            size_t h2 = hash<double>()(loc.lng);
            return h1 ^ (h2 << 1);
        }
    };

    // 为Address自定义哈希
    template<> struct hash<Address> {
        size_t operator()(const Address& addr) const {
            size_t h1 = hash<Location>()(addr.loc);
            size_t h2 = hash<string>()(addr.street);
            size_t h3 = hash<string>()(addr.city);
            return h1 ^ (h2 << 1) ^ (h3 << 2);
        }
    };
}

然后把统计部分的std::map换成std::unordered_map即可,其他逻辑不变。

注意事项

  • 浮点数比较:如果Location的lat/lng是浮点数,直接用==可能有精度问题,建议改成判断两个值的差小于某个极小值(比如1e-9)。
  • 自定义排序:如果两个Address出现次数相同,可以根据业务需求调整排序规则(比如按地址名称排序)。
  • 边界情况:如果总共有少于5个不同的Address,就输出全部即可,代码里用std::min(5, (int)countVec.size())处理了这种情况。

内容的提问来源于stack exchange,提问作者Robert1428

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:26:21