代码小记

1. sql中提取表名,以下代码为查询语句中提取表名。其他提取表名情况,可以根据需要添加key中key值。

点击查看代码
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <ctime>
using namespace std;


// select * from v$user_tables
// select * from ( select * from tables where table_name = '0000' ) v, t;
// select * from select * from tables;
// 0 str text
// 1 开始收集字符
// 2 之前收集界定符
// 3 结束或非收集标记
// 4 忽略字符标记
// 5 用户自定义字符串标识符

// 100 字符关联对

enum KeyType {
    Literal,
    CollectStart,
    CollectSplit,
    CollectEnd,
    Hidden,
    AssocChar = 100,         // associated character type
};

const std::string sym = ",()=;"; // 手动补加前后空格标记

const std::map<std::string, int> key = {
    {"from", KeyType::CollectStart},
    {"join", KeyType::CollectStart},
    {"all", KeyType::CollectStart},
    
    {",", KeyType::CollectSplit},

    {"select", KeyType::CollectEnd},
    {"left", KeyType::CollectEnd},
    {"inner", KeyType::CollectEnd},
    {"on", KeyType::CollectEnd},
    {"where", KeyType::CollectEnd},
    {"right", KeyType::CollectEnd},
    {"group", KeyType::CollectEnd},
    {"having", KeyType::CollectEnd},
    {"by", KeyType::CollectEnd},
    {"order", KeyType::CollectEnd},

    {"as", KeyType::Hidden},

    {"(", KeyType::AssocChar},
    {")", KeyType::AssocChar + 1},

    // 每组KeyType::AssocChar之间要存在距离
    // {"{", KeyType::AssocChar + 3},
    // {"}", KeyType::AssocChar + 4},
};

std::vector<std::string> GetTables(const std::string& s) {
    std::string str;
    for (int i = 0; i < s.size(); ++ i) {
        if (sym.find(s[i]) != -1) str += std::string(" ") + static_cast<char>(tolower(s[i])) + " ";
        else str += static_cast<char>(tolower(s[i]));
    }
    std::stringstream ss(str);
    std::vector<std::pair<int, std::string>> ps;

    std::string ts;
    while (ss >> ts) {
        if (key.count(ts)) ps.push_back({key.at(ts), ts});
        else ps.push_back({0, ts});
    }

    std::vector<int> dp(ps.size(), false);
    std::stack<int> stk;
    for (int i = 1; i < ps.size(); ++ i) {
        if (ps[i].first >= KeyType::AssocChar) {
            if (stk.empty() || ps[stk.top()].first + 1 != ps[i].first) {
                stk.push(i);
            } else {
                int top = stk.top();
                stk.pop();
                ps[i].first = ps[top - 1].first;
            }
        } else {
            dp[i] = ps[i - 1].first == KeyType::CollectStart && 
                    (!key.count(ps[i - 1].second) || key.at(ps[i - 1].second) < KeyType::AssocChar) &&
                    !ps[i].first && !dp[i - 1];
            if (!ps[i].first || ps[i].first == KeyType::CollectSplit) {
                ps[i].first = ps[i - 1].first == KeyType::Hidden ? ps[i - 2].first : ps[i - 1].first;
            }
        }
    }
    std::vector<std::string> tables;

#ifdef _DEBUG
    for (int i = 0; i < ps.size(); ++ i)
        std::cout << dp[i] << ' ' << ps[i].first << ' ' << ps[i].second << std::endl;
#endif

    for (int i = 0; i < ps.size(); ++ i)
        if (dp[i])
            tables.push_back(ps[i].second);
    std::sort(tables.begin(), tables.end());
    tables.erase(unique(tables.begin(), tables.end()), tables.end());

#ifdef _DEBUG
    for (auto t: tables)
        std::cout << t << std::endl;
    std::cout << "===============" << std::endl;
#endif
    return tables;
}

void FillStr(std::string& str) {
    bool flag = false;
    for (int pos = str.size(); ~pos; -- pos) {
        if (str[pos] == '\'' && (!pos || str[pos - 1] != '\\')) flag = !flag;
        if (flag) str[pos] = '0';
    }
}

