source: CIVL/examples/verifyThisProblems/lrs.c@ 59d519c

1.23 2.0 main test-branch
Last change on this file since 59d519c was 0ae124a, checked in by Yihao Yan <yihaoyan1@…>, 10 years ago

format changes

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@3115 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 2.5 KB
Line 
1/*
2author: Yihao
3
4Link(LCP.zip): http://fm2012.verifythis.org/challenges
5
6This is a problem in 2012 as an advance problem for LCP
7Here is the description:
8Together with a suffix array, LCP can be used to solve interesting text
9problems, such as finding the longest repeated substring (LRS) in a text.
10
11A suffix array (for a given text) is an array of all suffixes of the
12text. For the text [7,8,8,6], the suffix array is
13[[7,8,8,6],
14 [8,8,6],
15 [8,6],
16 [6]]
17
18Typically, the suffixes are not stored explicitly as above but
19represented as pointers into the original text. The suffixes in a suffix
20array are sorted in lexicographical order. This way, occurrences of
21repeated substrings in the original text are neighbors in the suffix
22array.
23
24For the above, example (assuming pointers are 0-based integers), the
25sorted suffix array is:
26
27[3,0,2,1]
28*/
29
30#include <stdlib.h>
31#include <stdio.h>
32#include <civlc.cvh>
33#include <assert.h>
34
35$input int N_BOUND = 4;
36$input int N;
37$input int X1[N];
38$assume (N < N_BOUND && N >= 0);
39
40int lcp1(int *arr, int n, int x, int y) {
41 int l=0;
42
43 while (x+l<n && y+l<n && arr[x+l]==arr[y+l]) {
44 l++;
45 }
46 return l;
47}
48
49int compare(int *a, int n, int x, int y) {
50 if (x == y) return 0;
51 int l = 0;
52
53 while (x+l<n && y+l<n && a[x+l] == a[y+l]) {
54 l++;
55 }
56
57 if (x+l == n) return -1;
58 if (y+l == n) return 1;
59 if (a[x+l] < a[y+l]) return -1;
60 if (a[x+l] > a[y+l]) return 1;
61
62 return -2;
63}
64
65void sort(int *a, int n, int *data) {
66 for (int i = 0; i < n + 0; i++) {
67 for(int j = i; j > 0 && compare(a, n, data[j - 1], data[j]) > 0; j--) {
68 int b = j - 1;
69 int t = data[j];
70
71 data[j] = data[b];
72 data[b] = t;
73 }
74 }
75}
76
77int lcp2(int *a, int n, int index, int* suffixes){
78 return lcp1(a,n,suffixes[index], suffixes[index-1]);
79}
80
81/**
82result[0]: index
83result[1]: length
84*/
85void lrs(int* a, int n, int *result) {
86 int suffixes[n];
87
88 for (int i=0; i<n; i++) {
89 suffixes[i] = i;
90 }
91 sort(a, n, suffixes);
92 for (int i=1; i<n; i++) {
93 int len = lcp2(a, n, i,suffixes);
94
95 if (len > result[1]) {
96 result[0] = suffixes[i];
97 result[1] = len;
98 }
99 }
100}
101
102int main(){
103 int* result = (int*)malloc(2* sizeof(int));
104
105 result[0] = 0;
106 result[1] = 0;
107 lrs(X1, N, result);
108
109 int index = result[0];
110 int maxLen = result[1];
111
112 if (N > 1) {
113 $assert($exists {int k | k >= 0 && k <= N - maxLen && k != index}(
114 $forall {i = 0 .. maxLen-1} X1[k+i] == X1[index+i]
115 ));
116 } else {
117 $assert(index == 0 && maxLen == 0);
118 }
119 free(result);
120 return 0;
121}
Note: See TracBrowser for help on using the repository browser.