1

我需要从字符集中生成所有可能的组合。

"abcdefghijklmnopqstuvxyz"

生成的模式应该像这样输出。

a
b
...
z
aa
ab
...
az
ba
...

这将在长度为 8 的情况下完成。即a=>zzzzzzzz。我已经通过用 C 编写一个示例来解决这个问题,并为此使用了递归函数。我知道它写得又快又脏,但希望你能有所了解。

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

#define WIDTH 8
char *charset = "abcdefghijklmnopqrstuvxyz";

void charset_r(int width, int pos, char *s)
{
    char buf[WIDTH];
    char *p = charset;

    while(*p!='\0')
    {
        strcpy(buf, s);
        if(pos<width)
        {
            strncat(buf, p, 1);
            printf("%s\n", buf);
            charset_r(width, pos+1, buf);
        }
        p++;
    }
}

int main(void)
{
    int i;
    for(i=0;i<=WIDTH;i++)
        charset_r(i,0,"");
}

我的问题是双重的:

  1. 我应该在 VHDL 中使用递归吗?
  2. 如果没有,我该如何解决这个问题?

更新:

因此,最终目标是合成代码并将值输出到时钟端口。据我了解,通过阅读评论递归可能是深度 2 之外的一个坏主意,因此最好以其他方式解决它,而不使用递归。

由于除了递归之外,我无法以任何其他方式思考这个问题(似乎无法弄清楚),任何指针或建议(甚至代码!)将不胜感激。

4

2 回答 2

4

您最好将其视为硬件问题而不是软件问题。您有八个状态变量——序列中的每个字符一个。如果您为每个字符使用 5 位计数器,那么您可以表示所有字符 [az],加上一个空状态(可能为零)以知道何时不输出该字符。

然后,您需要某种状态机来按照一组简单的规则递增计数器:“始终递增计数器 0。如果计数器 0 为 26,则将其设置为 0 并递增计数器 1……等等”。这将推动你的内部状态。

然后创建一个输出进程,查看计数器并决定及时输出哪个字符(或者如果计数器没有增加到零以上,则根本不输出字符)。如果您将字符连续输出,此过程将花费不同的时间来执行,因此它可能会充当推进状态机的触发器。

这里没有代码,只是方法的概述。但是我认为,如果您按照这些思路考虑它,它将对您有所帮助。

于 2013-01-14T15:00:07.927 回答
1

您可以将每个字符组合视为以 26 为基数的数字(即序列中的字符数)。这样,每个数字都隐含地告诉你后面的字符串序列。您可以将数字转换为基数 26 并获取字符串。当然,您需要对每个长度的字符串重复此过程。我已经为您编写了一个简单的代码来演示这个想法。您可以使用可综合的语言子集在 VHDL 中实现它。

for( int i = 1 ; i<= 8 ; ++i )
{
    for( int j = 0 ; j < pow(26,i) ; ++j )
    {
           foo( j , i  );
    }
}


void foo( int num , int len)
{
    char digits[len+1];
    // convert num from base 10 to base 26 and fill digits array with proper values in range 0-25
    toBase26(num,digits,len);
    digits[len] = '\0';
    for( int i = 0 ; i < len ; ++i )
    {
              digits[i] = digits[i] + 97 ; //  97 == 'a'
    }
    // do proper thing with your sequence

}
于 2013-01-14T12:00:30.817 回答