比较字符数组的子字符串与C中的另一个字符数组

时间:2014-06-11 08:48:01

标签: c arrays string substring pi

我有两个名为arraypiarraye的字符数组,其中包含我从文件中读取的数字。每个都有1,000,000个字符。我需要从arraye中的第一个字符开始(在本例中为7)并在arraypi中搜索它。如果7中存在arraypi,那么我必须搜索arraye的下一个子字符串(在本例中为71)。然后搜索7187182,依此类推,直到arraypi中不存在子字符串。然后我必须简单地将最大子字符串的长度放在整数变量中并打印出来。

值得一提的是,arraypi每50个字符包含一个换行符,而arraye每80个字符包含换行符,但我认为这不会对问题产生影响吗?

我试着想办法实现这个目标,但到目前为止我还没有想到什么。

3 个答案:

答案 0 :(得分:1)

我不确定我是否做对了。我脑子里有这样的事情:

  • 假设我们已将整个arraypi放在浏览器中
  • 您使用组合ctrl+f进行查找
  • 开始逐字母地输入arraye的内容,直至看到红色无匹配
  • 您想要在此之前输入的字符数

如果那是对的,那么像下面这样的算法应该可以解决这个问题:

#include <stdio.h>
#define iswhitespace(X) ((X) == '\n' || (X) == ' ' || (X) == '\t')

int main( ) {

    char e[1000] = "somet\n\nhing";
    char pi[1000] = "some other t\nhing\t som\neth\n\ning";

    int longestlen = 0;
    int longestx = 0;
    int pix = 0;
    int ex = 0;
    int piwhitespace = 0;       // <-- added
    int ewhitespace = 0;        // <-- these

    while ( pix + ex + piwhitespace < 1000 ) {

        // added the following 4 lines to make it whitespace insensitive
        while ( iswhitespace(e[ex + ewhitespace]) )
            ewhitespace++;
        while ( iswhitespace(pi[pix + ex + piwhitespace]) )
            piwhitespace++;

        if ( e[ex + ewhitespace] != '\0' && pi[pix + ex + piwhitespace] != '\0' && pi[pix + ex + piwhitespace] == e[ex + ewhitespace] ) {
            // the following 4 lines are for obtaining correct longestx value
            if ( ex == 0 ) {
                pix += piwhitespace;
                piwhitespace = 0;
            }
            ex++;
        }
        else {
            if ( ex > longestlen ) {
                longestlen = ex;
                longestx = pix;
            }
            pix += piwhitespace + 1;
            piwhitespace = 0;
            // the two lines above could be replaced with
            // pix++;
            // and it would work just fine, the injection is unnecessary here
            ex = 0;
            ewhitespace = 0;
        }
    }

    printf( "Longest sqn is %d chars long starting at %d", longestlen, longestx + 1 );

    putchar( 10 );
    return 0;
}

在那里发生了什么,循环首先搜索匹配的起点。在找到匹配项之前,它会递增要检查的数组的索引。当它找到一个起点时,它会开始递增包含搜索词的数组的索引,保持另一个索引不变。

直到下一次不匹配,即进行记录检查时,搜索术语索引被重置,考生索引开始再次递增。

我希望这有助于某种方式,而不仅仅是解决这场一次性的斗争。

编辑:

更改了代码以忽略空格字符。

答案 1 :(得分:1)

好的,既然你显然不是真的想要这个数组,而是内部有文本的两个文件,这里有一个合适的解决方案来实现:

#include <stdio.h>
#define iswhitespace(X) ((X) == '\n' || (X) == ' ' || (X) == '\t')

int main( ) {

    FILE * e;
    FILE * pi;

    if ( ( e = fopen( "e", "r" ) ) == NULL ) {
        printf( "failure at line %d\n", __LINE__ );
        return -1;
    }

    if ( ( pi = fopen( "pi", "r" ) ) == NULL ) {
        printf( "failure at line %d\n", __LINE__ );
        return -1;
    }

    int curre = fgetc( e );
    int currpi = fgetc( pi );
    int currentlength = 0;
    int longestlength = 0;
    int longestindex = 0;
    int whitespaces = 0;
    fpos_t startpoint;

    if ( curre == EOF || currpi == EOF ) {
        printf( "either one of the files are empty\n" );
        return -1;
    }

    while ( 1 ) {

        while ( iswhitespace( currpi ) )
            currpi = fgetc( pi );

        while ( iswhitespace( curre ) )
            curre = fgetc( e );

        if ( curre == currpi && currpi != EOF ) {
            if ( currentlength == 0 && fgetpos( pi, &startpoint ) ) {
                printf( "failure at line %d\n", __LINE__ );
                return -1;
            }
            currentlength++;
            curre = fgetc( e );
        }
        else if ( currentlength != 0 ) {
            if ( currentlength > longestlength ) {
                longestlength = currentlength;
                longestindex = startpoint;
            }
            if ( curre == EOF ) {
                printf( "Complete match!\n" );
                break;
            }
            fsetpos( pi, &startpoint );
            rewind( e );
            curre = fgetc( e );
            currentlength = 0;
        }

        if ( currpi == EOF )
            break;

        currpi = fgetc( pi );
    }

    printf( "Longest sequence is %d characters long starting at %d",
                                                    longestlength, longestindex );

    putchar( 10 );
    return 0;
}

它搜索起点,在确定当前匹配的长度后存储该起点返回。确定当前匹配的长度,忽略路上的空白。如有必要,更新记录长度,完全倒回搜索词文件,将受检者文件部分倒回到存储位置。

这是我的 e 文件:

somet

hing

这是我的 pi 文件:

some other  nhing    som
eth

ing

这是我得到的输出:

Complete match!
Longest sequence is 9 characters long starting at 20

顺便说一句,就我记忆而言,freadfwrite在人性上并不直观。你可以这样想,计算机在发布这些功能时会使用它自己理解的语言。

答案 2 :(得分:0)

你可以使用strstr() function.Consider在循环中使用它,返回字符串作为参数之一。