更优化的解决方案,查找字符串中的子串数。使用C.

时间:2010-10-18 19:30:01

标签: c string substring

所以,我有一个任务是找到给定字符串中的子串数。我无法使用任何C库来执行此任务。 stringExist只能有2个字符串作为参数。

我的解决方案正在运行,但我觉得应该有更优雅的方式来完成这项任务。 解决方案1: 事实证明,它无法正常工作

#include <stdio.h>

int stringExist(char string[], char s2[]);

int main(void){
    char string[] = "strstrASDstrSTRst";
    char s2[] = "str";
    printf("Final result: %i\n",stringExist(string,s2));
    return 0;
}

int stringExist(char string[], char s2[]){
/* I am aware that I can init all this values in one row */
    int count = 0;
    int size = 0;
    int i = 0;
    int temp = 0;
    int result = 0;

    while(s2[size]!='\0'){        
        size++;
    }

    while(string[i]!='\0')
    {        
        if(string[i]==s2[0])
        {
            printf("Found first occurrence\n");
            count=0;            
            while((temp=(string[i]==s2[count]))!=0)
            {            
                count++;                    
                if(size==count){
                    printf("Match\n");
                    result++;                    
                    break;                    
                }
                i++;
            }
        }
        i++;
    }


    return result;
} 

解决方案编号2:

到目前为止没有发现错误。

进行了一些不同的字符串遍历,现在我没有在比较字符循环中增加i。

#include <stdio.h>

int stringExist(char string[], char s2[]);

int main(void){
    char string[] = "bobobobojkhhkjjkhbo;klkl;bobo";
    char s2[] = "bobo";
    printf("Final result: %i\n",stringExist(string,s2));
    return 0;
}

int stringExist(char string[], char s2[]){
    int count = 0;
    int size = 0;
    int i = 0;
    int c = 0;
    int temp = 0;
    int result = 0;

    while(s2[size]!='\0'){      
        size++;
    }
    for(i=0;string[i]!='\0';i++){
        if(string[i]==s2[0])
        {
            printf("Found first occurence at %i\n",i);
            count = 0;
            c = i;              

                while((temp=(string[c]==s2[count]))!=0)
                {       
                    printf("Count %i, I %i, current char: %c\n",count, c,string[c]);
                    count++;                    
                    if(size==count){
                        printf("Match\n");
                        result++;                   
                        break;                  
                    }
                    c++;
                }

        }
    }


    return result;
}

谢谢你的建议, 维塔利彼得

4 个答案:

答案 0 :(得分:3)

击败它:(也适用于额外条件)

int stringExist( char *string, char *sub )
{
  int count = 0;

  while( *string )
  {
    char *a = string, *b = sub;
    while( *a && *a == *b ) {a++;b++;}
    count += !*b;
    ++string;
  }

  return count;
}

答案 1 :(得分:1)

我建议您按照允许使用库函数的方式编写它。然后返回并编写您自己使用的库函数版本。虽然编写高度优化的string.h函数版本可能很困难,但在C语言中编写大多数版本的版本非常简单。

使用子程序(函数)预先形成此问题的子任务将帮助您保持代码清晰,并避免某些类型的问题,例如,如果您调用:

x = stringExist("aaaaa", "aa");

“aaaaa”中有4个字符串“aa”,但我认为你的函数不会找到所有字符串。这样做的原因是,当你在较大的字符串中搜索第二个字符串时,你会在字符串的开头和字符串中使用相同的索引。事实上,看起来你会得到错误的结果:

x = stringExist("tBatBath", "tBath");

当然,除非我误解了这个功能应该做什么。

如果您要编写自己的字符串前缀比较函数(基本上是memcmpstrncmp),那么您可以将匹配字符串长度的工作与更深入地查找字符串,可能不会犯这样的错误。

如果您担心从功能中挤出效率以及调用函数的开销,请不要。首先,它并没有那么糟糕。其次,只需声明它们inlinestatic inline,如果在启用优化的情况下进行编译,编译器很可能会生成与没有使用多个函数时一样好的代码。

答案 2 :(得分:0)

这感觉就像是一个家庭作业问题 - 在这种情况下,你一定要自己做。但是,你可能想要检查的东西我不认为你的代码现在正确处理了这个:

字符串“bobobo”中出现“bobo”的次数。它可能应该是两次,我认为你的代码只会算一个。

祝你好运, 标记

答案 3 :(得分:0)

嗯,从算法的角度来看,它并不坏。你可以进行优化,但我不认为这是重点(看起来像家庭作业!)。

你可能会遇到一个小问题:在像“hahahaha”这样的字符串中,应该检测到多少次“haha”?两次?三次?你的代码会看到它两次。

从风格的角度来看,肯定有改进的余地,但随着时间的推移,您将从编码和阅读其他代码中了解到这一点=)。坚持下去!