Diff algorithm, i.e. shortest edit-graph path - c

I am trying to understand the algorithm from the famous 'diff' paper here, running on characters in the two command-line arguments. However, my code does not produce the results I expect. I've written the algorithm to match their variables to the extent possible:
$ ./diff abbcabba cbabac #Hmm.. I think it should be 5
SES: 10
$ ./diff abcdefg abcdefg #0! Great!
SES: 0
$ ./diff abcXefg abcYefg # 2 seems reasonable
SES: 2
$ ./diff abcXefg abcefg # clearly wrong
SES: 7
Here is my code (Sorry about the wall of code):
a = argv[1];
b = argv[2];
alen = strlen(a);
blen = strlen(b);
tlen = alen + blen;
maxd = tlen;
vp = (int *)calloc(2 * maxd + 1, sizeof(int));
// How I'm thinking about pointer arithmetic:
// vp in [0, 2*maxd + 1) == [0, 2*maxd]
// v in [-maxd, maxd + 1) == [-maxd, maxd]
v = vp + maxd;
v[1] = 0;
for (D = 0; D <= maxd; D++) {
for (k = -D; k <= D; k += 2) {
if (k == -D || (k != D && v[k-1] < v[k+1])) {
x = v[k + 1];
} else {
x = v[k - 1] + 1;
}
y = x - k;
while (x < alen && y < blen && a[x] == b[x]) {
x++;
y++;
}
v[k] = x;
if (x >= alen && y >= blen) {
printf("SES: %d\n", D);
goto out;
}
}
}
printf("Nothing found. SES > %d\n", maxd);
Any idea where the flaw is here? I've been finding it incredibly hard to search online for this problem...