std::string RemoveNewLine(const std::string& sql) {
    std::stringstream ss(sql);
    std::string ans, tmpstr;
    while (std::getline(ss, tmpstr)) ans += tmpstr;
    return ans;
}

std::vector<std::string> GetTablesFromSql(const std::string& sql) {
    std::string str = RemoveNewLine(sql);
    FillStr(str);
    return GetTables(str);
}

void PrintTables(const std::string& sql) {
    std::vector<std::string> args = GetTablesFromSql(sql);
#ifndef _DEBUG
    std::cout << sql << std::endl;
    for (auto tbl : args) std::cout << tbl << std::endl;
    std::cout << std::endl;
#endif
}

int main() {
    std::string sql = "select * from user_tables;";
    PrintTables(sql);
    sql = "select * from (select t from t_id) tid, rid;";
    PrintTables(sql);
    return 0;
}

2. c++模板实现基于量纲的数值计算。

点击查看代码
#include <iostream>
#include <tuple>

struct IntType;

template<int N>
struct Int {
    static const int value = N;
    typedef IntType typetype;
    typedef Int type;

    template<typename T>
    auto operator+(const T& t) const -> Int<T::value + value> {
        static_assert(std::is_same<typetype, typename T::typetype>::value, "type is different");
        return Int<T::value + value>();
    }

    template<typename T>
    auto operator-(const T& t) const -> Int<T::value - value> {
        static_assert(std::is_same<typetype, typename T::typetype>::value, "type is different");
        return Int<T::value - value>();
    }
};

template<typename T, typename Dimensions>
struct tquantity {
    typedef Dimensions type;
    typedef T value_type;

    explicit tquantity(T x) : value_(x) {}
    const T& value() const { return value_; }

private:
    T value_;
};

typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>> tscalar;
typedef std::tuple<Int<1>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>> tmass;
typedef std::tuple<Int<0>, Int<1>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>> tlength;
typedef std::tuple<Int<0>, Int<0>, Int<1>, Int<0>, Int<0>, Int<0>, Int<0>> ttime;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<1>, Int<0>, Int<0>, Int<0>> tcharge;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<1>, Int<0>, Int<0>> ttemperature;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<1>, Int<0>> tintensity;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<1>> tamount_of_substance;
typedef std::tuple<Int<0>, Int<1>, Int<-1>, Int<0>, Int<0>, Int<0>, Int<0>> tvelocity;
typedef std::tuple<Int<0>, Int<1>, Int<-2>, Int<0>, Int<0>, Int<0>, Int<0>> tacceleration;
typedef std::tuple<Int<1>, Int<1>, Int<-1>, Int<0>, Int<0>, Int<0>, Int<0>> tmomentum;
typedef std::tuple<Int<1>, Int<1>, Int<-2>, Int<0>, Int<0>, Int<0>, Int<0>> tforce;

template<typename T = tscalar, typename D = tscalar>
struct DimensionsBinaryOperatorPlus {
    // static_assert(
    //         std::is_same<typename decltype(std::get<0>(T()))::typetype, typename decltype(std::get<0>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<1>(T()))::typetype, typename decltype(std::get<1>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<2>(T()))::typetype, typename decltype(std::get<2>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<3>(T()))::typetype, typename decltype(std::get<3>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<4>(T()))::typetype, typename decltype(std::get<4>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<5>(T()))::typetype, typename decltype(std::get<5>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<6>(T()))::typetype, typename decltype(std::get<6>(D()))::typetype>::value,
    //         "DimensionsBinaryOperatorPlus typetype is different");
    typedef std::tuple<
        decltype(std::get<0>(T()) + std::get<0>(D())),
        decltype(std::get<1>(T()) + std::get<1>(D())),
        decltype(std::get<2>(T()) + std::get<2>(D())),
        decltype(std::get<3>(T()) + std::get<3>(D())),
        decltype(std::get<4>(T()) + std::get<4>(D())),
        decltype(std::get<5>(T()) + std::get<5>(D())),
        decltype(std::get<6>(T()) + std::get<6>(D()))
        > type;
};

