zoukankan      html  css  js  c++  java
  • Dijkstra算法以及各种海量数据排序算法

    一、Dijkstra最短路径算法

    是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

    实现一

    //
    //  Dijkstra
    //  ACM
    //  Find the number of minimal path
    //
    //  Created by Rachel on 18-2-12.
    //  Copyright (c) 2014年 ZJU. All rights reserved.
    //
    
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <functional>
    #include <utility>
    #include <memory.h>
    using namespace std;
    #define N 505
    #define INF 100000000
    #define min(a,b) a<b?a:b
    #define max(a,b) a>b?a:b
    
    int map[N][N];
    int minres[N]; //min distance from source to point_i
    bool visited[N];
    int weight[N];
    
    void init(int n)
    {
        int i,j;
        for (i=0; i<n; i++) {
            for (j=0; j<n; j++) {
                map[i][j] = INF;
            }
            minres[i] = INF;
        }
        memset(visited, false, sizeof(visited));
    }
    
    void dijkstra(int source, int dest, int n)
    {
        int i,j;
        for(i=0;i<n;i++)
            minres[i]=map[source][i];
        visited[source]=true;
        
        // (n-1) times, each time select one point into the start point set
        for (j=0; j<n-1; j++) {
            //select a point to add into the start point set
            int minn = INF, point=-1;
            for(i=0;i<n;i++)
                if (!visited[i]&&minres[i]<minn) {
                    minn = minres[i];
                    point = i;
                }
            visited[point] = true;
            
            //update the min distance of other points
            for (i=0; i<n; i++) {
                if (!visited[i]&&minres[i]>minres[point]+map[point][i]) {
                    minres[i] = minres[point]+map[point][i];
                }
            }
        }
    }
    
    void dfs(int source, int dest,int n, int curpoint, int curdis, int cursum, int* num, int* sum)
    {
        if (curpoint==dest && minres[dest]==curdis) {
            *num = *num+1;
            *sum = max(*sum, cursum);
            return;
        }
        if (curdis>minres[dest])
            return;
        for (int i=0; i<n; i++) {
            if(!visited[i]&&map[curpoint][i]!=INF)
            {
                visited[i] = true;
                dfs(source, dest, n, i, curdis+map[curpoint][i], cursum+weight[i], num, sum);
                visited[i] = false;
            }
        }
    }
    
    int main()
    {
        int i,m,n,a,b,t,source,dest;
        while (cin>>n>>m) {
            cin>>source>>dest;
            for (i=0; i<n; i++) {
                cin>>weight[i]; //#peoples @ each point
            }
            init(n);
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&t);
                map[b][a] = map[a][b]= min(map[a][b],t);
            }
            dijkstra(source,dest,n);
            minres[source] = 0;
            int num = 0, sum = 0;
            memset(visited, false, sizeof(visited));
            visited[source] = true;
            dfs(source, dest, n, source, 0, weight[source], &num, &sum);
            cout<<num<<" "<<sum<<endl;
        }
    }
    

     实现二

    /*Dijkstra求单源最短路径 2010.8.26*/
     /*http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html
     */
    #include <iostream>
    #include<stack>
    #define M 100
    #define N 100
    using namespace std;
    
    typedef struct node
    {
        int matrix[N][M];      //邻接矩阵 
        int n;                 //顶点数 
        int e;                 //边数 
    }MGraph; 
    
    void DijkstraPath(MGraph g,int *dist,int *path,int v0)   //v0表示源顶点 
    {
        int i,j,k;
    
        bool *visited=(bool *)malloc(sizeof(bool)*g.n);
    
        for(i=0;i<g.n;i++)     //初始化 
        {
            if(g.matrix[v0][i]>0&&i!=v0)
            {
                dist[i]=g.matrix[v0][i];
                path[i]=v0;     //path记录最短路径上从v0到i的前一个顶点 
            }
            else
            {
                dist[i]=INT_MAX;    //若i不与v0直接相邻,则权值置为无穷大 
                path[i]=-1;
            }
            visited[i]=false;
            path[v0]=v0;
            dist[v0]=0;
        }
        visited[v0]=true;
        for(i=1;i<g.n;i++)     //循环扩展n-1次 
        {
            int min=INT_MAX;
            int u;
            for(j=0;j<g.n;j++)    //寻找未被扩展的权值最小的顶点 
            {
                if(visited[j]==false&&dist[j]<min)
                {
                    min=dist[j];
                    u=j;        
                }
            } 
            visited[u]=true;
            for(k=0;k<g.n;k++)   //更新dist数组的值和路径的值 
            {
                if(visited[k]==false&&g.matrix[u][k]>0&&min+g.matrix[u][k]<dist[k])
                {
                    dist[k]=min+g.matrix[u][k];
                    path[k]=u; 
                }
            }        
        }    
    }
    
    void showPath(int *path,int v,int v0)   //打印最短路径上的各个顶点 
    {
        stack<int> s;
        int u=v;
        while(v!=v0)
        {
            s.push(v);
            v=path[v];
        }
        s.push(v);
        while(!s.empty())
        {
            cout<<s.top()<<" ";
            s.pop();
        }
    } 
    
    int main(int argc, char *argv[])
    {
        int n,e;     //表示输入的顶点数和边数 
        while(cin>>n>>e&&e!=0)
        {
            int i,j;
            int s,t,w;      //表示存在一条边s->t,权值为w
            MGraph g;
            int v0;
            int *dist=(int *)malloc(sizeof(int)*n);
            int *path=(int *)malloc(sizeof(int)*n);
            
            for(i=0;i<N;i++)
                for(j=0;j<M;j++)
                    g.matrix[i][j]=0;
            g.n=n;
            g.e=e;
            for(i=0;i<e;i++)
            {
                cin>>s>>t>>w;
                g.matrix[s][t]=w;
            }
            cin>>v0;        //输入源顶点 
            DijkstraPath(g,dist,path,v0);
            for(i=0;i<n;i++)
            {
                if(i!=v0)
                {
                    showPath(path,i,v0);
                    cout<<dist[i]<<endl;
                }
            }
        }
        return 0;
    }
    

     二、基于bitset排序

    各种排序算法,生成随机文件程序。

        //purpose:  生成随机的不重复的测试数据  
        //copyright@ 2011.04.19 yansha  
        //1000w数据量,要保证生成不重复的数据量,一般的程序没有做到。  
        //但,本程序做到了。  
        //July、2010.05.30。  
        #include <iostream>  
        #include <time.h>  
        #include <assert.h>  
        using namespace std;  
          
        const int size = 10000000;  
        int num[size];  
          
        int main()  
        {  
            int n;  
            FILE *fp = fopen("data.txt", "w");  
            assert(fp);  
          
            for (n = 1; n <= size; n++)    
                //之前此处写成了n=0;n<size。导致下面有一段小程序的测试数据出现了0,特此订正。  
                num[n] = n;  
            srand((unsigned)time(NULL));  
            int i, j;  
          
            for (n = 0; n < size; n++)  
            {  
                i = (rand() * RAND_MAX + rand()) % 10000000;  
                j = (rand() * RAND_MAX + rand()) % 10000000;  
                swap(num[i], num[j]);  
            }  
          
            for (n = 0; n < size; n++)  
                fprintf(fp, "%d ", num[n]);  
            fclose(fp);  
            return 0;  
        }  
        
    

    基于bitset实现方法

    #include<iostream>
    #include<bitset>
    #include<assert.h>
    #include<time.h>
    using namespace std;
    
    const int max_each_scan=5000000;
    
    int main(){
    	clock_t begin=clock();
    
    	bitset<max_each_scan> bitmap;
    	bitmap.reset();
    
    	FILE* fp_unsort_file=fopen("data.txt","r");
    	assert(fp_unsort_file);
    	int num;
    
    	while(fscanf(fp_unsort_file,"%d",&num)!=EOF){
    		if(num<max_each_scan)
    			bitmap.set(num,1);
    	}
    
    	FILE* fp_sort_file=fopen("sort.txt","w");
    	assert(fp_sort_file);
    	int i ;
    
    	for(i=0;i<max_each_scan;i++){
    		if(bitmap[i]==1)
    			fprintf(fp_sort_file, "%d
    ", i);
    	}
    	int result=fseek(fp_unsort_file,0,SEEK_SET);
    	if(result)
    		cout<<"failed"
    	else{
    		bitmap.reset();
    		while(fscanf(fp_unsort_file,"%d",$num)!=EOF){
    			if(num>max_each_scan&&num<10000000){
    				num=num-max_ean_scan;
    				bitmap.set(num,1);
    			}
    		}
    		for(i=0;i<max_each_scan;i++){
    			if(bitmap[i]==1){
    				fprintf(fp_sort_file, "%d
    ", max_each_scan+i);
    			}
    		}
    	}
    
    	clock_t end=clock();
    	cout<<"排序用时:"<<endl;  
    	cout << (end - begin) / CLK_TCK << "s" << endl;  
        fclose(fp_sort_file);  
        fclose(fp_unsort_file);  
    	return 0;  
    }
    

     三、海量数据排序实例

        //copyright@ yansha  
        //July、updated,2011.05.28。  
        #include <iostream>  
        #include <string>  
        #include <algorithm>  
        #include <time.h>  
        using namespace std;  
          
        int sort_num = 10000000;  
        int memory_size = 250000;    
          
        //每次只对250k个小数据量进行排序  
        int read_data(FILE *fp, int *space)  
        {  
            int index = 0;  
            while (index < memory_size && fscanf(fp, "%d ", &space[index]) != EOF)  
                index++;  
            return index;  
        }  
          
        void write_data(FILE *fp, int *space, int num)  
        {  
            int index = 0;  
            while (index < num)  
            {  
                fprintf(fp, "%d ", space[index]);  
                index++;  
            }  
        }  
          
        // check the file pointer whether valid or not.  
        void check_fp(FILE *fp)  
        {  
            if (fp == NULL)  
            {  
                cout << "The file pointer is invalid!" << endl;  
                exit(1);  
            }  
        }  
          
        int compare(const void *first_num, const void *second_num)  
        {  
            return *(int *)first_num - *(int *)second_num;  
        }  
          
        string new_file_name(int n)  
        {  
            char file_name[20];  
            sprintf(file_name, "data%d.txt", n);  
            return file_name;  
        }  
          
        int memory_sort()  
        {  
            // open the target file.  
            FILE *fp_in_file = fopen("data.txt", "r");  
            check_fp(fp_in_file);  
            int counter = 0;  
            while (true)  
            {  
                // allocate space to store data read from file.  
                int *space = new int[memory_size];  
                int num = read_data(fp_in_file, space);  
                // the memory sort have finished if not numbers any more.  
                if (num == 0)  
                    break;  
          
                // quick sort.  
                qsort(space, num, sizeof(int), compare);  
                // create a new auxiliary file name.  
                string file_name = new_file_name(++counter);  
                FILE *fp_aux_file = fopen(file_name.c_str(), "w");  
                check_fp(fp_aux_file);  
          
                // write the orderly numbers into auxiliary file.  
                write_data(fp_aux_file, space, num);  
                fclose(fp_aux_file);  
                delete []space;  
            }  
            fclose(fp_in_file);  
          
            // return the number of auxiliary files.  
            return counter;  
        }  
          
        void merge_sort(int file_num)  
        {  
            if (file_num <= 0)  
                return;  
            // create a new file to store result.  
            FILE *fp_out_file = fopen("result.txt", "w");  
            check_fp(fp_out_file);  
          
            // allocate a array to store the file pointer.  
            FILE **fp_array = new FILE *[file_num];  
            int i;  
            for (i = 0; i < file_num; i++)  
            {  
                string file_name = new_file_name(i + 1);  
                fp_array[i] = fopen(file_name.c_str(), "r");  
                check_fp(fp_array[i]);  
            }  
          
            int *first_data = new int[file_num];     
            //new出个大小为0.1亿/250k数组,由指针first_data指示数组首地址  
            bool *finish = new bool[file_num];  
            memset(finish, false, sizeof(bool) * file_num);  
          
            // read the first number of every auxiliary file.  
            for (i = 0; i < file_num; i++)  
                fscanf(fp_array[i], "%d ", &first_data[i]);  
            while (true)  
            {  
                int index = 0;  
                while (index < file_num && finish[index])  
                    index++;  
          
                // the finish condition of the merge sort.  
                if (index >= file_num)  
                    break;  
                //主要的修改在上面两行代码,就是merge sort结束条件。  
                //要保证所有文件都读完,必须使得finish[0]...finish[40]都为真  
                //July、yansha,555,2011.05.29。  
          
                int min_data = first_data[index];  
                // choose the relative minimum in the array of first_data.  
                for (i = index + 1; i < file_num; i++)  
                {  
                    if (min_data > first_data[i] && !finish[i])     
                        //一旦发现比min_data更小的数据first_data[i]  
                    {  
                        min_data = first_data[i];      
                        //则置min_data<-first_data[i]index = i;                     
                        //把下标i 赋给index。  
                    }  
                }  
          
                // write the orderly result to file.  
                fprintf(fp_out_file, "%d ", min_data);  
                if (fscanf(fp_array[index], "%d ", &first_data[index]) == EOF)  
                    finish[index] = true;  
            }  
          
            fclose(fp_out_file);  
            delete []finish;  
            delete []first_data;  
            for (i = 0; i < file_num; i++)  
                fclose(fp_array[i]);  
            delete [] fp_array;  
        }  
          
        int main()  
        {  
            clock_t start_memory_sort = clock();  
            int aux_file_num = memory_sort();  
            clock_t end_memory_sort = clock();  
            cout << "The time needs in memory sort: " << end_memory_sort - start_memory_sort << endl;  
            clock_t start_merge_sort = clock();  
            merge_sort(aux_file_num);  
            clock_t end_merge_sort = clock();  
            cout << "The time needs in merge sort: " << end_merge_sort - start_merge_sort << endl;  
            system("pause");  
            return 0;  
        }  
    

     
    四、多路归并排序

    //copyright@ 纯净的天空 && yansha  
     //5、July,updated,2010.05.28。 
    //harryshayne,update again。2011.6.30 
    #include <iostream>  
    #include <ctime>  
    #include <fstream>  
    //#include "ExternSort.h"  
    using namespace std;  
      
    //使用多路归并进行外排序的类  
    //ExternSort.h  
      
    /* 
    * 大数据量的排序 
    * 多路归并排序 
    * 以千万级整数从小到大排序为例 
    * 一个比较简单的例子,没有建立内存缓冲区 
    */  
      
    #ifndef EXTERN_SORT_H  
    #define EXTERN_SORT_H  
      
    #include <cassert>  
    //#define k 5  
    #define MIN -1//这里开始的时候出现了一个BUG,如果定义的MIN大于等于待排序的数,则会是算法出现错误
    #define MAX 10000000//最大值,附加在归并文件结尾
    typedef int* LoserTree;
    typedef int* External;
    
    class ExternSort  
    {  
    public:  
        void sort()  
        {  
            time_t start = time(NULL);  
              
            //将文件内容分块在内存中排序,并分别写入临时文件  
            k = memory_sort();  //
              
            //归并临时文件内容到输出文件  
            //merge_sort(file_count); 
            ls=new int[k];
            b=new int[k+1];
            
            K_Merge();
            delete []ls;
            delete []b;
              
            time_t end = time(NULL);  
            printf("total time:%f
    ", (end - start) * 1000.0/ CLOCKS_PER_SEC);  
        }  
          
        //input_file:输入文件名  
        //out_file:输出文件名  
        //count: 每次在内存中排序的整数个数  
        ExternSort(const char *input_file, const char * out_file, int count)  
        {  
            m_count = count;  
            m_in_file = new char[strlen(input_file) + 1];  
            strcpy(m_in_file, input_file);  
            m_out_file = new char[strlen(out_file) + 1];  
            strcpy(m_out_file, out_file);  
        }  
        virtual ~ExternSort()  
        {  
            delete [] m_in_file;  
            delete [] m_out_file;  
        }  
          
    private:  
        int m_count; //数组长度  
        char *m_in_file;   //输入文件的路径  
        char *m_out_file; //输出文件的路径  
       
        int k;//归并数,此数必须要内排序之后才能得到,所以下面的ls和b都只能定义为指针(注意和书上区别)
    
        LoserTree ls;//定义成为指针,之后动态生成数组
        External b;//定义成为指针,在成员函数中可以把它当成数组使用
        //int External[k];
    protected:  
        int read_data(FILE* f, int a[], int n)  
        {  
            int i = 0;  
            while(i < n && (fscanf(f, "%d", &a[i]) != EOF)) i++;  
            printf("read:%d integer
    ", i);  
            return i;  
        }  
        void write_data(FILE* f, int a[], int n)  
        {  
            for(int i = 0; i < n; ++i)  
                fprintf(f, "%d ", a[i]);  
            fprintf(f,"%d",MAX);//在最后写上一个最大值
        }  
        char* temp_filename(int index)  
        {  
            char *tempfile = new char[100];  
            sprintf(tempfile, "temp%d.txt", index);  
            return tempfile;  
        }  
        static int cmp_int(const void *a, const void *b)  
        {  
            return *(int*)a - *(int*)b;  
        }  
          
        int memory_sort()  
        {  
            FILE* fin = fopen(m_in_file, "rt");  
            int n = 0, file_count = 0;  
            int *array = new int[m_count];  
              
            //每读入m_count个整数就在内存中做一次排序,并写入临时文件  
            while(( n = read_data(fin, array, m_count)) > 0)  
            {  
                qsort(array, n, sizeof(int), cmp_int);     
                //这里,调用了库函数阿,在第四节的c实现里,不再调用qsort。  
                char *fileName = temp_filename(file_count++);  
                FILE *tempFile = fopen(fileName, "w");  
                free(fileName);  
                write_data(tempFile, array, n);  
                fclose(tempFile);  
            }  
              
            delete [] array;  
            fclose(fin);  
              
            return file_count;  
        }  
    
        void Adjust(int s)
        {//沿从叶子节点b[s]到根节点ls[0]的路径调整败者树
            int t=(s+k)/2;//ls[t]是b[s]的双亲节点
    
            while(t>0)
            {
                if(b[s]>b[ls[t]])//如果失败,则失败者位置s留下,s指向新的胜利者
                {
                    int tmp=s;
                    s=ls[t];
                    ls[t]=tmp;
                }
                t=t/2;
            }
            ls[0]=s;//ls[0]存放调整后的最大值的位置
        }
    
        void CreateLoserTree()
        {
            b[k]=MIN;//额外的存储一个最小值
            for(int i=0;i<k;i++)ls[i]=k;//先初始化为指向最小值,这样后面的调整才是正确的
                                        //这样能保证非叶子节点都是子树中的“二把手”
            for(i=k-1;i>=0;i--)
                Adjust(i);//依次从b[k-1],b[k-2]...b[0]出发调整败者树
        }
    
        void K_Merge()
        {//利用败者数把k个输入归并段归并到输出段中
            //b中前k个变量存放k个输入段中当前记录的元素
            //归并临时文件  
            FILE *fout = fopen(m_out_file, "wt");  
            FILE* *farray = new FILE*[k];  
            int i;  
            for(i = 0; i < k; ++i)  //打开所有k路输入文件
            {  
                char* fileName = temp_filename(i);  
                farray[i] = fopen(fileName, "rt");  
                free(fileName);  
            }  
              
            for(i = 0; i < k; ++i)  //初始读取
            {  
                if(fscanf(farray[i], "%d", &b[i]) == EOF)//读每个文件的第一个数到data数组  
                {
                    printf("there is no %d file to merge!",k);
                    return;
                }
            }  
        //    for(int i=0;i<k;i++)input(b[i]);
    
            CreateLoserTree();
            int q;
            while(b[ls[0]]!=MAX)//
            {
                q=ls[0];//q用来存储b中最小值的位置,同时也对应一路文件
                //output(q);
                fprintf(fout,"%d ",b[q]);
                //input(b[q],q);
                fscanf(farray[q],"%d",&b[q]);
                Adjust(q);
            }
            //output(ls[0]);
            fprintf(fout,"%d ",b[ls[0]]);
            //delete [] hasNext;  
            //delete [] data;  
              
            for(i = 0; i < k; ++i)  //清理工作
            {  
                fclose(farray[i]);  
            }  
            delete [] farray;  
            fclose(fout);  
        }
        /*
        void merge_sort(int file_count)  
        {  
            if(file_count <= 0) return;  
              
            //归并临时文件  
            FILE *fout = fopen(m_out_file, "wt");  
            FILE* *farray = new FILE*[file_count];  
            int i;  
            for(i = 0; i < file_count; ++i)  
            {  
                char* fileName = temp_filename(i);  
                farray[i] = fopen(fileName, "rt");  
                free(fileName);  
            }  
              
            int *data = new int[file_count];//存储每个文件当前的一个数字  
            bool *hasNext = new bool[file_count];//标记文件是否读完  
            memset(data, 0, sizeof(int) * file_count);  
            memset(hasNext, 1, sizeof(bool) * file_count);  
              
            for(i = 0; i < file_count; ++i)  //初始读取
            {  
                if(fscanf(farray[i], "%d", &data[i]) == EOF)//读每个文件的第一个数到data数组  
                    hasNext[i] = false;  
            }  
              
            while(true)  //循环读取和输出,选择最小数的方法是简单遍历选择法
            {  
                //求data中可用的最小的数字,并记录对应文件的索引  
                int min = data[0];  
                int j = 0;  
                  
                while (j < file_count && !hasNext[j])  //顺序跳过已读取完毕的文件
                    j++;  
                  
                if (j >= file_count)  //没有可取的数字,终止归并  
                    break;  
                  
                  
                for(i = j +1; i < file_count; ++i)  //选择最小数,这里应该是i=j吧!但结果是一样的!
                {  
                    if(hasNext[i] && min > data[i])  
                    {  
                        min = data[i];  
                        j = i;  
                    }  
                }  
                  
                if(fscanf(farray[j], "%d", &data[j]) == EOF) //读取文件的下一个元素  
                    hasNext[j] = false;  
                fprintf(fout, "%d ", min);  
                  
            }  
              
            delete [] hasNext;  
            delete [] data;  
              
            for(i = 0; i < file_count; ++i)  
            {  
                fclose(farray[i]);  
            }  
            delete [] farray;  
            fclose(fout);  
        }  
        */
    };  
      
    #endif  
      
      
    //测试主函数文件  
    /* 
    * 大文件排序 
    * 数据不能一次性全部装入内存 
    * 排序文件里有多个整数,整数之间用空格隔开 
    */  
      
    const unsigned int count = 10000000; // 文件里数据的行数  
    const unsigned int number_to_sort = 100000; //在内存中一次排序的数量  
    const char *unsort_file = "unsort_data.txt"; //原始未排序的文件名  
    const char *sort_file = "sort_data.txt"; //已排序的文件名  
    void init_data(unsigned int num); //随机生成数据文件  
      
    int main(int argc, char* *argv)  
    {  
        srand(time(NULL));  
        init_data(count);  
        ExternSort extSort(unsort_file, sort_file, number_to_sort);  
        extSort.sort();  
        system("pause");  
        return 0;  
    }  
      
    void init_data(unsigned int num)  
    {  
        FILE* f = fopen(unsort_file, "wt");  
        for(int i = 0; i < num; ++i)  
            fprintf(f, "%d ", rand());  
        fclose(f);  
    }
    

     五、字符串回文结构判断

    class Solution{
    	//http://blog.csdn.net/v_july_v/article/details/6712171
    public:
    	    /**  
         *check weather s is a palindrome, n is the length of string s 
         *Copyright(C) fairywell 2011 
         */  
        bool IsPalindrome(const char *s, int n)  
        {  
           if (s == 0 || n < 1) return false; // invalid string  
           char *front, *back;  
           front = s; back = s + n - 1; // set front and back to the begin and endof the string  
           while (front < back) {  
               if (*front != *back) return false; // not a palindrome  
               ++front; --back;  
            }  
           return true; // check over, it's a palindrome  
          
        }  
    
            /**  
         *check weather s is a palindrome, n is the length of string s 
         *Copyright(C) fairywell 2011 
         */  
        bool IsPalindrome2(const char *s, int n)  
        {  
           if (s == 0 || n < 1) return false; // invalid string  
           char *first, *second;  
           int m = ((n>>1) - 1) >= 0 ? (n>>1) - 1 : 0; // m is themiddle point of s      
           first = s + m; second = s + n - 1 - m;  
           while (first >= s)  
                   if (s[first--] !=s[second++]) return false; // not equal, so it's not apalindrome  
           return true; // check over, it's a palindrome  
        }  
            /**  
         *find the longest palindrome in a string, n is the length of string s 
         *Copyright(C) fairywell 2011 
         */  
        int LongestPalindrome(const char *s, int n)  
        {  
           int i, j, max;  
           if (s == 0 || n < 1) return 0;  
           max = 0;  
    
           for (i = 0; i < n; ++i) { // i is the middle point of the palindrome  
               for (j = 0; (i-j >= 0) && (i+j < n); ++j) // if the lengthof the palindrome is odd  
                   if (s[i-j] != s[i+j]) break;  
           
               if (j*2+1 > max) max = j * 2 + 1;  
           
               for (j = 0; (i-j >= 0) && (i+j+1 < n); ++j) // for theeven case  
                   if (s[i-j] != s[i+j+1]) break;  
    
               if (j*2+2 > max) max = j * 2 + 2;  
            }  
           return max;  
        }  
    
            int LongestPalindrome(const char *s, int n)  
        {  
            int max = 0;  
            int i,j;  
            for (  i = 0; i < n  ; i++ )  
            {//以i为中心开始计算回文子串  
                //计算奇数回问子串长度  
                for (  j = 0; (i-j) >= 0 && (i+j) < n; j++ )  
                {  
                    if ( s[i-j] != s[i+j] )  
                    {  
                        break;  
                    }  
                    else  
                    {  
                        max = GETMAX(max, (2 * j  + 1));  
                    }  
                }  
                  
                //计算偶数回问子串长度  
                for ( j = 0; (i-j) >= 0 && i + j + 1< n; j++ )  
                {  
                    if ( s[i-j] != s[i+j+1])  
                    {  
                        break;  
                    }  
                    else  
                    {  
                        max = GETMAX(max, ( 2 * j  + 2) );  
                    }  
                }  
            }  
          
            return max;  
        }  
    }
    
  • 相关阅读:
    适用于小白的 python 快速入门教程
    Centos7.x & RedHat7.x系统忘记 root 密码解决办法
    让我来教你如何免费使用RHEL小红帽系统
    10#Windows注册表的那些事儿
    9#搭建网站
    8#继承和多态
    7#Java基本语句语法
    6#day2总结
    5#关于数据数值的转换
    .NET Core开发日志——配置
  • 原文地址:https://www.cnblogs.com/sansan/p/4065706.html
Copyright © 2011-2022 走看看