字符串匹配KMP算法在true时打破循环?

发布于 2025-01-10 06:54:57 字数 2867 浏览 0 评论 0原文

我是中国人,我的英语很差,我会尽力让自己明白,谢谢!

发生了什么:我正在学习 kmp,我写了一段代码,while ( i < strlen(S) && j < strlen(T) ) 是 true,但事实并非如此进入循环,然后转到 if(T.length == j) :

感谢 PaulMcKenzie 指出了差异,是 int next[strlen(T)]; 导致了问题吗?我将其更改为 int next[80],它没有任何区别;

此处代码:

#include<stdio.h>
#include "string.h"
void getNext(char T[], int next[]){
    int i=0, j=-1;
    next[0] = -1;
    while ( i < strlen(T) -1 ){
        if( -1 == j || T[i] == T[j]){
            i++;
            j++;
            next[i] = j;
        }else{
            j = next[j];
        }
    }
}

int kmp(char S[], char T[]){
    int next[strlen(T)];
    getNext(T, next);
    int i = 0, j = 0;
    while (  i < strlen(S) && j < strlen(T) ){   //look here please
        if ( -1 == j || S[i] == T[j]){
            i++;
            j++;
        } else{
            j = next[j];
        }
    }

    if(strlen(T) == j)
        return i - j;
    else
        return -1;
}

int main()
{
    char S[80],T[80];
    gets(S);
    gets(T);
    printf("%d", kmp(S, T));
}

测试数据:jfaweiof of

the next[0] = -1, next[1] = 0

我尝试过:

  1. 使用IDEA debug:

idea debug

  1. 我尝试了Java代码,它可以得到正确的结果
package com.peterjxl.string;

import java.util.Scanner;

public class KMP {

    public static void getNext(char[] T, int[] next){
        int i = 0, j = -1;
        next[0] = -1;
        while ( T.length -1 > i){

            if( -1 == j || T[i] == T[j]){
                ++i;
                ++j;
                next[i] = j;
            }else {
                j = next[j];
            }
        }
    }

    public static int KMP(char[] S, char[] T){
        int[] next = new int[T.length];
        getNext(T, next);
        int i=0, j=0;
        while (S.length > i && T.length > j){
            if(-1 == j || S[i] == T[j]){
                i++;
                j++;
            }else {
                j = next[j];
            }
        }
        if(T.length == j)
            return i-j;
        else
            return -1;
    }

    public static void main(String[] args) {
        String S, T;
        Scanner input = new Scanner(System.in);
        S = input.nextLine();
        T = input.nextLine();
        System.out.println(KMP(S.toCharArray(), T.toCharArray()));
    }
}
  1. 我搜索stackoverflow,看起来没有人有同样的问题...
  2. 问朋友,在中国论坛问,没有得到答案。 .:<一href="https://segmentfault.com/q/1010000041451224" rel="nofollow noreferrer">https://segmentfault.com/q/1010000041451224

本地环境: win10 x64,

Clion 2021.3.2 内置 mingw:w649.0

Java 1.8 + idea: 2021.2.3 (终极版)

有什么建议吗?谢谢!

I'm a Chinese and my english is poor, I'll try to make myself understand, Thanks!

what happened: I am learning kmp, I wrote a code, the while ( i < strlen(S) && j < strlen(T) ) is true, but it didn't go in the loop, and go to the if(T.length == j):

thanks PaulMcKenzie point out the difference, is the int next[strlen(T)]; casue the problem? I change it to int next[80], it dosen't make any difference;

code here:

#include<stdio.h>
#include "string.h"
void getNext(char T[], int next[]){
    int i=0, j=-1;
    next[0] = -1;
    while ( i < strlen(T) -1 ){
        if( -1 == j || T[i] == T[j]){
            i++;
            j++;
            next[i] = j;
        }else{
            j = next[j];
        }
    }
}

int kmp(char S[], char T[]){
    int next[strlen(T)];
    getNext(T, next);
    int i = 0, j = 0;
    while (  i < strlen(S) && j < strlen(T) ){   //look here please
        if ( -1 == j || S[i] == T[j]){
            i++;
            j++;
        } else{
            j = next[j];
        }
    }

    if(strlen(T) == j)
        return i - j;
    else
        return -1;
}

int main()
{
    char S[80],T[80];
    gets(S);
    gets(T);
    printf("%d", kmp(S, T));
}

test data: jfaweiof of

the next[0] = -1, next[1] = 0

I tried:

  1. using IDEA debug:

idea debug

  1. I tried Java code, it can get correct result
package com.peterjxl.string;

import java.util.Scanner;

public class KMP {

    public static void getNext(char[] T, int[] next){
        int i = 0, j = -1;
        next[0] = -1;
        while ( T.length -1 > i){

            if( -1 == j || T[i] == T[j]){
                ++i;
                ++j;
                next[i] = j;
            }else {
                j = next[j];
            }
        }
    }

    public static int KMP(char[] S, char[] T){
        int[] next = new int[T.length];
        getNext(T, next);
        int i=0, j=0;
        while (S.length > i && T.length > j){
            if(-1 == j || S[i] == T[j]){
                i++;
                j++;
            }else {
                j = next[j];
            }
        }
        if(T.length == j)
            return i-j;
        else
            return -1;
    }

    public static void main(String[] args) {
        String S, T;
        Scanner input = new Scanner(System.in);
        S = input.nextLine();
        T = input.nextLine();
        System.out.println(KMP(S.toCharArray(), T.toCharArray()));
    }
}
  1. I search the stackoverflow, It look like nobody had same question...
  2. asking friend, asking in China Forum, get no answer...: https://segmentfault.com/q/1010000041451224

local environment:
win10 x64,

Clion 2021.3.2 Built in mingw:w649.0

Java 1.8 + idea: 2021.2.3 (Ultimate Edition)

any suggestion? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

很快妥协 2025-01-17 06:54:57
while (  i < strlen(S) && j < strlen(T) )

unsigned intsigned int 相比,因此 C++ 中的结果是 0xFFFFFFFF

我将其更改为:

while (  i < (int)strlen(S) && j < (int)strlen(T) )

现在,程序有效!

由 brokkr 在论坛 SegmentFault 上回答

while (  i < strlen(S) && j < strlen(T) )

unsigned int compare to signed int, so the result in C++ is 0xFFFFFFFF

I change it to:

while (  i < (int)strlen(S) && j < (int)strlen(T) )

Now, the program works!

Answerer by brokkr, on the forum SegmentFault

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文