The Damerau-Levenshtein distance in C - c

I'm working on a spell checker and I need to optimize the Damerau-Levenshtein distance. For example... when 2 words have a distance greater than 3 (or a limit), I need to break the function. This will reduce the execution time. i was thinking veryfy when the min is greater than 3, but through the proccess, sometimes the min is greater, because Damerau-Levenshtein distance works on a table of min values. I think to add a condition like i == j, but when a word is longer than the other it fail. The code is version from Internet.
#include <stdio.h>
#include "levenshtein.h"
#include <stdlib.h>
#include <string.h>
int min_(int a, int b){
return (a<b)?a:b;
}
int dist_dlevenshtein(char* p_string1, char* p_string2, int umbral)
{
int l_string_length1 = strlen(p_string1);
int l_string_length2 = strlen(p_string2);
int d[l_string_length1+1][l_string_length2+1];
int i;
int j;
int l_cost;
for (i = 0;i <= l_string_length1;i++)
{
d[i][0] = i;
}
for(j = 0; j<= l_string_length2; j++)
{
d[0][j] = j;
}
for (i = 1;i <= l_string_length1;i++)
{
for(j = 1; j<= l_string_length2; j++)
{
if( p_string1[i-1] == p_string2[j-1] )
{
l_cost = 0;
}
else
{
l_cost = 1;
}
d[i][j] = min_(
d[i-1][j] + 1, // delete
min_(d[i][j-1] + 1, // insert
d[i-1][j-1] + l_cost) // substitution
);
if( (i > 1) &&
(j > 1) &&
(p_string1[i-1] == p_string2[j-2]) &&
(p_string1[i-2] == p_string2[j-1])
)
{
d[i][j] = min_(d[i][j],d[i-2][j-2] + l_cost); // transposition
}
}
}
return d[l_string_length1][l_string_length2];
}```

Related

How the counting is conducted in this function?

See the function search below, it returns count but I don't see where this variable count acts/works (the function is found in a library , click here to download the source code, you will find kmp.c in \source\algos):
#include "include/define.h"
#include "include/main.h"
void preKmp(unsigned char *x, int m, int kmpNext[]) {
int i, j;
i = 0;
j = kmpNext[0] = -1;
while (i < m) {
while (j > -1 && x[i] != x[j])
j = kmpNext[j];
i++;
j++;
if (i<m && x[i] == x[j])
kmpNext[i] = kmpNext[j];
else
kmpNext[i] = j;
}
}
int search(unsigned char *x, int m, unsigned char *y, int n) {
int i, j, kmpNext[XSIZE], count;
/* Preprocessing */
BEGIN_PREPROCESSING
preKmp(x, m, kmpNext);
END_PREPROCESSING
/* Searching */
BEGIN_SEARCHING
count = 0;
i = j = 0;
while (j < n) {
while (i > -1 && x[i] != y[j])
i = kmpNext[i];
i++;
j++;
if (i >= m) {
OUTPUT(j - i);
i = kmpNext[i];
}
}
END_SEARCHING
return count;
}
Can any one explain how it works?
The OUTPUT macro that is defined in ./source/algos/include/define.h looks like this:
#define OUTPUT(j) count++
And in search you have
if (i >= m) {
OUTPUT(j - i); // <- here
i = kmpNext[i];
}
which explains how count is updated.

When I print all the variables of a list it gives me an unexpected value that is inconsistent in c. Can you tell me what went wrong?

Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
struct rule {
int id;
int allow[3];
};
char key_id[10] = { '\\', '/', '`', '#', '_', '*', '#', '%', '>', '<' };
struct rule def_rule(int id, int *arr, int arr_size) {
struct rule temp;
temp.id = id;
for (int i; i < arr_size; i++) {
temp.allow[i] = arr[i];
}
return temp;
}
void collapse(int *map, int map_w, int map_h) {
srand(time(0));
//finding adj indexes
int nth;
int wst;
int sth;
int est;
int map_a = map_h * map_w;
int dir[4] = { nth, wst, sth, est };
for (int i = 0; i < map_w * map_h; i++) {
if ((i - 4) >= 0) {
nth = map[i - 4];
}
if ((i + 1) < map_a) {
wst = map[i + 1];
}
if (i + 4 <= 15) {
sth = map[i + 4];
}
if (i - 1 >= 0) {
est = map[i - 1];
}
}
}
void main(void) {
//define some rules
struct rule rules[0];
int arr[3] = { 0, 1, 2 };
rules[0] = def_rule(0, arr, 3);
//collapse
int map_w = 4;
int map_h = 4;
int map[map_w * map_h];
for(int i = 0; i < 15; i++) {
map[i] = 0;
}
collapse(map, map_w, map_h);
for (int i = 0; i < map_w; i++) {
for (int j = 0; j < map_h; j++) {
printf(" %d ", map[(i * 4) + j]);
}
printf("\n");
}
}
When I compile it it doesn't give me any errors or warnings and I think when I access map[i] I am not out of range.
However it gives me this output in my terminal:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 21896
When I run it again 21896 changes to a different number.
I am trying to turn zeros in an array into other numbers depending on some rules.
I made the code for checking adjacency such that it doesn't change the variable map.
The only time variable map is changed is when I iterate over it to set everything to 0.
I have tested all the code and it seemed to work however when I added structs it started to do this.
Edit:
The problem was that I was accessing all but the last index of map so I was trying to print an undefined variable I think.
The initialization loop for map is incorrect: you never initialize the last element. You should use:
int map[map_w * map_h];
for (int i = 0; i < map_w * map_h; i++) {
map[i] = 0;
}