template<typename T = tscalar, typename D = tscalar>
struct DimensionsBinaryOperatorMinus {
    // static_assert(
    //         std::is_same<typename decltype(std::get<0>(T()))::typetype, typename decltype(std::get<0>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<1>(T()))::typetype, typename decltype(std::get<1>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<2>(T()))::typetype, typename decltype(std::get<2>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<3>(T()))::typetype, typename decltype(std::get<3>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<4>(T()))::typetype, typename decltype(std::get<4>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<5>(T()))::typetype, typename decltype(std::get<5>(D()))::typetype>::value &&
    //         std::is_same<typename decltype(std::get<6>(T()))::typetype, typename decltype(std::get<6>(D()))::typetype>::value,
    //         "DimensionsBinaryOperatorMinus typetype is different");
    typedef std::tuple<
        decltype(std::get<0>(T()) - std::get<0>(D())),
        decltype(std::get<1>(T()) - std::get<1>(D())),
        decltype(std::get<2>(T()) - std::get<2>(D())),
        decltype(std::get<3>(T()) - std::get<3>(D())),
        decltype(std::get<4>(T()) - std::get<4>(D())),
        decltype(std::get<5>(T()) - std::get<5>(D())),
        decltype(std::get<6>(T()) - std::get<6>(D()))
        > type;
};

template<typename T = tscalar, typename D = tscalar, typename BinaryOperator = DimensionsBinaryOperatorPlus<T, D>>
struct DimensionsTypeOperator {
    typedef typename BinaryOperator::type type;
};

template<typename T1, typename T2>
tquantity<typename T1::value_type, typename T1::type> operator+(const T1& lhs, const T2& rhs) {
    static_assert(std::is_same<typename T1::type, typename T2::type>::value, "T1::type must be same as T2::type");
    return tquantity<typename T1::value_type, typename T1::type>(lhs.value() + rhs.value());
}

template<typename T1, typename T2>
tquantity<typename T1::value_type, typename T1::type> operator-(const T1& lhs, const T2& rhs) {
    static_assert(std::is_same<typename T1::type, typename T2::type>::value, "T1::type must be same as T2::type");
    return tquantity<typename T1::value_type, typename T1::type>(lhs.value() - rhs.value());
}

template<typename T1, typename T2>
tquantity<typename T1::value_type, typename DimensionsTypeOperator<typename T1::type, typename T2::type>::type>
operator*(const T1& lhs, const T2& rhs) {
    typedef typename DimensionsTypeOperator<typename T1::type, typename T2::type>::type type;
    return tquantity<typename T1::value_type, type>(lhs.value() + rhs.value());
}

template<typename T1, typename T2>
tquantity<typename T1::value_type,
    typename DimensionsTypeOperator<typename T1::type, typename T2::type,
        DimensionsBinaryOperatorMinus<typename T1::type, typename T2::type>>::type>
operator/(const T1& lhs, const T2& rhs) {
    typedef typename DimensionsTypeOperator<typename T1::type, typename T2::type,
        DimensionsBinaryOperatorMinus<typename T1::type, typename T2::type>>::type type;
    return tquantity<typename T1::value_type, type>(lhs.value() / rhs.value());
}

void quantity_test() {
    tquantity<float, tmass> m(0.5f);
    tquantity<float, tacceleration> a(9.8f);
    tquantity<float, tforce> f = m * a;
    std::cout << "operator + test:" << (m + m).value() << std::endl;
    std::cout << "operator - test:" << (m - m).value() << std::endl;
    std::cout << "operator * test:" << (m * a).value() << std::endl;
    std::cout << "operator / test:" << (m / a).value() << std::endl;
}

int main() {
    quantity_test();
    return 0;
}

3. c++元编程实现编译期堆排序。

点击查看代码
#include <iostream>
#include <type_traits>

using namespace std;

