source: CIVL/examples/verifyThisProblems/lrs.c@ 0e12c94

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 0e12c94 was f7e5282, checked in by Yihao Yan <yihaoyan1@…>, 10 years ago

minor changes

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

  • Property mode set to 100644
File size: 2.6 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
29command: civl verify lrs.c
30
31result: the problem is solved
32*/
33
34#include <stdlib.h>
35#include <stdio.h>
36#include <civlc.cvh>
37#include <assert.h>
38
39$input int N_BOUND = 4;
40$input int N;
41$input int X1[N];
42$assume (N < N_BOUND && N >= 0);
43
44int lcp1(int *arr, int n, int x, int y) {
45 int l=0;
46
47 while (x+l<n && y+l<n && arr[x+l]==arr[y+l]) {
48 l++;
49 }
50 return l;
51}
52
53int compare(int *a, int n, int x, int y) {
54 if (x == y) return 0;
55 int l = 0;
56
57 while (x+l<n && y+l<n && a[x+l] == a[y+l]) {
58 l++;
59 }
60
61 if (x+l == n) return -1;
62 if (y+l == n) return 1;
63 if (a[x+l] < a[y+l]) return -1;
64 if (a[x+l] > a[y+l]) return 1;
65
66 return -2;
67}
68
69void sort(int *a, int n, int *data) {
70 for (int i = 0; i < n + 0; i++) {
71 for(int j = i; j > 0 && compare(a, n, data[j - 1], data[j]) > 0; j--) {
72 int b = j - 1;
73 int t = data[j];
74
75 data[j] = data[b];
76 data[b] = t;
77 }
78 }
79}
80
81int lcp2(int *a, int n, int index, int* suffixes){
82 return lcp1(a,n,suffixes[index], suffixes[index-1]);
83}
84
85/**
86result[0]: index
87result[1]: length
88*/
89void lrs(int* a, int n, int *result) {
90 int suffixes[n];
91
92 for (int i=0; i<n; i++) {
93 suffixes[i] = i;
94 }
95 sort(a, n, suffixes);
96 for (int i=1; i<n; i++) {
97 int len = lcp2(a, n, i,suffixes);
98
99 if (len > result[1]) {
100 result[0] = suffixes[i];
101 result[1] = len;
102 }
103 }
104}
105
106int main(){
107 int* result = (int*)malloc(2* sizeof(int));
108
109 result[0] = 0;
110 result[1] = 0;
111 lrs(X1, N, result);
112
113 int index = result[0];
114 int maxLen = result[1];
115
116 if (N > 1) {
117 $assert($exists {int k | k >= 0 && k <= N - maxLen && k != index}(
118 $forall {i = 0 .. maxLen-1} X1[k+i] == X1[index+i]
119 ));
120 } else {
121 $assert(index == 0 && maxLen == 0);
122 }
123 free(result);
124 return 0;
125}
Note: See TracBrowser for help on using the repository browser.