Display every combination of a given array in C

I'm trying to write a program with my teacher that displays every possible combination of n numbers (for example, if n = 2, it displays from 01,02,03 etc.. to 89.) I'm using multiple tabs, incrementing the last one to go up to 9, and then incrementing the one just before so I can go from 09 to 12, and so on, but I don't really know how to proceed.
I'm quite new to C programming, so feel free to tell me if anything can be made better.
#include <unistd.h>
ft_putchar(char c)
{
write(1, &c, 1);
}
ft_affichage(int tab[], int nb)
{
int index = 0;
while(index < nb)
{
ft_putchar(tab[index] + 48);
ft_putchar(',');
ft_putchar(' ');
index++;
}
}
int ft_end(int tab[], int nb)
{
int index;
for (index = 0; index < nb ; index++)
{
if (tab[index] != 9 - nb + 1 + index)
{
return 0;
}
}
return 1;
}
void ft_print_comb_n(int nb)
{
int comb[nb];
int index = 0;
// init comb
while(index < nb)
{
comb[index] = index;
index++;
}
ft_affichage(comb, nb);
while(ft_end(comb, nb) == 0)
{
// incrementer comb;
int i = nb - 1;
int max = 9;
while(comb[0] != 9 - nb + 1 + index && comb[nb- 1] != 9 )
{
comb[nb - 1]++;
}
{
}
}
//afficher comb;
ft_affichage(comb, nb);
}
int main(void)
{
ft_print_comb_n(2);
return 0;
}
so feel free to tell me if anything can be made better
Depending on the requirements your teacher gave, the solution below is possible and very simple. It makes use of printf feature that allow to print a variable number of digit of an integer number with leading zero.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void ft_print_comb_n(int nb)
{
// Compute the limit based on the number of digits
int maxN = (int)(pow(10, nb) + 0.5);
for (int i = 0; i < maxN; i++)
printf("%0*d\n", nb, i);
}
int main(int argc, char *argv[])
{
ft_print_comb_n(3);
return 0;
}
This is based on some old code of mine, but I've forgotten how it works.
int ft_debut(int tab[], int n, int k)
{
if (k <= 0 || k > n)
{
return 0;
}
while (k--)
{
tab[k] = k;
}
return 1;
}
int ft_suivant(int tab[], int n, int k)
{
int i = k;
if (k < 0 || k > n)
{
return 0;
}
while (i--)
{
int x = tab[i];
if (x < --n)
{
do
{
tab[i++] = ++x;
}
while (i < k);
return 1;
}
}
return 0;
}
void ft_print_comb_n(int nb)
{
int comb[nb];
int va;
for (va = ft_debut(comb, 10, nb); va; va = ft_suivant(comb, 10, nb))
{
ft_affichage(comb, nb);
}
}
ft_debut fills tab[] with the initial combination (tab[i] = i for i from 0 to k) if the n and k parameters are valid.
ft_suivant "increments" the combination in tab[] if the n and k values are valid and the combination in tab[] has not yet reached the maximum value. i scans backwards from k-1 to 0, stopping when a tab[i] that can be incremented (the maximum allowed value for tab[i] is n-k+i) has been reached or when tab[0] is already at its maximum allowed value (so tab[] already contains the final combination). If a suitable tab[i] is found, it is incremented by 1, and any remaining elements from tab[i+1] up to tab[k-1]` are set to one more than their preceding element.
Example of ft_suivant for n=10, k=2, tab[0]=2, tab[1]=9:
int i = k; — i=2
while (i--) — true, i=1
{
int x = tab[i]; — x=9 (tab[1])
if (x < --n) — n=9, false
}
while (i--) — true, i=0
{
int x = tab[i]; — x=2 (tab[0])
if (x < --n) — n=8, true
{
do
{
tab[i++] = ++x; — x=3, tab[0]=3, i=1
}
while (i < k); — true
do
{
tab[i++] = ++x; — x=4, tab[1]=4, i=2
}
while (i < k); — false
return 1;
The combination has been successfully "incremented" from {2, 9} to {3, 4}.

How to fix C2109:subscript requires array or pointer type

I'm having problem with some homework here. I'm totally newbie in programming, so anything should be helpful. I don't know how to fix C2109 error in C.
As you see, I have a float array that I have to sort, and look for the number 55.5
#include <stdio.h>
#include <conio.h>
#include <math.h>
main() {
float mr1[30], pom = 0;
int i, indeks = -1, j, n, start, end, mid;
printf("Enter length of array n<=30:\n");
scanf("%d", &n);
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
scanf("%f", &mr1[i]);
}
for (i = 0; i <n - 1; i++) {
for (j = i + 1; j < n; j++)
if (mr1[i] > mr1[j]) {
mr1[i] = pom;
mr1[i] = mr1[j];
mr1[j] = mr1[i];
}
}
start = 0;
end = n - 1;
do {
mid = (start + end) / 2
if (mr1[mid] == 55.5) {
indeks = mid;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
kraj = mid - 1;
}
}
} while (poc <= kraj && indeks < 0);
printf("Number 55.5 is on indeks:\n");
printf("%d", indeks);
}
There are multiple issues in the code:
The swapping code is incorrect. It should read:
pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
you did not translate all poc as start and kraj as end.
There is a missing ; after mid=(start+end)/2
main() is an obsolete prototype for the main function, you should specify the return type int.
the do / while loop will not handle an empty array correctly. You should use a while loop instead. As a rule of thumb, do / while loop are very often incorrect, sometimes in subtile ways.
Here is a corrected version:
#include <stdio.h>
int main() {
float mr1[30];
int n, i, j, index, start, end, mid;
printf("Enter length of array n<=30:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 30) {
printf("invalid length\n");
return 1;
}
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
if (scanf("%f", &mr1[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
/* sort the array with simplistic swap sort */
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (mr1[i] > mr1[j]) {
/* swap entries */
float pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
}
}
}
/* try and locate 55.5 with binary search */
index = -1;
start = 0;
end = n - 1;
while (start <= end) {
mid = (start + end) / 2;
if (mr1[mid] == 55.5) {
index = mid;
break;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
end = mid - 1;
}
}
}
if (index >= 0) {
printf("Number 55.5 is at index %d\n", index);
} else {
printf("Number 55.5 is not present\n");
}
return 0;
}
Note also that 55.5 happens to have an exact representation as a float, but comparing floating point values with == may yield surprising results when the approximate value is not exactly identical to the expected value.

simulation algorithm implementation in C/C++

Let a row of 8000 lamps. Initially, only the one located to the left is lit.
Then, every second, the following operation is performed: each lamp changes state (on or off) if the one on its left was lit a second before. The leftmost lamp stays on all the time. This operation is instantaneous.
The process stops when the lamp at the right end lights for the first time.
How many lights are on?
My following implementation of the problem is false, can you help me?
#include <cstdio>
int t[8001][2];
int main()
{
t[1][0] = 1;
t[1][1] = 1;
int cpt1 = 0, ip = 0;
while (t[8000][0] != 1 && t[8000][1] != 1)
{
ip++;
for (int j=2;j<8001;j++)
{
if(t[j-1][!(ip&1)])
t[j][(ip & 1)] = !t[j][!(ip & 1)];
}
}
for(int j = 1;j < 8001; j++)
cpt1 += t[j][1];
printf("cpt=%d\n", cpt1);
}
Code is missing an update when the left does not change.
Code simplified (zero based offset, use of bool) and corrected below
#include<stdbool.h>
#include<stdio.h>
#define N 8000
bool t[N][2];
int main(void) {
t[0][0] = true;
t[0][1] = true;
int ip = 0;
while (t[N - 1][0] == 0 && t[N - 1][1] == 0) {
ip = !ip;
for (int j = 1; j < N; j++) {
if (t[j - 1][!ip]) {
t[j][ip] = !t[j][!ip];
} else {
t[j][ip] = t[j][!ip]; // add
}
}
}
int cpt1 = 0;
for (int j = 0; j < N; j++) {
cpt1 += t[j][1];
}
printf("N=%d cpt=%d\n", N, cpt1);
return 0;
}
Output
N=8000 cpt=2048
the following proposed code:
cleanly compiles
uses C header files rather than C++ header files
performs the desired operation, but not the fastest possible algorithm
is liberally commented
And now the proposed code:
#include <stdio.h>
int t1[8000]; // initially all zeros
int t2[8000];
int main( void )
{
// setup initial conditions
int numLitLights = 0;
t1[0] = 1;
// while stop condition not true
while ( t1[7999] != 1 )
{
// make one pass through lamps
// update values
for (int j=0; j<7999; j++)
{
if( t1[j] )
{
t2[j+1] = ( t1[j+1] )? 0 : 1;
}
}
// update original
for( int j=0; j< 8000; j++ )
{
t1[j] = t2[j];
}
}
// count lit lamps
for(int j = 0; j < 8000; j++)
{
if( t1[j] )
{
numLitLights++;
}
}
// output number of lit lamps
printf( "number of lit lamps: %d\n", numLitLights );
} // end function: main
The result (number of lamps lit) is
1024

Resources