迭代字符串枚举
Iterative String Enumeration
我正在尝试构建一个程序来枚举给定字母表中所有可能的字符串。我计划之后在算法上使用分布式和并行技术,因此递归不是一种选择。到目前为止,我尝试的是这样的:
const char alph[] = "01";
char **
generate(int size)
{
int i, j, k;
char str[10];
memset(str, alph[0], size);
str[size] = '[=10=]';
for (i = size-2; i >= -1; --i) {
for (j = size-1; j > i; --j) {
for (k = 0; k < strlen(alph); k++) {
str[j] = alph[k];
printf("%s\n", str);
}
}
}
}
所以 generate(2)
的结果应该是 {00, 01, 10, 11}。但是在当前的实现中,我得到了 {00, 01, 00, 01, 01, 11}。我想这是索引的问题,但我找不到哪个索引。
尺寸 2 的简单解决方案
这是一个简单的解决方案,但它仅适用于尺寸 2:
#include <stdio.h>
#include <string.h>
const char alph[] = "01";
// Note: This only works for size 2
void generate(int size) {
char str[10];
str[size] = 0;
for (int i = 0; i < strlen(alph); i++) {
str[0] = alph[i];
for (int j = 0; j < strlen(alph); j++) {
str[1] = alph[j];
printf("%s\n", str);
}
}
}
int main() {
generate(2);
}
有两个嵌套循环,每个循环对应于输出字符串中的一个位置。如果你想增加输出字符串的长度,一般的想法是增加更多的循环。通常,递归用于执行此操作,但您在问题中禁止递归。
更通用的解决方案
这是一个更通用的解决方案,它做的工作更多,但更容易并行化。它首先计算输出中的行数,然后调用 print_line
打印每一行。对 print_line
的调用都可以是 运行 并行的,我想,只要你做一些事情来确保输出以所需的顺序打印。
#include <stdio.h>
#include <string.h>
#include <stdint.h>
const char alph[] = "01";
void print_line(uint64_t v, int size)
{
char str[size + 1];
str[size] = 0;
for (int i = size - 1; i >= 0; i--)
{
str[i] = alph[v % strlen(alph)];
v /= strlen(alph);
}
printf("%s\n", str);
}
void generate(int size) {
uint64_t output_line_count = 1;
for (int i = 0; i < size; i++) { output_line_count *= strlen(alph); }
for (uint64_t v = 0; v < output_line_count; v++)
{
print_line(v, size);
}
}
int main() {
generate(3);
}
我正在尝试构建一个程序来枚举给定字母表中所有可能的字符串。我计划之后在算法上使用分布式和并行技术,因此递归不是一种选择。到目前为止,我尝试的是这样的:
const char alph[] = "01";
char **
generate(int size)
{
int i, j, k;
char str[10];
memset(str, alph[0], size);
str[size] = '[=10=]';
for (i = size-2; i >= -1; --i) {
for (j = size-1; j > i; --j) {
for (k = 0; k < strlen(alph); k++) {
str[j] = alph[k];
printf("%s\n", str);
}
}
}
}
所以 generate(2)
的结果应该是 {00, 01, 10, 11}。但是在当前的实现中,我得到了 {00, 01, 00, 01, 01, 11}。我想这是索引的问题,但我找不到哪个索引。
尺寸 2 的简单解决方案
这是一个简单的解决方案,但它仅适用于尺寸 2:
#include <stdio.h>
#include <string.h>
const char alph[] = "01";
// Note: This only works for size 2
void generate(int size) {
char str[10];
str[size] = 0;
for (int i = 0; i < strlen(alph); i++) {
str[0] = alph[i];
for (int j = 0; j < strlen(alph); j++) {
str[1] = alph[j];
printf("%s\n", str);
}
}
}
int main() {
generate(2);
}
有两个嵌套循环,每个循环对应于输出字符串中的一个位置。如果你想增加输出字符串的长度,一般的想法是增加更多的循环。通常,递归用于执行此操作,但您在问题中禁止递归。
更通用的解决方案
这是一个更通用的解决方案,它做的工作更多,但更容易并行化。它首先计算输出中的行数,然后调用 print_line
打印每一行。对 print_line
的调用都可以是 运行 并行的,我想,只要你做一些事情来确保输出以所需的顺序打印。
#include <stdio.h>
#include <string.h>
#include <stdint.h>
const char alph[] = "01";
void print_line(uint64_t v, int size)
{
char str[size + 1];
str[size] = 0;
for (int i = size - 1; i >= 0; i--)
{
str[i] = alph[v % strlen(alph)];
v /= strlen(alph);
}
printf("%s\n", str);
}
void generate(int size) {
uint64_t output_line_count = 1;
for (int i = 0; i < size; i++) { output_line_count *= strlen(alph); }
for (uint64_t v = 0; v < output_line_count; v++)
{
print_line(v, size);
}
}
int main() {
generate(3);
}