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.
Related
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];
}```
I am using eclipse 3.2020 on WIN10 and I have a problem executing my main function.
When I run the program as it is, I get no output to conole, even when I add a printf in the first line, and the exit code is -1,073,741,819. When I comment out/ delete the line solve(s); the code run as intended and gives exit code 0.
Edit: added full code (both solve and print_sol are in solver.c)
Edit 2: As mentioned in the comments, the problem was in the code (bug) and not eclipse, I just assumed that an error message will be printed if there is one.
p.s.: I still find the fact a printf in the start won't print if there is a runtime error in another part of the main function quite weird.
main.c:
#include "solver.h"
#include <stdlib.h>
int main(int argc, char** argv){
int **grid = (int**) malloc(sizeof(int*) * 4);
for (int i = 0; i < 4 ; i++){
grid[i] = (int*) malloc(sizeof(int) * 4);
}
int mat[4][4] = {{1,0,3,0}
,{2,0,0,0}
,{3,0,0,0}
,{4,2,0,0}};
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
grid[i][j] = mat[i][j];
}
}
solver *s = create_solver(4, &grid);
solve(s);
print_sol(s);
}
solver.h:
#ifndef SOLVER_H_
#define SOLVER_H_
typedef struct sudoku_solver solver;
/*creates a new solver using the length of one row of the board.
*Then, the user will follow the instructions on screen to input the board*/
solver* create_solver(int row_len, int ***input_board_ptr);
/*if solver is NULL, an error will appear.
*Otherwise, The board that was given won't be changed, and neither
*the solver nor the solution (unless saved before using get_sol)
*will be accessible after this*/
void destroy_solver(solver *solver);
/*if solver is NULL, an error will appear.
*Otherwise, it will solve the inputed board*/
void solve(solver *solver);
/*if "solve" wasn't executed before, an error will appear.
*Otherwise, it will print a solution to the inputed board*/
void print_sol(solver *solver);
/*if "solve" wasn't executed before, an error will appear.
*Otherwise, returns a solution to the inputed board as a matrix of integers*/
int** get_sol(solver *solver);
#endif /* SOLVER_H_ */
solver.c:
#include "solver.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
/*the board will be represented by an array of size NxN.
*the value of every board cell is between 0 and N when 0
*means "default value"*/
typedef struct sudoku_solver{
/*length of one row of the board*/
int N;
/*a pointer to the solution board*/
int ***sol_ptr;
}solver;
solver* create_solver(int row_len, int ***input_board_ptr){
solver *s = (solver*) malloc(sizeof(solver));
/*throw an ERROR if the malloc failed*/
/*row_len is a variable, so we have to declare everything dynamically */
/*allocating the sol matrix as an array of pointers (1 out of 2D)*/
int **sol = (int**) malloc(row_len * sizeof(int*));
for (int i = 0; i < row_len; i++){
/*allocating every row (the second D)
*while making sol equal to input_board*/
sol[i] = (int*) malloc(row_len * sizeof(int));
for (int j = 0; j < row_len; j++){
sol[i][j] = (*input_board_ptr)[i][j];
}
}
s->N = row_len;
/*if row_len != pow(sqrt(row_len),2) then throw invalid input ERROR*/
s->sol_ptr = /
return s;
}
void destroy_solver(solver *s){
for (int i = 0; i < s->N; i++){
free((*(s->sol_ptr))[i]);
}
free(*(s->sol_ptr));
free(s->sol_ptr);
free(s);
}
int* calc_next(int x, int y, int *next, solver *s);
bool isSafe(int x, int y, int val, solver *s);
bool solve_rec(int x, int y, solver *s);
void solve(solver *s){
int n = s->N;
int next[2];
int ***sp = s->sol_ptr;
//find next empty space
if ((*sp)[0][0] == 0){
next[0] = 0;
next[1] = 1;
}
else{
calc_next(0, 0, next, s);
}
int nextX = next[0];
int nextY = next[1];
for (int i = 1; i < n; i++){
if (isSafe(nextX, nextY, i, s)){
(*sp)[nextX][nextY] = i;
if(solve_rec(nextX, nextY, s)){
return;
}
//backtrack
(*sp)[nextX][nextY] = 0;
}
}
printf("no sol");
return;
}
bool solve_rec(int x, int y, solver *s){
int n = s->N;
int next[2];
int ***sp = s->sol_ptr;
if (x == n - 1 && y == n - 1){
return true;
}
//find next empty space
calc_next(x, y, next, s);
int nextX = next[0];
int nextY = next[1];
for (int i = 1; i < n; i++){
if (isSafe(nextX, nextY, i, s)){
(*sp)[nextX][nextY] = i;
if(solve_rec(nextX, nextY, s)){
return true;
}
//backtrack
(*sp)[nextX][nextY] = 0;
}
}
return false;
}
bool isSafe(int x, int y, int val, solver *s){
int n = s->N;
int ***sp = s->sol_ptr;
/*check row*/
for (int j = 0; j < n; j++){
if ((*sp)[x][j] == val){
return false;
}
}
/*check col*/
for (int i = 0; i < n; i++){
if ((*sp)[i][y] == val){
return false;
}
}
/*check block
*the index of a block in a grid is just like the index of entry in block.
*In sudoku, there are bs*bs blocks, and each has bs rows and bs columns*/
int bs = sqrt(n); // block size
int block_x_index = x / bs;
int block_y_index = y / bs;
for(int i = block_x_index * bs; i < bs * (block_x_index + 1); i++){
for(int j = block_y_index * bs; j < bs * (block_y_index + 1); j++){
if ((*sp)[i][j] == val){
return false;
}
}
}
return true;
}
/*assuming x,y is not the last place in the grid,
* finds the next empty place after it*/
int* calc_next(int x, int y, int *next, solver *s){
int n;
int ***sp = s->sol_ptr;
/*find the first empty place*/
do{
n = s->N;
if (y == n - 1){
x++;
y = 0;
}
else{
y++;
}
}while ((*sp)[x][y] != 0);
next[0] = x;
next[1] = y;
return next;
}
void print_sol(solver *s){
int n = s->N;
int bs = sqrt(n); // block size
char curr;
int rows_passed, col_passed;
for (int i = 0; i < n + bs - 1; i++){
for (int j = 0; j < n + bs - 1; j++){
//if it's a grid row
if (i == bs || ((i - bs) % (bs + 1)) == 0){
//if it's also a grid col
if (j == bs || ((j - bs) % (bs + 1) == 0)){
curr = '+';
}
else{
curr = '-';
}
}
//if it's only a grid col
else if (j == bs || ((j - bs) % (bs + 1) == 0)){
curr = '|';
}
else{
rows_passed = i / (bs + 1);
col_passed = j / (bs + 1);
curr = '0' + (*(s->sol_ptr))[i-rows_passed][j-col_passed];
}
printf("%c",curr);
}
printf("\n");
}
}
int** get_sol(solver *solver){
return *(solver->sol_ptr);
}
Thank you.
Please learn how to use your debugger. In this case, it would take you directly to the problem: you're crashing with an access violation (Windows 0xc0000005) here:
void solve(solver *s) {
int n = s->N;
int next[2];
int ***sp = s->sol_ptr;
//find next empty space
if ((*sp)[0][0] == 0) { // <-- Access violation here: "sp" incorrectly initialized!
next[0] = 0;
next[1] = 1;
}
The underlying problem is that although sudoku_solver.N was initialized to "4" ... sudoku_solver.sol_ptr[0][0] is pointing to uninitialized memory.
PS:
Yes, it's very definitely "executing". It wouldn't crash if it didn't run ;)
The problem is to find the number of times a word occurs in a given N x N matrix of alphabets. We can move from any cell to other adjacent cell. The first line has one integer N and then a N x N matrix. Next line has M (size of the word) and then a string to be found in the matrix.
Input:
4
ABCD
ABCD
ABCD
ABCD
2
BC
Expected output:
10
I have written the following code for the same and used recursion for solving the problem. The function adj checks if the character is adjacent in the matrix with the previous character using their indexes. The function check increases the count whenever the string is completed. The 2-d array keeps a check on the visited and unvisited elements.
I am getting the output as
OUPUT
1
EDIT 1: This output is just because of the debugging print statement, so the if statement is being visited only once. It does not mean that the count variable is 1 after many recursion calls.
EDIT 2: There shouldn't be & in the scanf statement for word. But still the output is not the desired one.
EDIT 3:
Another input
7
SHELDON
HSTYUPQ
EHGXBAJ
LMNNQQI
DTYUIOP
OZXCVBN
NQWERTY
7
SHELDON
Expected output:
5
My output - 1
EDIT 4(Solved!): So the problem was in writing the no. of columns as 500 for the grid matrix, changing it to 5 did the job! Thanks to #gsamaras
Code
#include <stdio.h>
int vis[500][500], count;
int adj(int a, int b, int c, int d) {
if((c == a - 1) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b)) {
return 1;
}
else if((c == a) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b)) {
return 1;
}
else if((c == a + 1) && (d == b + 1)) {
return 1;
}
else if((c == a) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b - 1)) {
return 1;
}
else {
return 0;
}
}
void check(char grid[][500],int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("%d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < n; q++) {
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char grid[n][n+1];
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", &word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
return 0;
}
Change this:
void check(char grid[][500], ......
to this:
void check(char grid[][5], ....... // that should be equal to N + 1 (5 in your case)
since your grid is of size N x N + 1. With the 500 as the dimension, you distorted the grid, and when trying to search into it recursively, you wouldn't traverse the grid that you would expect to traverse..
As you see this is not flexible, since N can vary. You cannot declare grid as global, since its dimensions are not fixed. Dynamic memory allocation should be used instead.
Change this:
scanf("%s", &word);
to this:
scanf("%s", word);
since word is an array of characters.
Complete example with Dynamic Memory Allocation:
#include <stdio.h>
#include <stdlib.h>
int vis[500][500], count;
char **get(int N, int M) { /* Allocate the array */
int i;
char **p;
p = malloc(N*sizeof(char *));
for(i = 0 ; i < N ; i++)
p[i] = malloc( M*sizeof(char) );
return p;
}
void free2Darray(char** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int adj(int a, int b, int c, int d) {
// Same as in your question
}
void check(char** grid, int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("count = %d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < 499; q++) {
//printf("p = %d, q = %d, id = %d, grid[p][q] = %c, word[id] = %c\n", p, q, id, grid[p][q], word[id]);
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char** grid = get(n, n + 1);
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
//printf("i = %d, j = %d, id = %d\n", i, j, id);
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
free2Darray(grid, n);
return 0;
}
Output (for your 1st input):
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
10
PS: Not a problem, just a suggestion about readability: count is initialized to 0, because it's a global variable, but it's always best to explicitly initialize your variables, when it matters.
I am try to write a A recursive implementation, but it dont work. Can you help me to find mistake. I need just a recursive solution on C.
void findsum(int arr[],int i, int k){
if (k <= 0 || arr[i] > k) return;
if (arr[i] <= k) {
k -= arr[i];
if (k == 0) {
NSLog(#"Summ %d, %d",arr[i], arr[i]); return;
}
}
if (i == (25)) return;
for (int a=i ;a<25; a ++ ) {
findsum(arr, a, k);
}
}
int main()
{
int set[] = {18897109, 12828837, 9461105, 6371773, 5965343, 5946800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279833, 3095313, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411};
int sum = 100000000;
int n = sizeof(set)/sizeof(set[0]);
for (int i = 0; i < n; i++) {
findsum(set, i, sum);
}
}
You code not stop because every time you assign i=0 by loop
for (i = 0 ;i<26; i ++ ) {
findsum(arr, i, k);
}
In findsum function.
So as per my suggestion you can make some changes as like
first in main
int main()
{
int set[] = {18897109, 12828837, 9461105, 6371773, 5965343, 5946800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279833, 3095313, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411};
int sum = 100000000,i;
int n = sizeof(set)/sizeof(set[0]);
findsum(set, n, sum);
}
And second in findsum like
void findsum(int arr[],int i, int k)
{
if (k <= 0 || arr[i] > k) return;
if (arr[i] <= k)
{
k -= arr[i];
if (k == 0) {
NSLog(#"Summ %d, %d",arr[i], arr[i]); return;
}
}
if (i == 25) return;
findsum(arr, i, k);
}
I have the next KMP-implementation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int kmp(char substr[], char str[])
{
int i, j, N, M;
N = strlen(str);
M = strlen(substr);
int *d = (int*)malloc(M * sizeof(int));
d[0] = 0;
for(i = 0, j = 0; i < M; i++)
{
while(j > 0 && substr[j] != substr[i])
{
j = d[j - 1];
}
if(substr[j] == substr[i])
{
j++;
d[i] = j;
}
}
for(i = 0, j = 0; i < N; i++)
{
while(j > 0 && substr[j] != str[i])
{
j = d[j - 1];
}
if(substr[j] == str[i])
{
j++;
}
if(j == M)
{
free(d);
return i - j + 1;
}
}
free(d);
return -1;
}
int main(void)
{
char substr[] = "World",
str[] = "Hello World!";
int pos = kmp(substr, str);
printf("position starts at: %i\r\n", pos);
return 0;
}
You can test it here: http://liveworkspace.org/code/d2e7b3be72083c72ed768720f4716f80
It works well on small strings, and I have tested it with a large loop, on this way all is fine.
But if I change the substring I'm searching for and the complete string to these:
char substr[] = "%end%",
str[] = "<h1>The result is: <%lua% oleg = { x = 0xa }
table.insert(oleg, y) oleg.y = 5 print(oleg.y) %end%></h1>";
Only after first try, this implementation fails...
Please, could you help me with repairing implementation of KMP to make the algorithm work with such data in strings...
In one place you deviate from your source, the source has
while(j>0 && p[j]!=p[i]) j = d[j-1];
if(p[j]==p[i])
j++;
d[i]=j;
while you have
while(j > 0 && substr[j] != substr[i])
{
j = d[j - 1];
}
if(substr[j] == substr[i])
{
j++;
d[i] = j;
}
being deceived by the source's indentation. In the source, there are no braces around the if() branch, so only the increment j++; is controlled by the if; d[i] = j; is unconditional.
Then, the source has an error, probably due to the unusual use of indices. The correct way to set up the array is
int *d = (int*)malloc(M * sizeof(int));
d[0] = 0;
for(i = 1, j = 0; i < M; i++)
{
while(j > 0 && substr[j-1] != substr[i-1])
{
j = d[j - 1];
}
if(substr[j] == substr[i])
j++;
d[i] = j;
}
But it's confusing, since the setup here uses the indices i-1 and j-1 as well as i and j to determine d[i]. The usual way to implement it is different; the way it is implemented in C#. Since that's the form you find in most sources, it's far easier to convince yourself of the correctness of that.