• 【POJ 1200】Crazy Search(将字符映射为数字,将NC进制hash成10进制)


    题目链接

    题目链接 http://poj.org/problem?id=1200

    题意

    原字符串有NC个不同字母,统计原字符串长度为N的子字符串个数

    解题思路

    1. 将字符按ASCII码映射成数字。
    2. 将n个字符,即n位NC进制拼起来。
    3. 将拼起来的n位NC进制转化为10进制。
    4. 将10进制映射入hash表,每次映射判断是否已经存在。
      若不存在,则ans++;否则将hash设置为存在

    如何将子串(n位NC进制)映射为10进制

    a = 0

    b = 1

    c = 2

    cbaa = 2 * 3^3 + 1 * 3^2 + 0 * 3^1 + 0 * 3^0

    abcc = 0 * 3^3 + 1 * 3^2 + 2 * 3^1 + 2 * 3^0

    时间复杂度

    本题用的是map红黑树,查找插入时间为log(NC)

    时间复杂度O(mlog(NC))

    m为原字符串长度(题中并未给出),NC为进制数

    代码如下(G++)

    #include <iostream>
    #include <string.h>
    #include "map"
    #include "string"
    
    using namespace std;
    typedef long long ll;
    double eps = 1e-7;
    
    // 将字符的ASCII码映射成整型
    map <char, int> m;
    
    // 将字符串子串按nc进制转化为10进制存入
    bool hashs[16000010];
    
    int main() {
        ios::sync_with_stdio(false);
        int nc,n;
        string s;
        while(cin >> n >> nc >> s){
            // 初始化
            memset(hashs,false, sizeof(hashs));
            m.clear();
            // 将字符映射为整型
            int cnt = 0;
            for(int i = 0;s[i]; ++i){
                if(m.find(s[i]) == m.end())
                    m[s[i]] = cnt++;
            }
    
            int ans = 0;
            for(int i = 0;i <= s.length()-n;++i){
                // 将字符串s[i...i+n-1]的NC进制数转化为10进制
                int p = 0;
                for(int j =i;j < i+n;++j){
                    p = p*nc+m[s[j]];
                }
                // 判断10进制是否存在,若存在则表示原字符串已经计数过一次
                if(!hashs[p]){
                    ++ans;
                    hashs[p] = true;
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    CriminalIntent项目开发笔记(二)
    CriminalIntent项目开发笔记(一)----动态添加Fragment
    android应用中去掉标题栏的方法
    15个IT程序员必须思考的问题
    Android Studio快捷键
    Android 学习笔记
    win7系统安装方法
    jquery随学随记
    接口功能测试策略--转载
    测试随笔
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/11474022.html
Copyright © 2020-2023  润新知