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
RevLine 
[724ceb2]1/*
[0ae124a]2author: Yihao
[e769359]3
4Link(LCP.zip): http://fm2012.verifythis.org/challenges
[724ceb2]5
[e769359]6This is a problem in 2012 as an advance problem for LCP
[724ceb2]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
[e769359]22array.
[724ceb2]23
24For the above, example (assuming pointers are 0-based integers), the
25sorted suffix array is:
26
27[3,0,2,1]
[f7e5282]28
29command: civl verify lrs.c
30
31result: the problem is solved
[724ceb2]32*/
33
[63a79f0]34#include <stdlib.h>
35#include <stdio.h>
36#include <civlc.cvh>
37#include <assert.h>
38
[ae55290]39$input int N_BOUND = 4;
40$input int N;
[63a79f0]41$input int X1[N];
[ae55290]42$assume (N < N_BOUND && N >= 0);
[63a79f0]43
[0ae124a]44int lcp1(int *arr, int n, int x, int y) {
[63a79f0]45 int l=0;
[e769359]46
[63a79f0]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) {
[0ae124a]70 for (int i = 0; i < n + 0; i++) {
[63a79f0]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];
[e769359]74
[63a79f0]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*/
[0ae124a]89void lrs(int* a, int n, int *result) {
[63a79f0]90 int suffixes[n];
[e769359]91
[0ae124a]92 for (int i=0; i<n; i++) {
[63a79f0]93 suffixes[i] = i;
94 }
95 sort(a, n, suffixes);
[0ae124a]96 for (int i=1; i<n; i++) {
[63a79f0]97 int len = lcp2(a, n, i,suffixes);
[e769359]98
[0ae124a]99 if (len > result[1]) {
[63a79f0]100 result[0] = suffixes[i];
101 result[1] = len;
102 }
103 }
104}
105
106int main(){
107 int* result = (int*)malloc(2* sizeof(int));
[e769359]108
[63a79f0]109 result[0] = 0;
110 result[1] = 0;
111 lrs(X1, N, result);
[e769359]112
[63a79f0]113 int index = result[0];
114 int maxLen = result[1];
[e769359]115
[0ae124a]116 if (N > 1) {
[ae55290]117 $assert($exists {int k | k >= 0 && k <= N - maxLen && k != index}(
118 $forall {i = 0 .. maxLen-1} X1[k+i] == X1[index+i]
[63a79f0]119 ));
[0ae124a]120 } else {
[ae55290]121 $assert(index == 0 && maxLen == 0);
122 }
[63a79f0]123 free(result);
124 return 0;
125}
Note: See TracBrowser for help on using the repository browser.