【问题标题】:How to compare strings "partly" ( to return the number of characters that were matched)?如何“部分”比较字符串(返回匹配的字符数)?
【发布时间】:2013-05-23 05:55:07
【问题描述】:

程序适用于 .wave 文件。

下面的代码是查找“数据”子块的程序的一部分。它将所有必要的块写入输出文件,然后找到"data"(将接下来的4个字节复制到char comp_dataID[4];并与const char dataID[4] = "data";进行比较):

while(1)  /* finding "data"*/ {
    fread(comp_dataID, 4, 1, input);

    if ( memcmp(comp_dataID, dataID, 4) == 0 ) {
        printf(">>>   \"data\" found!\n");
        fwrite(&comp_dataID, 1, 4, output);
        break;
    }
    else {
        fseek(input, -3, SEEK_CUR);
    }
}

“数据”之前可以有很多扩展子块,所以我要优化程序:

  1. 如果接下来的 4 个字节包含“....”,则复制接下来的 4 个字节。 (跳过 3 个不必要的操作)
  2. 如果 "...d" 然后 fseek(input, -1, SEEK_CUR); /* 在 "d" 之前设置 pionter */ 然后复制接下来的 4 个字节。
  3. 如果 "..da" 然后 fseek(input, -2, SEEK_CUR); /* 在 "d" 之前设置 pionter */ 然后复制接下来的 4 个字节。
  4. 如果 ".dat" 然后 fseek(input, -3, SEEK_CUR); /* 在 "d" 之前设置 pionter */ 然后复制接下来的 4 个字节。

问题是我不明白如何比较“...d”和“data”。 IE。如何找出char comp_dataID[4]; 是否包含“...d”或“..da”或“.dat”。


问题:是否有任何函数可以执行此操作(返回匹配的字符数:0 表示“....”,1 表示“...d "等等)?

...或者我将使用for() 循环 ti 找到“d”,然后找到“a”,然后找到“t”。并根据结果,在“d”之前设置 pionter 以便复制接下来的 4 个字节(“数据”)。

附言 在这个 char[4] 之后接下来的 4 个字节是所有样本的大小(在程序中使用)

【问题讨论】:

    标签: c string algorithm wav


    【解决方案1】:

    在开始尝试优化之前,您确定这是个问题吗?您是否真的在分析器中运行了代码,并确定循环中的几个额外时钟周期是减慢程序的最大因素,而不是磁盘 I/O 或其他地方发生的事情?

    在一般情况下,memcmp 可能不会比滚动您自己的函数来比较和计算偏移量慢多少,并且与磁盘 I/O 的影响以及您实际最终执行的任何处理相比,这可能是最小的贡献.

    *edit*删除损坏的示例。


    【讨论】:

    • 不,我没有在...分析器中运行我的代码。 (我不知道它是什么?)我不是很熟练的程序员,但我相信如果有非常大的“额外”子块,这种优化将有助于节省一些机器的资源(我说得对吗? ?)。
    • strstr() 返回什么类型?
    • 正如链接文档所说,char*。
    • 好吧,这个:set_input = strstr( comp_dataID, dataID ); 将返回一个指向data 字符串开头的指针。但是我怎样才能将input (pointer) 替换到"data" 的开头? PS(关于“displase”,我的意思是……例如:fread() 替换指针,下一个 fread() 将从停止的地方继续)。
    【解决方案2】:

    这个函数可以做到:

    int match(char *a, const char *b) {
    
        int matches = 0;
    
        if( a[3] == b[0] )  
            matches = 1;
        if( a[2] == b[0] )
            matches = 2;
        if( a[1] == b[0] )
            matches = 3;
        if( a[0] == b[0] )
            matches = 4;
    
        return matches;
    }
    

    int main()
    {
        ...
        step = match( buf, dataID ); // number of matched letters
        fseek(input, -step, SEEK_CUR);       // sets `pointer` to the beginning of "data"
    
        return 0;
    }
    

    【讨论】:

    • 问题是我与const char比较的字符串可以像???d??da?dat这样开始...
    • 这会给你多长时间直到两个字符串发散,这是一个不同的问题。他在等待两个人会合多长时间。
    • @Julian 关于对你有用的编辑:) 我正在考虑避免对任何值进行硬编码,也许我仍然错过了你问题的一个方面。
    • @Nobilis 如果您在此处找到 (Ctrl + F):ccrma.stanford.edu/courses/422/projects/WaveFormat 以下内容:如果 PCM,则不存在,您将能够看到“额外的块”......我想跳过它们(我对它们不感兴趣)到“数据”的开头。无论如何,问题已经解决了。谢谢! ;)
    • 啊哈,哦,那应该没问题。我不得不承认我对处理声音文件一无所知,所以它们的组成对我来说完全是难以捉摸的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-03-30
    相关资源
    最近更新 更多