您可以将状态建模为一个结构数组,每个结构都包含一个用于转换的函数指针和一个可能的目标状态数组。
然后,创建一个获取当前状态和目标状态的函数,并让它遍历可能的状态列表。如果一个匹配目的地,把它放在一个空的状态列表的开头并返回列表。如果不是,则递归每个可能的中间状态,直到其中一个返回非空列表并将当前状态添加到列表的前面。
递归函数返回后,您可以遍历运行转换的列表。
#include <stdio.h>
#include <stdlib.h>
typedef void (*func)(void); // modify as needed
typedef enum { NONE=-1, A, B, C, D, E, F, G, H, MAX_STATES } states;
struct transitions {
func transition;
states slist[MAX_STATES];
};
struct tlist {
struct transitions *trans;
struct tlist *next;
};
void trans_a(void) { printf("transition A\n"); }
void trans_b(void) { printf("transition B\n"); }
void trans_c(void) { printf("transition C\n"); }
void trans_d(void) { printf("transition D\n"); }
void trans_e(void) { printf("transition E\n"); }
void trans_f(void) { printf("transition F\n"); }
void trans_g(void) { printf("transition G\n"); }
void trans_h(void) { printf("transition H\n"); }
struct transitions transitions[] = {
{ trans_a, { B, NONE } },
{ trans_b, { A, C, NONE } },
{ trans_c, { B, D, NONE } },
{ trans_d, { C, G, E, NONE } },
{ trans_e, { D, F, NONE } },
{ trans_f, { E, NONE } },
{ trans_g, { D, H, NONE } },
{ trans_h, { G, NONE } }
};
struct tlist *getStates(states prev, states start, states end)
{
int i;
for (i = 0; transitions[start].slist[i] != NONE; i++) {
if (transitions[start].slist[i] == prev) continue;
if (transitions[start].slist[i] == end) {
struct tlist *entry = malloc(sizeof *entry);
entry->trans = transitions + start;
entry->next = NULL;
return entry;
}
struct tlist *list = getStates(start, transitions[start].slist[i], end);
if (list) {
struct tlist *entry = malloc(sizeof *entry);
entry->trans = transitions + start;
entry->next = list;
return entry;
}
}
return NULL;
}
void runStates(states start, states end)
{
printf("from %d to %d\n", start, end);
struct tlist *list = getStates(NONE,start,end);
while (list) {
struct tlist *tmp = list;
list->trans->transition();
list = list->next;
free(tmp);
}
printf("\n");
}
int main()
{
runStates(A,H);
runStates(A,E);
runStates(E,A);
runStates(F,H);
return 0;
}
输出:
from 0 to 7
transition A
transition B
transition C
transition D
transition G
from 0 to 4
transition A
transition B
transition C
transition D
from 4 to 0
transition E
transition D
transition C
transition B
from 5 to 7
transition F
transition E
transition D
transition G