超长字符串

来源:互联网 发布:飞思卡尔单片机 区别 编辑:程序博客网 时间:2024/04/19 19:08
给一个数字串T:12345678910111213141516171819202122...它是由所有自然数从小到大排列起来的。任意给一个数字串S,容易知道它一定在T中出现无穷多次。编程求出它第一次出现的位置。例如对于串"81",它最先出现在位置27。

/*
 * 超长字符串
 * tanliboy<tanliboy2003@yahoo.com.cn> 24 Nov. 2008
 */
#include<iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;

int partition(int* data,int from,int to,int* order)
{
    int cur = from;
    for(int i = from;i<to-1;i++)
    {
        if(data[i] < data[to-1])
        {
            swap(data[i],data[cur]);
            swap(order[i],order[cur]);
            cur++;
        }
    }
    swap(data[to-1],data[cur]);
    swap(order[to-1],order[cur]);
    return cur;
}

void quickSort(int* data,int from,int to,int* order)
{
    if(to<= from)
        return;
    int p = partition(data,from,to,order);
    quickSort(data,from,p,order);
    quickSort(data,p+1,to,order);
}

bool match(const char* ch,const int pos,const int len,const int num)
{
    int finished = false;
    int p = pos;

    //forward
    for(int i = num; p<len; i++)
    {
        stack<int> s;
        for(int tt = i;tt>0;tt/=10)
        {
            s.push(tt%10);
        }

        while(!s.empty() && p<len)
        {
            int cur = s.top();
            s.pop();
            if(cur != ch[p++] - '0')
            {
                return false;
            }
        }
    }

    p = pos-1;
    //backward
    for(int i = num-1; p>=0; i--)
    {
        if(i<=0)
            return false;

        for(int t = i;t>0 && p>=0; t/=10)
        {
            int cur = t%10;
            if(cur !=ch[p--] -'0')
            {
                return false;
            }
        }
    }

    return true;
}


/**
 * check whether the number satisfy ch
 */
int check(const char* ch,const int pos,const int l,const int len)
{
    int num = 0;
    //the first case.
    if(pos+l <= len)
    {
        int p = pos;
        for(int i = 0;i<l;i++)
        {
            num *= 10;
            num += ch[p++] -'0';
        }
    }else
    {
        //forward
        for(int i = pos;i<pos+l;i++)
        {
            num*= 10;
            if(i<len)
                num += ch[i] - '0';
        }

        //backward
        int tail = 0;
        bool nine = true; // for special case
        for(int i = len-l;i<pos;i++)
        {
            int cur = ch[i] - '0';
            if(9!= cur)
            {
                nine = false;
            }

            tail *= 10;
            tail += cur;
        }

        if(false == nine)
        {
            num += tail+1;
        }
    }
   
    if(match(ch,pos,len,num))
    {
        return num;
    }else
    {
        return 0;
    }
}

int main()
{
    string str;
    cin>>str;
    int len = str.length();
    const char* ch = str.c_str();

    // get integer
    int* data = new int[len];
    int* order = new int[len];
    for(int i = 0;i<len;i++)
    {
        data[i] = ch[i] - '0';
        order[i] = i;

        // input error
        if(data[i]>9 || data[i] <0)
        {
            cerr<<"Input error !"<<endl;
            cerr<<"Please input an integer number!"<<endl;
            return -1;
        }
    }

    // quick sort order.
    quickSort(data,0,len,order);

    // search the first number
    int num;
    int pos;
    bool found = false;
   
    int l; // size of base
    for( l = 1;l<=len ;l++)
    {
        //begin with the order i;
        for(int i = 0;i<len && !found;i++)
        {
            int site = order[i];
            if(ch[site] == '0')
            {
                continue;
            }

            num = check(ch,site,l,len);
            if(num)
            {
                found = true;
                pos = order[i];

                cout<<"the finded number is "<<num<<endl;
                break;
            }
        }

        if(found)
            break;
    }

    //calculate the pos according to the num and pos.
    int res = l * (num-1);
    for(int i = 1,base = 1; i<l;i++)
    {
        base*=10;
        res -= base-1;
    }

    cout<<"the position is: "<<res-pos+1<<endl;

    delete[] data;
    delete[] order;
}

原创粉丝点击