超长字符串

本文介绍了一种算法,用于确定一个给定数字串在由所有自然数依次排列形成的超长数字串中首次出现的位置。通过快速排序和特定匹配策略实现了高效搜索。
给一个数字串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;
}

### Oracle 超长字符串字段类型及解决方案 在 Oracle 数据库中,用于存储超长字符串的字段类型主要包括 `CLOB` 和已逐渐被淘汰的 `LONG` 类型。以下是关于这些类型的详细说明以及相关解决方案: #### 1. CLOB 类型 `CLOB` 是 Character Large Object 的缩写,专门用于存储大容量的字符数据。它的最大存储长度可达 **4GB**(取决于数据库块大小)。与 `LONG` 类型相比,`CLOB` 更加灵活且功能强大,支持更多操作,如索引和搜索[^1]。 - **特点**: - 支持存储超长字符串,适合处理文本文件、XML 数据等。 - 默认情况下,`CLOB` 使用逻辑指针(locator)来引用实际数据,而不是直接存储数据本身[^3]。 - 在事务期间有效,能够参与索引创建和全文搜索。 - **使用限制**: - 如果直接通过 `INSERT` 或 `UPDATE` 语句写入数据,超过 4000 字符时会报错,需要使用特定方法处理超长字符串[^2]。 ```sql -- 示例:创建包含 CLOB 字段的表 CREATE TABLE example_table ( id NUMBER PRIMARY KEY, content CLOB ); -- 插入超长字符串数据(需使用 PL/SQL 或绑定变量) DECLARE long_string CLOB := '...'; -- 超长字符串内容 BEGIN INSERT INTO example_table (id, content) VALUES (1, long_string); END; ``` #### 2. LONG 类型 `LONG` 类型是一种较老的数据类型,用于存储可变长度的字符数据,最大长度为 **2GB**。然而,由于其功能受限且已被标记为过时,Oracle 建议用 `CLOB` 替代 `LONG`[^4]。 - **特点**: - 最大长度为 2GB,但不支持索引和部分字符串操作。 - 不推荐在新设计中使用,未来版本可能会完全移除该类型。 #### 3. 替代方案 如果需要存储超长字符串并希望避免 `CLOB` 的复杂性,可以考虑以下替代方案: - **VARCHAR2**:对于不超过 4000 字节的字符串,`VARCHAR2` 是更简单的选择。如果数据库支持扩展数据类型(Extended Data Types),则 `VARCHAR2` 的最大长度可扩展至 32767 字节[^1]。 - **JSON 数据类型**:从 Oracle 12c 开始,支持 JSON 格式数据存储,适用于结构化或半结构化的超长字符串。 ```sql -- 示例:使用 VARCHAR2 扩展数据类型 ALTER SESSION SET MAX_STRING_SIZE = EXTENDED; CREATE TABLE json_example ( id NUMBER PRIMARY KEY, data CLOB CHECK (data IS JSON) ); ``` #### 4. 数据库设计建议 在设计数据库时,应根据实际需求选择合适的字段类型: - 如果需要存储超长字符串(如文档、日志等),优先选择 `CLOB`。 - 如果字符串长度有限且需要频繁搜索或索引,使用 `VARCHAR2`。 - 对于结构化数据,考虑使用 JSON 数据类型以提高灵活性。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值