簡體   English   中英

c-查找另一個字符串中所有可能的字符串組合

[英]c - find all possible combinations of a string in another string

假設我有一個字符串“ ron”。 我需要在字符串中找到“ ron”的所有組合,假設是“ xxxxxxronxxxxnorxxxxxrno ”。 輸出應該是ron,在字符串中也找不到rno。

一種方法是首先生成“ ron”的所有組合,然后使用類似的方法檢查原始字符串中的這些子字符串。

#include<stdio.h>
#include<string.h>

int count, occur; 
char *str[100];

/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

/* Function to print permutations of string
   This function takes three parameters:
   1. String
   2. Starting index of the string
   3. Ending index of the string. */
void permute(char *a, int i, int n) 
{
   int j; 
   if (i == n)
     //printf("%s\t", a);
     {
        str[count++]=a;
        printf("%s\t", str[count-1]);
     }    

   else
   {
        for (j = i; j <= n; j++)
       {
          swap((a+i), (a+j));
          permute(a, i+1, n);
          swap((a+i), (a+j)); //backtrack
       }
   }
} 

void substring(char *b, int i)
{
    char *tmp = b;
    while(tmp = strstr(tmp, str[i]))
    {
       occur++;
       tmp++;
    }
}

/* Driver program to test above functions */
int main()
{
   char a[] = "ABC";
   char b[] = "ABCRTYBACXCAB";    
   int i;

   count=0;
   occur=0;

   permute(a, 0, 2);

   for(i=0;i<count;i++)
      printf("%s\t", str[i]);

   for(i=0;i<count;i++)
      substring(b,i);

   printf("\nOccurences: %d", occur);

   return 0;
}

執行此命令時,輸出為:

ABC ACB BAC BCA CBA CAB

ABC ABC ABC ABC ABC ABC

發生次數:6

置換中的str值正確顯示,但是為什么它們在main中不同? 怎么了

解決了:

STR [計數++] =的strdup(a)的

要么

將* str []轉換為str [] [],然后執行strcpy(str [],a)

首先為所有"ron"排列制作Aho-Corasick狀態機(僅是很好的練習),然后將此機器應用於第二個字符串。 這是相當有效的解決方案,短首字符串。

編輯 :我已經意識到Aho-Corasick狀態機將需要N! 內部狀態無論如何都會炸毀它。 必須構造其他一些具有壓縮狀態的狀態機。 我正在考慮到目前為止找到的子字符串的鏈接列表,其中哈希表或線性表指向每個部分。

EDIT2:沒有與溶液O(N+M)的時間和O(A)的空間復雜度,其中NM被輸入的字符串的尺寸和A是字母表的大小GitHubGist 它使用位圖來跟蹤屬於子列表的字符,這些字符在到目前為止找到的每個字符的字符串和反向引用指針中找到。 在64位平台上,ASCII的所有狀態大小均為2128,非常適合現代硬件的L1 CPU緩存。

以下是很一般的...

  char test[] = "xxxronronronxxx" ;
  const char* s ;

  s = test ;

  const char* seek = "ron" ;
  int count = 0 ;
  while (1)
    {
      char find[strlen(seek) + 1] ;
      const char* t ;
      int n ;

      s = strpbrk(s, seek) ;
      if ((s == NULL) || (strlen(s) < strlen(seek)))
        break ;

      strcpy(find, seek) ;
      t = s ;
      n = strlen(find) ;
      while (1)
        {
          char* f ;

          f = strchr(find, *t) ;
          if (f == NULL)
            break ;

          n -= 1 ;
          if (n == 0)
            {
              count += 1 ;
              break ;
            } ;

          *f = find[n] ;
          find[n] = '\0' ;

          t += 1 ;
        } ;

      s += 1 ;
    } ;

  printf("'%s' in '%s' %d times\n", seek, test, count) ;    

...如果需要的話,最后的s += 1可以是s += strlen(seek)以超越比賽。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM