在没有数组的长序列中搜索模式字符串[关闭]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在没有数组的长序列中搜索模式字符串[关闭]相关的知识,希望对你有一定的参考价值。

我想问一下如何使用getchar()在不同字符的长输入中搜索两种模式(例如RFMKCR和AWY)?

P.S不允许使用数组。谢谢!

答案

这是状态机的完整代码,它从通用函数getchar1()获取输入。模式:AWYRFMKCR被认可和报告。

函数getchar1()只是从输入中获取char的任何函数的包装器。可以在里面使用getchar()scanf。由STOP定义的char终止输入处理。

这个问题的困难来自需要寻找两种模式的开头:AWYRFMKCR同时。我们可能被迫切换到寻找另一个模式中间的不同模式或重新同步。

给出了三个完整的解决方案

第一种解决方案使用递归。

第二种解决方案使用简单的goto结构,避免递归调用。这种方法对于这个特定问题非常有效。

注意:在C中通常不鼓励使用goto。尽可能使用breakcontinuereturn语句而不是goto是一种很好的编程风格。由于break语句仅从循环的一个级别退出,因此从深层嵌套循环中退出循环可能需要goto

第三种解决方案不使用递归或goto语句,并试图显示一种可以轻松适应不同模式的通用方法。

解决方案1)

#include <stdio.h>
#include <stdlib.h>

#define STOP    '!'

int START(void);
int AWY(void);
int RFMKCR(void);
int END(void);

int getchar1 (void)
{
  char in;
  in = getchar(); // scanf ("%c", &in);
  return in;
}

int START(void)
{
  int c = getchar1 ();
  if (c == 'A')    return AWY(); 
  if (c == 'R')    return RFMKCR();
  if (c == STOP)   return END(); 
  return 1;
}

int AWY(void)   // A already found
{
  int c = getchar1 ();
  if (c == 'A')    return AWY(); 
  if (c == 'R')    return RFMKCR();
  if (c == STOP)   return END();
  if (c != 'W')    return 1; 
  // W found

  c = getchar1 ();
  if (c == 'A')    return AWY(); 
  if (c == 'R')    return RFMKCR();
  if (c == STOP)   return END();
  if (c != 'Y')    return 1; 
  // Y found

  printf ("AWY found
");
  return 1;
}

int RFMKCR(void)    // R already found
{
  int c = getchar1 ();
  if (c == 'A')     return AWY();
  if (c == 'R')     return RFMKCR();
  if (c == STOP)    return END();
  if (c != 'F')     return 1;
  // F found

  c = getchar1 ();
  if (c == 'A')     return AWY(); 
  if (c == 'R')     return RFMKCR();
  if (c == STOP)    return END();
  if (c != 'M')     return 1; 
  // M found

  c = getchar1 ();
  if (c == 'A')     return AWY();
  if (c == 'R')     return RFMKCR(); 
  if (c == STOP)    return END();  
  if (c != 'K')     return 1;
  // K found

  c = getchar1 ();
  if (c == 'A')     return AWY();
  if (c == 'R')     return RFMKCR(); 
  if (c == STOP)    return END();
  if (c != 'C')     return 1;
  // C found
  c = getchar1 ();
  if (c == 'A')     return AWY();
  if (c == STOP)    return END();
  if (c != 'R')     return 1; 
  // R found

  printf ("RFMKCR found
");
  return 1;
}

int END(void)
{
  return 0;
}

int main ()
{
  printf ("
*start*
");
  while(START());
  printf ("*the end*
");
  return 0; 
}  

解决方案2)

#include <stdio.h>
#include <stdlib.h>

#define STOP '!'

int START()
{
int c;

START:
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == STOP)   goto END;
  goto START;

AWY:                // A found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == STOP)   goto END;
  if (c != 'W')    goto START;
  // W found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == STOP)   goto END;
  if (c != 'Y')    goto START;
  // Y found
  printf ("AWY found
");
  goto START;

RFMKCR:         // R found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == STOP)   goto END;
  if (c != 'F')    goto START;
  // F found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == '!')    goto END;
  if (c != 'M')    goto START;
  // M found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == '!')    goto END;
  if (c != 'K')    goto START;
  // K found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == 'R')    goto RFMKCR;
  if (c == STOP)   goto END;
  if (c != 'C')    goto START;
  // C found
  c = getchar1 ();
  if (c == 'A')    goto AWY;
  if (c == STOP)   goto END;
  if (c != 'R')    goto START;
  // R found
  printf ("RFMKCR found
");
  goto START;

END:
  return 0;
}

int getchar1(void) // wraper around your input
{ 
  char in;
  in = getchar(); // or scanf ("%c", &in);
  return in;
}

int main ()
{
  printf ("*start*
");
  START();
  printf ("*the end*
");
  return 0;
} 

两种解决方案都产生相同的输出。

INPUT的输出:AAWY AAWWAWY RRRFMKCR A A WY AWRFMCR AAA!

*start*                                                                                                                                                                                                                                                                                                                                                                                                                                                
AWY found                                                                                                                                                                                                                                        
AWY found                                                                                                                                                                                                                                        
RFMKCR found                                                                                                                                                                                                                                     
*the end* 

3)解决方案

/******************************************************************************

                 CLASSICAL STATE MACHINE APPROACH 

                 - take a notice how the generic `next` function service transitions
                 - together with the `start` helper.
                 - `next` and `start` have the same functions signatures
                 - and can be replaced with a function pointers

The resulting code is more complicated than previous two examples.

However: 
a) the input is taken only from one place (inside the while loop)
b) the generic nature of the code allows easy customization/

*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>


#define STOP             '!' // character chosen to stop processing


#define END               0
#define IDLE              1
#define START             2

#define AWY_A             3
#define AWY_W             4 
#define AWY_Y             5 

#define RFMKCR_R          6
#define RFMKCR_F          7
#define RFMKCR_M          8
#define RFMKCR_K          9
#define RFMKCR_C         10
#define RFMKCR_R_END     11

#define AWY_FOUND        12         
#define RFMKCR_FOUND     13
#define TO_BE_CALCULATED 14
#define UNKNOWN_STATE    15

// we keep here the current state and next state to which we will transit
struct state_machine_state
{
    int current_state;     
    int next_state;

    unsigned int debug_flag;
};


int getchar1 (void);

int start(struct state_machine_state *p, int c, int current_state, int char_expected, int next_state);
int next(struct state_machine_state *p, int c, int current_state, int char_expected, int next_state);

int state_machine(struct state_machine_state *p, int c);
int processing(void);

int getchar1 (void)
{
  int in;
  in = getchar();   //char in = scanf ("%c", &in);
  return in;
}

int next(struct state_machine_state *p, int c, int current_state, int char_expected, int next_state)
{
    // This generic function provides transitions to the required states based on the input `c` character
    // If c matches the expected character than we transition to known apriori next state 
    // If the input `c` does not match expected character then we re-start the hunt for patterns

    if (c == char_expected) 
    {
        if(p->debug_flag)
            printf("++: c=%c cs=%d next=%d 
", c, p->nex

以上是关于在没有数组的长序列中搜索模式字符串[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

数据库中的搜索模式[关闭]

KMP算法实现原理

在字符串数组中搜索特定字符串。 [关闭]

如何强制缠绕没有任何空白的长字符串?

在结构数组中搜索字符串变量[关闭]

Visual Studio 调试 - 将数组转储到文件