zoukankan      html  css  js  c++  java
  • 超长字符串

    一、问题描述

        给定一个字符串S:123456789101112131415161718192021...它是由所有自然数从小到大依次排列起来的。任意给一个数字串S1,绒衣知道它一定在S中出现多次。编程出它第一次出现的位置。例如对于串“81”,它最先出现的位置为27。

    二、算法描述

         分四种情况:

      (1)字串是连续的若干个数组成的,如12131415 是由12,13,14,15的连续数字组成的,搜索的最小数字位置为n=12的第一位,偏移为0

      (2)字串的前后有一部分子串相同,如1234567123 ,前三个数和后三个数都是123。则n=1234567是要搜索的最小数字,偏移为0

      (3)字串的前后有一部分子串,后一个比前一个多1,如123454124。前三个数是123,后三个数是124,则最小搜索数字是n=454124(去掉最开始的三个数),偏移为-3

      (4)没有出现上述三种情况,如1123129,则最小的搜索数为n=9112312,偏移为1。

          上诉的偏移是指搜索到数字n首位出现的位置在加上偏移,就等于最终要求得的结果。

    三、代码实现

    #include<iostream>
    #include<string>
    using namespace std;
    //将字符串翻译成数字
    int str2int(string str){
        int t=0;
        for(int i=0;i<str.size();i++){
            t=t*10+(str[i]-'0');
        }
        return t;
    }
    int check9s(string str){
        for(int i=0;i<str.size();i++){
            if(str[i]!='9'){
                return 0;
            }
        }
        return 1;
    }
    //首先考虑数字是否是m位连续的数字组成如(111213,最先出现的位置11, 12, 13串位置)
    int continueStrSearch(string str){
    
        for(int i=1;i<=str.size()/2;i++){
            int startNum=0;
            int curNum=0;
            int preNum=0;
            int cursor=0;
            int span=i;
            int flag=1;
            while(cursor<str.size()){
    
                preNum=curNum;
                string subs=str.substr(cursor,span);
                //cout<<"subs="<<subs<<endl;
                curNum=str2int(subs);
                if(cursor==0){
                    startNum=curNum;
                }else if(preNum+1!=curNum){
                    flag=0;
                    break;
                }
                cursor+=span;
                if(check9s(subs)){
                    span++;
                }
                
                //cout<<span<<endl;
            }
            if(flag==1){
                return startNum;
            }
                
        }
        return -1;
    }
    
    struct reS{
        int minNum;
        int off;
    };
    //找到最小的数和偏移
    reS findP(string str){
        reS res;
        int minNum=0;
        int flag=0;
        int m=0;
        int n=str.size();
        //找到一个数前m位和后m位相等或后比前大1的最大位置 如 1234123 返回3 13814 返回2 121212 返回1
        for(int i=1;i<str.size()/2;i++){
            int f=1;
            for(int j=0;j<i;j++){
                if(str[j]!=str[n-i-1+j]){
                    f=0;
                }
            }
            if(f==1){
                m=i;
                if(str[i]==str[n-1]){
                    flag=1;
                }else if(str[i]+1==str[n-1]){
                    flag=2;
                }
            }
        }
        string s;
        //找到最小的数
        if(flag==0){
            
            s.push_back(str.back());
            s=s+str.substr(0,str.size()-1);
            res.off=1;
        }else if(flag==1){
            s=str.substr(0,str.size()-(m+1));
            res.off=0;
            
        }else if(flag==2){
            s=str.substr(m+1,str.size()-(m+1));
            res.off=-(m+1);
        }
        minNum=str2int(s);
        res.minNum=minNum;
        
        return res;
        
    }
    int minPos(reS res){
        int t=10;
        //cout<<res.minNum<<" "<<res.off<<endl;
        int num=res.minNum-1;
        int posNum=num+1;
        int off=res.off;
        while(num/t){
            posNum+=(num-t+1);
            t=t*10;
        }
        posNum=posNum+off;
        return posNum;
    }
    
    //计算这个字串的范围(即可能出现在两个数字之间)
    int main(){
        
        while(1){
            cout<<"输入数字字符串:"<<endl;
            string numStr;
            cin>>numStr;
            reS res;
            int startNum;
            int t=continueStrSearch(numStr);
            if(t!=-1){
                startNum=t;
                res.minNum=t;
                res.off=0;
            }else{
                res=findP(numStr);
                startNum=res.minNum;
            }
            int minpos=minPos(res);
            cout<<"minNum="<<res.minNum<<" off="<<res.off<< " minPos="<<minpos<<endl;
        }
        
        system("pause");
        return 0;
    }

     四、运行结果

  • 相关阅读:
    Android NDK学习(1) 简介
    wmsys.wm_concat结果长度限制的问题
    onInterceptTouchEvent和onTouchEvent调用时序
    滑动到底部或顶部响应的ScrollView实现
    Android ViewPager使用详解
    android include标签的使用,在RelativeLayout中使用include标签需注意!!!!!
    Eclipse中如何在指定工程中搜索指定的字符串
    android:windowSoftInputMode属性详解
    cocos2d-x中关于touch事件的响应
    《从零开始学Swift》学习笔记(Day 6)——哎呀常量和变量都该什么时候用啊?
  • 原文地址:https://www.cnblogs.com/jfcspring/p/3786427.html
Copyright © 2011-2022 走看看