#if __cplusplus <= 201103L
template< bool B, class T, class F >
using conditional_t = typename conditional<B,T,F>::type;
#endif

template<typename T>
struct DelayCalcType {
    using type = T;
};

template<int ... N> struct seq {};

template<typename T1, typename T2, int pos> struct split;

template<int F, int ... N1, int ... N2>
struct split<seq<F, N1...>, seq<N2...>, 0> {
    using second = seq<N1...>;
    using first = seq<N2...>;
    using mid = seq<F>;
};

template<int F, int ... N1, int ... N2, int pos>
struct split<seq<F, N1...>, seq<N2...>, pos> : split<seq<N1...>, seq<N2..., F>, pos - 1> {};

template<typename T1, typename T2> struct merge;

template<int ... N1, int ... N2>
struct merge<seq<N1...>, seq<N2...>> {
    using type = seq<N1..., N2...>;
};

template<typename T, int pos> struct get;

template<int F, int ... N>
struct get<seq<F, N...>, 0> {
    static constexpr int value = F;
};

template<int F, int ... N, int pos>
struct get<seq<F, N...>, pos> {
    static constexpr int value = get<seq<N...>, pos - 1>::value;
};

template<int l, int r, typename T> struct seq_swap;
template<int l, int ... N>
struct seq_swap<l, l, seq<N...>> {
    using type = seq<N...>;
};

template<int l, int r, int ... N>
struct seq_swap<l, r, seq<N...>> {
private:
    using ltype = split<seq<N...>, seq<>, l>;
    using ltype1 = typename ltype::first;
    using ltype2 = typename ltype::mid;
    
    using rtype = split<typename ltype::second, seq<>, r - l - 1>;
    using rtype1 = typename rtype::first;
    using rtype2 = typename rtype::mid;
    
    using etype = typename rtype::second;

public:
    using type =
        typename merge<
            typename merge<
                typename merge<ltype1, rtype2>::type,
                typename merge<rtype1, ltype2>::type
            >::type,
            etype
        >::type;
};

template<typename T, int pos> struct up;

template<int ... N>
struct up<seq<N...>, 0> {
    using type = seq<N...>;
};

template<int pos, int ... N>
struct up<seq<N...>, pos> {
    using type = conditional_t<get<seq<N...>, (pos - 1) / 2>::value <= get<seq<N...>, pos>::value, seq<N...>,
        typename up<typename seq_swap<(pos - 1) / 2, pos, seq<N...>>::type, (pos - 1) / 2>::type>;
};

template<typename T, int pos, int epos> struct down;

template<int ... N, int pos>
struct down<seq<N...>, pos, pos> {
    using type = seq<N...>;
};

template<typename T, int l, int r> struct get_pos;

template<int ... N, int l, int r>
struct get_pos<seq<N...>, l, r> {
    static constexpr int value = get<seq<N...>, l>::value <= get<seq<N...>, r>::value ? l : r;
};

template<int pos, int p2, int epos, typename T> struct delay_down;

template<int pos, int p2, int epos, int ... N>
struct delay_down<pos, p2, epos, seq<N...>> {
    using type = typename down<
            typename seq_swap<pos, p2, seq<N...>>::type,
            p2, epos
        >::type;
};

template<int ... N, int pos, int epos>
struct down<seq<N...>, pos, epos> {
// private:
    static constexpr int p = pos;
    using pt1 = conditional_t<pos * 2 + 1 < epos,
        DelayCalcType<get_pos<seq<N...>, pos, pos * 2 + 1>>,
        DelayCalcType<get<seq<pos>, 0>>>;
    static constexpr int p1 = pt1::type::value;
    using pt2 = conditional_t<pos * 2 + 2 < epos,
        DelayCalcType<get_pos<seq<N...>, pos * 2 + 2, p1>>,
        DelayCalcType<get<seq<p1>, 0>>>;
    static constexpr int p2 = pt2::type::value;
public:
    using type = typename conditional_t<
        pos == p2,
        DelayCalcType<seq<N...>>,
        delay_down<pos, p2, epos, seq<N...>>
    >::type;
};