It seems that the problem is in this line:
while (x < alen && y < blen && a[x] == b[x]) {
Here b[x] should be b[y], which gives:
while (x < alen && y < blen && a[x] == b[y]) {
With this change the results for your examples are 6, 0, 2 and 1. This seems to be accurate.

Related

Not sure how to deal with the error "excess elements in array initializer"

In line 10 I cannot find out where my problem is at first. I place int a[100][100]={0} but the cpu speed is stuck.
Then, I try to change it into a[n][n] but no output is shown.
Last, I try to change it again as if it resembles the original ones.
However, nothing works instead of a new question.
#include<stdio.h>
int main() {
int n;
while (scanf("%d", &n)) {
n *= 2;
int x = 0, y = 0, num = 1;
int a[n][n] = {0};
a[x][y] = num++;
while (n * n >= num) //定義陣列
{
while (y + 1 < n && !a[x][y + 1]) //向右
a[x][++y] = num++;
while (x + 1 < n && !a[x + 1][y]) //向下
a[++x][y] = num++;
while (y - 1 >= 0 && !a[x][y - 1]) //向左
a[x][--y] = num++;
while (x - 1 >= 0 && !a[x - 1][y]) //向上
a[--x][y] = num++;
}
for (x = 0; x < n; x++) //print 陣列
{
for (y = 0; y < n; y++) {
if (y != n - 1) {
printf("%d ", a[x][y]);
} else {
printf("%d", a[x][y]);
}
}
printf("\n");
}
break;
}
return 0;
}
At least this problem:
Variable Length Arrays (VLA) cannot be initialized via the C standard.
Alternate, assign via memset() after defining a.
// int a[n][n]={0};
int a[n][n];
memset(a, 0, sizeof a);

Malloc aborting with specific inputs

This is my first time posting here so I apologize if I'm not following the right etiquette. I also tried searching for answers but to no avail.
Basically, I have this function for a greedy coin change algorithm which takes as input some int. In my function I return a malloc'd array containing each coin. While it works for the most part, for some reason any coin value which produces 5, 9, ... (+4) coins as optimal distribution, ie, 9 would be (5 + 1 + 1 +1 + 1), or 650 which is 13 coins of 50 each, causes the program to abort with this message:
hello: malloc.c:2401: sysmalloc: Assertion `(old_top == initial_top (av) &&
old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse
(old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted (core dumped)
However, every coin distribution that isn't 5 or 5+4+... works. Not sure what to do.
This is the function:
int* greedyAlg(int value)//computes and returns the optimal (minimum) number of denominations for a given value for US currency
{
//denominations
int one = 1, five = 5, ten = 10, twenty = 20, fifty = 50;
int x5 = 0, x4 = 0, x3 = 0, x2 = 0, x1 = 0;
int count = 0;
//int[] denom;
while(value != 0)
{
if(value >= fifty)
{
value -= fifty;
count++;
x5++;
/*while(value >= fifty)
{
// int *i = &fifty;
value-=fifty;
count++;
x5++;
}*/
}
else if(value < fifty && value >= twenty)
{
value -= twenty;
count++;
x4++;
}
else if(value < twenty && value >= ten)
{
value -= ten;
count++;
x3++;
}
else if(value < ten && value >= five)
{
value -= five;
count++;
x2++;
}
else if(value < five && value >= one)
{
value -= one;
count++;
x1++;
}
}
//printf("Optimal denominations: ");
int* denom = malloc(sizeof(int)*(count + 1));
//int* denom = (int *)calloc(count + 1,sizeof (int));
denom[0]=count;
for(int i = 1; i<= (x5 + 1); i++){
denom[i] = fifty;
}
for(int i= (x5 + 1); i<=(x5 + x4) + 1; i++){
denom[i] = twenty;
}
for(int i = (x5 + x4) + 1; i <= ( x5 + x4 +x3 ) + 1; i++){
denom[i] = ten;
}
for(int i = (x5 + x4 + x3) + 1; i <= (x5 + x4 + x3 + x2) + 1; i++){
denom[i] = five;
}
for(int i = (x5 + x4 + x3 + x2) + 1; i <= (x5 + x4 + x3 + x2 + x1) + 1; i++){
denom[i]=one;
}
return denom;
free(&denom);
//return count;
}
And this is how I'm printing it:
//prints elements of array created by (greedy) coin change algorithm
void printGreedyArr(int arr[], size_t count)
{
for(int i = 1; i <= count; i++)
{
printf("%s%d%s, ","[",arr[i],"]");
}
printf("\n%s %d\n","count was",count);
}
I call it with the 0th index which holds the length like so:
printGreedyArr(greedyAlg(x),greedyAlg(x)[0]);
(In my code I set up a loop with x as user input to test)
I can post any other relevant details if need be.
Assuming count equals x5+x4+x3+x2+x1, you've got an off-by-one error:
for(int i=(x5+x4+x3+x2)+1; i<=(x5+x4+x3+x2+x1)+1; i++){
Should probably be:
for(int i=(x5+x4+x3+x2)+1; i<(x5+x4+x3+x2+x1)+1; i++){
Also similarly for the other for loops. Note the termination condition has changed from <= to <.
Also:
return denom;
free(&denom);
That free() will never be executed, and also the & should be removed from before the denom if you place it elsewhere.

How can I implement the knapsack algorithm where the index of the array represent the weight of the item

I am trying to implement an algorithm to solve the Knapsack problem:
cst = 1;
for (j = 0; j < 200; j++) {
if (kk - cst < 0) {
continue;
cst++;
}
for (i = kk - cst; i >= 0; --i) {
C[i + cst] = max(C[i + cst], C[i] + index[cst]);
}
cst++;
}
The index array has the values of respective items represented by index of the array. I want to know where I'm going wrong.
In your code
if(kk-cst < 0)
{
continue;
cst++;
}
is wrong. the cst++ will never be executed. Please check and change your logic accordingly.
The increment to cst is unreachable code here. Swap the two lines
if (kk - cst < 0) {
cst++;
continue;
}
A simple dynamic programming knapsack implementation would be
int KnapSack(int W, int wt[], int val[], int n) {
int i, w;
int K[n + 1][W + 1];
for (i = 0; i <= n; i++) {
for (w = 0; w <= W; w++) {
if (i == 0 || w == 0) K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else K[i][w] = K[i - 1][w];
}
}
return K[n][W];
}
as listed in http://www.geeksforgeeks.org/dynamic-programming-set-10-0-1-knapsack-problem/

Bubble sort not working at all, if statement not executing

I'm working on a program which is going to be used to sort students test scores and eventually retrieve the mean, median, and the mode of the scores. For some strange reason my bubble sort is not working.. I'm unsure why.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
int main (void)
{
char vStudents[N][15], trans = 'y', vTemp2;
int vScores[N], vTemp, x, i = 0, j=0, NewN;
printf("\t\tWhatsamatta U Scores System\n\n");
do
{
printf("Please Enter Students Name: ");
gets(vStudents[i]);
trans = 'N';
while (trans == 'N')
{
printf("Enter Students Score: ");
scanf("%d", &vScores[i]);
fflush(stdin);
if (vScores[i] >= 0 & vScores[i] <= 100)
trans = 'y';
else
printf("Score is invalid, please re-enter score.\n");
}
i++;
j++;
} while (j != N);
for(x = 0; x < N - 1; x++)
{
if ((x < N - 1) && (vScores[i] > vScores[i + 1]))
{
vTemp = vScores[i];
vScores[i] = vScores[i + 1];
vScores[i + 1] = vTemp;
x = -1;
}
}
printf("%d %d %d\n\n", vScores[0], vScores[1], vScores[2]);
system("Pause");
return 0;
Any help would be useful, thanks in advance!
At least one error:
for(x = 0; x < vScores[N] - 1; x++)
{
if ((x < vScores[N] - 1) && (vScores[N] > vScores[N + 1]))
{
should be
for(x = 0; x <N - 1; x++)
{
if ((x < N - 1) && (vScores[N] > vScores[N + 1]))
{
//^^you should not compare index x with array elements
N is always 3. if we replace N in your code with 3, does it still make sense?
for(x = 0; x < vScores[3] - 1; x++)
{
if ((x < vScores[3] - 1) && (vScores[3] > vScores[3 + 1]))
{
vTemp = vScores[3];
vScores[3] = vScores[3 + 1];
vScores[3 + 1] = vTemp;
x = -1;
}
}
Ok, now that it is this:
for(x = 0; x < N - 1; x++)
{
if ((x < N - 1) && (vScores[i] > vScores[i + 1]))
{
vTemp = vScores[i];
vScores[i] = vScores[i + 1];
vScores[i + 1] = vTemp;
x = -1;
}
}
Ask, when does i change?

Triangulation algorithm

I've decided to create a simple demo, dividing a polygon into triangle set. Here what i've got so far:
A sequential vertex list is given (P1) forming polygon edges (polygon is not convex in most cases); a triangle set is needed
Loop through all the vertices within the polygon P1 and find the one (v), which will satisfy next clauses:
remove v from polygon and save the new one to P2 previous vertex to v
connected to its next one form a
line which do not cross any of P2
edges
v is not inside P2
If these are satisfied, we can replace P1 with (P2 + triangle( prev(v), v, next(v)) ) and repeat this action until P1 contains more than 3 vertices.
So, the questions are: is this algorithm correct and how it could be implemented using C / C++ using the most obvious and simple way?
I think you're describing the ear clipping method. There's code for that method at http://cs.smith.edu/~orourke/books/ftp.html ; it's the code described in the book Computational Geometry in C.
Seems that i'm done with this algorithm implementation. Please, verify it someone. Thanks!
typedef struct Point
{
float x, y;
};
class MooPolygon
{
private:
vector<Point> points;
int isVertexEar(int n, const vector<Point> &p)
{
return (isVertexInsideNewPoly(n, p) && !isEdgeIntersect(n, p));
}
int isEdgeIntersect(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 0, cnt = a.size(), prev = (cnt + (n - 1)) % cnt, next = n % cnt;
Point v1 = a[prev], v2 = a[next];
for (size_t i = 0, j = cnt - 1; i < cnt; j = i++)
{
if (prev == i || prev == j || next == i || next == j)
continue;
Point v4 = a[j], v3 = a[i];
float denominator = ((v4.y - v3.y) * (v2.x - v1.x)) - ((v4.x - v3.x) * (v2.y - v1.y));
if (!denominator)
continue;
float ua = (((v4.x - v3.x) * (v1.y - v3.y)) - ((v4.y - v3.y) * (v1.x - v3.x))) / denominator;
float ub = (((v2.x - v1.x) * (v1.y - v3.y)) - ((v2.y - v1.y) * (v1.x - v3.x))) / denominator;
//float x = v1.x + (ua * (v2.x - v1.x)), y = v1.y + (ua * (v2.y - v1.y));
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
{
c = 1;
break;
}
}
return c;
}
int isVertexInsideNewPoly(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 1;
for (size_t i = 0, j = a.size() - 1; i < a.size(); j = i++)
{
if ((((a[i].y <= v.y) && (v.y < a[j].y)) || ((a[j].y <= v.y) && (v.y < a[i].y))) && (v.x > (a[j].x - a[i].x) * (v.y - a[i].y) / (a[j].y - a[i].y) + a[i].x))
c = !c;
}
return c;
}
float dist(Point a, Point b)
{
return sqrt( ((a.x - b.x) * (a.x - b.x)) + (((a.y - b.y) * (a.y - b.y))) );
}
public:
void push(const Point &p)
{
for (size_t i = 0; i < points.size(); i++)
{
if (dist(points[i], p) < 7.f)
{
points.push_back(points[i]);
return;
}
}
points.push_back(p);
}
void pop()
{
if (points.size() > 0)
points.pop_back();
}
void clear()
{
points.clear();
}
Point v(int index)
{
return points[index];
}
size_t size()
{
return points.size();
}
void triangulate()
{
vector<Point> a;
for (size_t i = 0; i < points.size(); i++)
{
a.push_back(points[i]);
}
points.clear();
for (size_t t = a.size() - 1, i = 0, j = 1; i < a.size(); t = i++, j = (i + 1) % a.size())
{
if (a.size() == 3)
{
points.push_back(a[0]);
points.push_back(a[1]);
points.push_back(a[2]);
break;
}
if (isVertexEar(i, a))
{
points.push_back(a[t]);
points.push_back(a[i]);
points.push_back(a[j]);
a.erase(a.begin() + i, a.begin() + i + 1);
t = a.size() - 1;
i = 0;
j = 1;
}
}
}
};
The code has an error on the line below. The line is in the for loop in the push() function of your class:
points.push_back(points[i]);
You are not passing the pushed Point, but an empty element of the vector itself. I changed the line to
points.push_back(p);
and it worked.

Resources