private static SMSRD SMS(DiffData DataA, int LowerA, int UpperA, DiffData DataB, int LowerB, int UpperB, int[] DownVector, int[] UpVector)
{
SMSRD ret;
int MAX = DataA.Length + DataB.Length + 1;
int DownK = LowerA - LowerB; // the k-line to start the forward search
int UpK = UpperA - UpperB; // the k-line to start the reverse search
int Delta = (UpperA - LowerA) - (UpperB - LowerB);
bool oddDelta = (Delta & 1) != 0;
// The vectors in the publication accepts negative indexes. the vectors implemented here are 0-based
// and are access using a specific offset: UpOffset UpVector and DownOffset for DownVektor
int DownOffset = MAX - DownK;
int UpOffset = MAX - UpK;
int MaxD = ((UpperA - LowerA + UpperB - LowerB) / 2) + 1;
// init vectors
DownVector[DownOffset + DownK + 1] = LowerA;
UpVector[UpOffset + UpK - 1] = UpperA;
for (int D = 0; D <= MaxD; D++) {
// Extend the forward path.
for (int k = DownK - D; k <= DownK + D; k += 2) {
// find the only or better starting point
int x, y;
if (k == DownK - D) {
x = DownVector[DownOffset + k + 1]; // down
} else {
x = DownVector[DownOffset + k - 1] + 1; // a step to the right
if ((k < DownK + D) && (DownVector[DownOffset + k + 1] >= x))
x = DownVector[DownOffset + k + 1]; // down
}
y = x - k;
// find the end of the furthest reaching forward D-path in diagonal k.
while ((x < UpperA) && (y < UpperB) && (DataA.data[x] == DataB.data[y])) {
x++; y++;
}
DownVector[DownOffset + k] = x;
// overlap ?
if (oddDelta && (UpK - D < k) && (k < UpK + D)) {
if (UpVector[UpOffset + k] <= DownVector[DownOffset + k]) {
ret.x = DownVector[DownOffset + k];
ret.y = DownVector[DownOffset + k] - k;
return (ret);
}
}
}
// Extend the reverse path.
for (int k = UpK - D; k <= UpK + D; k += 2) {
// find the only or better starting point
int x, y;
if (k == UpK + D) {
x = UpVector[UpOffset + k - 1];
} else {
x = UpVector[UpOffset + k + 1] - 1;
if ((k > UpK - D) && (UpVector[UpOffset + k - 1] < x))
x = UpVector[UpOffset + k - 1];
}
y = x - k;
while ((x > LowerA) && (y > LowerB) && (DataA.data[x - 1] == DataB.data[y - 1])) {
x--; y--; // diagonal
}
UpVector[UpOffset + k] = x;
// overlap ?
if (!oddDelta && (DownK - D <= k) && (k <= DownK + D)) {
if (UpVector[UpOffset + k] <= DownVector[DownOffset + k]) {
ret.x = DownVector[DownOffset + k];
ret.y = DownVector[DownOffset + k] - k;
return (ret);
}
}
}
}
throw new Exception ("function return path");
}