template<typename T, int pos, int epos> struct build;

template<int ... N, int epos>
struct build<seq<N...>, 0, epos> {
    using type = typename down<seq<N...>, 0, epos>::type;
};

template<int ... N, int pos, int epos>
struct build<seq<N...>, pos, epos> {
private:
    using ttype = typename down<seq<N...>, pos, epos>::type;

public:
    using type = typename build<ttype, pos - 1, epos>::type;
};

template<typename T, typename ans, int epos, bool build_flg = false> struct heap_sort;

template<int F, int ... N, int ... C, bool flg>
struct heap_sort<seq<F, N...>, seq<C...>, 0, flg> {
    using type = seq<C...>;
    using type1 = seq<F, N...>;
};

template<int F, int ... N, int ... C, int epos, bool flg>
struct heap_sort<seq<F, N...>, seq<C...>, epos, flg> {
private:
    using ttype = typename
        conditional_t<flg == false, build<seq<F, N...>, epos - 1, epos>, DelayCalcType<seq<F, N...>>>::type;
    using ttype1 = seq<C..., get<ttype, 0>::value>;
    using ttype2 = typename seq_swap<0, epos - 1, ttype>::type;
    using ttype3 = typename down<ttype2, 0, epos - 1>::type;

public:
    using type = typename heap_sort<ttype3, ttype1, epos - 1, true>::type;
    using type1 = typename heap_sort<ttype3, ttype1, epos - 1, true>::type1;
};

template<int ...N>
void print(const seq<N...>&) {
    static int args[] = {N...};
    for (int i = 0; i < sizeof args / sizeof(int); ++i)
        cout << args[i] << ' ';
    cout << endl;
}


int main() {
    seq<3, 6, 7, 4, 2, 8, 1> s;
    cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 0>::value << endl;
    cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 1>::value << endl;
    cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 2>::value << endl;
    cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 3>::value << endl;
    cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 4>::value << endl;
    cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 5>::value << endl;
    // split<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 3>
    print(split<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 3>::first());
    print(split<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 3>::second());
    cout << "----" << endl;
    print(seq<3, 6, 7, 4, 2, 8, 1>());
    print(seq_swap<1, 5, seq<3, 6, 7, 4, 2, 8, 1>>::type());
    print(up<seq<3, 6, 7, 4, 2, 8, 1>, 3>::type());
    print(down<seq<13, 6, 7, 4, 2, 8, 1>, 1, 7>::type());
    // print(build<seq<13, 6, 7, 4, 2, 8, 1>, 6, 7>::ttype());
    // print(build<seq<13, 6, 7, 4, 2, 8, 1>, 5, 7>::ttype());
    // print(build<seq<13, 6, 7, 4, 2, 8, 1>, 4, 7>::ttype());
    // print(build<seq<13, 6, 7, 4, 2, 8, 1>, 3, 7>::ttype());
    // print(build<seq<13, 6, 7, 4, 2, 8, 1>, 2, 7>::ttype());
    // print(build<seq<13, 6, 7, 4, 2, 8, 1>, 1, 7>::ttype());
    print(build<seq<13, 6, 7, 4, 2, 8, 1>, 6, 7>::type());
    cout << down<seq<13, 6, 7, 4, 2, 8, 1>, 1, 7>::p1 << ' ' << down<seq<13, 6, 7, 4, 2, 8, 1>, 3, 7>::p2 << endl;
    
    cout << "----" << endl;
    cout << "final test" << endl;
    print(heap_sort<seq<13, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type());
    print(heap_sort<seq<13, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type1());
    print(heap_sort<seq<5, 7, 4, 2, 8, 6, 1, 9, 0, 3>, seq<>, 10, false>::type());
    print(heap_sort<seq<5, 7, 4, 2, 8, 6, 1, 9, 0, 3>, seq<>, 10, false>::type1());
    print(heap_sort<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type());
    print(heap_sort<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type1());

    return 0;
}
posted @ 2022-04-24 23:41  楓羽  阅读(19)  评论(0编辑  收藏  举报