在没有数组的长序列中搜索模式字符串[关闭]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在没有数组的长序列中搜索模式字符串[关闭]相关的知识,希望对你有一定的参考价值。
我想问一下如何使用getchar()在不同字符的长输入中搜索两种模式(例如RFMKCR和AWY)?
P.S不允许使用数组。谢谢!
答案
这是状态机的完整代码,它从通用函数getchar1()
获取输入。模式:AWY
和RFMKCR
被认可和报告。
函数getchar1()
只是从输入中获取char的任何函数的包装器。可以在里面使用getchar()
或scanf
。由STOP
定义的char终止输入处理。
这个问题的困难来自需要寻找两种模式的开头:AWY
和RFMKCR
同时。我们可能被迫切换到寻找另一个模式中间的不同模式或重新同步。
给出了三个完整的解决方案
第一种解决方案使用递归。
第二种解决方案使用简单的goto
结构,避免递归调用。这种方法对于这个特定问题非常有效。
注意:在C中通常不鼓励使用goto
。尽可能使用break
,continue
和return
语句而不是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以上是关于在没有数组的长序列中搜索模式字符串[关闭]的主要内容,如果未能解决你的问题,请参考以下文章