C++字符串对分类实现

键盘侠 2022年04月06日 1,298次浏览

目的

将一个字符串对数组进行两两拉通配对进行分类,例如:
[(a,b),(c,d),(e,f),(g,h),(j,k),(a,j),(h,c),(k,e),(x,y)] 这个数组
分类后为:
a,b + a,j + j,k + k,e + e,f --> (a,b,j,k,e,f)
c,d + h,c + g,h --> (c,d,h,g)
x,y --> (x,y)
所以最终结果为:
[(a,b,j,k,e,f),(c,d,h,g),(x,y)]

实现

新建cmake工程:

cmake_minimum_required(VERSION 3.21)
project(testDemo)

set(CMAKE_CXX_STANDARD 20)

link_directories(/usr/local/lib)

file(GLOB BASE_H_FILES ./base/*.h)
file(GLOB BASE_CPP_FILES ./base/*.cpp)
set(BASE_FILES ${BASE_H_FILE} ${BASE_CPP_FILES})
add_library(base ${BASE_FILES})

add_executable(testDemo main.cpp)

set(WORKLOADLIBRARIES base)

target_link_libraries(testDemo -Wl,--start-group ${WORKLOADLIBRARIES})

定义头文件

#ifndef TEST_CONTAINERDEMO_H
#define TEST_CONTAINERDEMO_H
/**************************************************************** 
* @Copyright:   Copyright(c) 2022
* @Author:      wudl
* @CreateDate:  2022/3/16
* @LastDate:    2022/3/16 
* @version      1.0.0.1  
* @Description: 申明头文件
******************************************************************/

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

using namespace std;

namespace base {

    /**
     * @author:wudl
     * @brief: 字符串对的结构
     */
    struct pairStr {
        string s1;
        string s2;
    };

    /***
     * @author: wudl
     * @brief: 生成指定大小的随机字符串
     * @param count
     * @return
     */
    vector<pairStr> generatePair(const int &count);

    /***
     * @author: wudl
     * @brief: 生成指定长度的字符串对
     * @param count
     * @return
     */
    string generateStr(const int &count);

    /***
     * @author: wudl
     * @brief: 将多组字符串进行分类
     * @param ps
     * @return
     */
    bool groupStr(vector<pairStr> &ps, vector<vector<string>> &rs);

    /***
     * @author: wudl
     * @brief:
     *  判断一个字符串是否在一个数组里
     * @param vecStr
     * @param str
     * @return
     */
    bool strInVector(const vector<string> &vecStr, const string &str);
}


#endif //TEST_CONTAINERDEMO_H

实现方法

/****************************************************************
* @Copyright:   Copyright(c) 2022
* @Author:      wudl
* @CreateDate:  2022/3/16
* @LastDate:    2022/3/16 
* @version      1.0.0.1  
* @Description: 功能实现
******************************************************************/

#include "ContainerDemo.h"

using std::default_random_engine;
using std::random_device;
using std::string;


string base::generateStr(const int &count) {
    char tmp;
    string buffer;
    random_device rd;
    default_random_engine dre(rd());

    for (int i = 0; i < count; i++) {
        tmp = dre() % 36;
        if (tmp < 10)
            tmp += '0';
        else {
            tmp -= 10;
            tmp += 'A';
        }
        buffer += tmp;
    }
    return buffer;
}

vector<base::pairStr> base::generatePair(const int &count) {
    vector<base::pairStr> rs;
    for (int i = 0; i < count; i++) {
        base::pairStr ps;
        ps.s1 = base::generateStr(16);
        ps.s2 = base::generateStr(16);
        rs.emplace_back(ps);
    }
    return rs;
}

bool base::groupStr(vector<pairStr> &ps, vector<vector<string>> &rs) {
    if (ps.empty())
        return false;
    vector<string> ids;
    ids.insert(ids.end(), ps.begin()->s1);
    ids.insert(ids.end(), ps.begin()->s2);
    rs.insert(rs.end(), ids);
    ids.clear();
    ps.erase(ps.begin());
    if (ps.empty())
        return true;

    auto rs_it = rs.begin();
    while (rs_it != rs.end()) {
        auto ps_it = ps.begin();
        while (ps_it != ps.end()) {
            bool s1InIds = strInVector(*rs_it, ps_it->s1);
            bool s2InIds = strInVector(*rs_it, ps_it->s2);
            if (s1InIds && s2InIds)
                ps_it = ps.erase(ps_it);
            else if (s1InIds) {
                rs_it->insert(rs_it->end(), ps_it->s2);
                ps.erase(ps_it);
                ps_it = ps.begin();
            } else if (s2InIds) {
                rs_it->insert(rs_it->end(), ps_it->s1);
                ps.erase(ps_it);
                ps_it = ps.begin();
            } else
                ps_it++;
        }
        if (!ps.empty()) {
            ids.insert(ids.end(), ps.begin()->s1);
            ids.insert(ids.end(), ps.begin()->s2);
            rs_it = rs.insert(rs.end(), ids);
            ids.clear();
            ps.erase(ps.begin());
        } else
            rs_it++;
    }

    return true;
}

bool base::strInVector(const vector<string> &vecStr, const string &str) {
    return any_of(vecStr.begin(), vecStr.end(), [&](const string &s) { return s == str; });
}

main方法来测试 一把

#include <iostream>

#include "base/ContainerDemo.h"

using namespace std;

int main() {

    vector<base::pairStr> tmp = base::generatePair(50);
    cout << tmp.size() << endl;

    for (int i = 0; i < 10; i++) {
        tmp.emplace_back(tmp.at(i));
    }

    for (const auto &p: tmp)
        cout << p.s1 << "," << p.s2 << endl;

    cout << tmp.size() << endl;

    vector<vector<string>> rs;
    base::groupStr(tmp, rs);

    cout << rs.size() << endl;
    for (const auto &sub: rs) {
        cout << sub.size() << ",";
    }

    return 0;
}