Cantor数组问题

Cantor数组问题:

已知数组A[0...N-1]乱序着前N个正整数,现统计后缀数组A[i+1...N-1]中小于元素A[i]的数目,并存放在数组C[i]中。则C数组称为Cantor数组。

如给定数组:4,6,2,5,1,3。得到的Cantor数组为:3,4,1,2,1,0。

生成Cantor数组程序实现:

 1 //生成Cantor数组
 2 void CantorCreate(int* A,int* C,int size){
 3     for(int i=0;i<size;i++){
 4         C[i] = 0;
 5         for(int j=i+1;j<size;j++){
 6             if(A[j]<A[i])
 7                 C[i]++;
 8         }
 9     }
10 }

运行结果:

由Cantor数组得到原数组,需要一个顺序数组B辅助,A[i] = B[C[i]]。程序实现如下:

 1 //由cantor数组求原数组,时间复杂度为O(n^2),空间复杂度为O(n)
 2 void CantorReverse(const int* C,int* A,int size){
 3     vector<int> B(size);
 4     for(int i=0;i<size;i++){
 5         B[i] = i + 1;
 6     }
 7     for(int i=0;i<size;i++){
 8         A[i] = B[C[i]];
 9         B.erase(B.begin()+C[i]);
10     }
11 }

但上面实现时间复杂度为O(n^2),空间复杂度为O(n)。现在允许改变Cantor数组,空间复杂度可降为O(1)。

 1 //cantor数组可变,由cantor数组求原数组,空间复杂度为O(1)
 2 void CantorReverse2(int* C,int* A,int size){
 3     memset(A,0,sizeof(int)*size);
 4     int i,j;
 5     for(i=0;i<size;i++){
 6         for(j=0;j<size;j++){
 7             if(A[j] != 0)
 8                 continue;
 9             if(C[j] == 0)
10                 break;
11             C[j]--;
12         }
13         A[j] = i+1;
14     }
15 }

运行结果:

总体程序代码实现:

 1 /***************************************
 2 FileName Cantor.cpp
 3 Author : godfrey
 4 CreatedTime : 2016/5/4
 5 ****************************************/
 6 #include <iostream>
 7 #include <cstring>
 8 #include <vector>
 9 #include <algorithm>
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 using namespace std;
14 //生成Cantor数组
15 void CantorCreate(int* A,int* C,int size){
16     for(int i=0;i<size;i++){
17         C[i] = 0;
18         for(int j=i+1;j<size;j++){
19             if(A[j]<A[i])
20                 C[i]++;
21         }
22     }
23 }
24 //由cantor数组求原数组,时间复杂度为O(n^2),空间复杂度为O(n)
25 void CantorReverse(const int* C,int* A,int size){
26     vector<int> B(size);
27     for(int i=0;i<size;i++){
28         B[i] = i + 1;
29     }
30     for(int i=0;i<size;i++){
31         A[i] = B[C[i]];
32         B.erase(B.begin()+C[i]);
33     }
34 }
35 //cantor数组可变,由cantor数组求原数组,空间复杂度为O(1)
36 void CantorReverse2(int* C,int* A,int size){
37     memset(A,0,sizeof(int)*size);
38     int i,j;
39     for(i=0;i<size;i++){
40         for(j=0;j<size;j++){
41             if(A[j] != 0)
42                 continue;
43             if(C[j] == 0)
44                 break;
45             C[j]--;
46         }
47         A[j] = i+1;
48     }
49 }
50 int main()
51 {
52 //    int a[] = {4,6,2,5,3,1};
53 //    int size = sizeof(a)/sizeof(int);
54 //    int* c = new int[size];
55 //    cout<<"原数组 : "<<endl;
56 //    for(int i=0;i<size;i++){
57 //        cout<<a[i]<<" ";
58 //    }
59 //    cout<<endl;
60 //    CantorCreate(a,c,size);
61 //    cout<<"Cantor数组 : "<<endl;
62 //    for(int i=0;i<size;i++){
63 //        cout<<c[i]<<" ";
64 //    }
65 //    cout<<endl;
66 
67     int c[] = {3,4,1,2,1,0};
68     int size = sizeof(c)/sizeof(int);
69     int* a = new int[size];
70     cout<<"Cantor数组 : "<<endl;
71     for(int i=0;i<size;i++){
72         cout<<c[i]<<" ";
73     }
74     cout<<endl;
75     CantorReverse2(c,a,size);
76     cout<<"原数组 : "<<endl;
77     for(int i=0;i<size;i++){
78         cout<<a[i]<<" ";
79     }
80     cout<<endl;
81     return 0;
82 }

转载请注明出处:

C++博客园:godfrey_88

http://www.cnblogs.com/gaobaoru-articles/

转载请注明出处: C++博客园:godfrey_88 http://www.cnblogs.com/gaobaoru-articles/
原文地址:https://www.cnblogs.com/gaobaoru-articles/p/5460305.html