[英]How to iteratively generate all possible combinations of letters and numbers for matching with a variable length string?
我希望编写一个迭代逻辑程序,其中有一个输入字符串,该程序从长度1开始,并尝试所有可能的字母和数字组合。 如果找不到匹配项,它将尝试使用所有长度为2的字母和数字的组合,依此类推,直到找到与输入字符串匹配的为止。
例如,
string input = "xG7a";
// loop all possible combinations for length 1, i.e., 0-9 then A-Z, then a - z
// check for all if matches the input string
// loop all possible combinations for length 2, i.e., 00-09, then 0A-0Z, then 0a - 0z. Then
// for 10-19, then 1A-1Z, then 1a - 1z ... till z0-z9, then zA-zZ, then za - zz
// again check for all if matches the input string
// Keep doing this for lengths 3, 4, 5 and so on till it matches with the input string.
// exit with status success if match else keep going till infinity
// This example would exit at length 4 when it matches with "xG7a"
此处匹配的所有可能组合的数量为(10 + 26 + 26 = 62)= 62 ^ 1 + 62 ^ 2 + 62 ^ 3 + ...直到找到匹配项。
编辑更多详细信息:
预先感谢您提供的所有帮助。
用正确的顺序创建一个包含所有可能字符的字符串:
char charlist[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
然后针对您要检查的每个字符,遍历此字符串以构建测试字符串并进行比较:
int i, found;
char str_to_test[5];
for (i=0, found=0; !found && i<strlen(charlist); i++) {
str_to_test[0] = charlist[i];
str_to_test[1] = 0;
if (!strcmp(str_to_test, target_string)) {
found = 1;
}
}
if (found) {
printf("found it!\n");
} else {
printf("not found\n");
}
对每个子字符串重复嵌套循环。
您说-我说的是一些伪代码- 完整的工作程序 !
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MARGIN 5
// if you're getting errors due to redeclaration of 'strdup', just remove that
const char *strdup(const char *string) {
const size_t len = strlen(string);
char *dst = calloc(len + 1, sizeof(char));
memmove(dst, string, len);
return dst;
}
struct NumeralSystem {
char *alphabet;
size_t base;
};
struct Word {
struct NumeralSystem ns;
char *data; // the current combination, null-terminated
unsigned int *_internal; // indices of the characters of 'data' in 'ns.alphabet'
size_t length, maxLength;
};
struct NumeralSystem NewSystem(const char *alpha) {
struct NumeralSystem ret = {strdup(alpha), strlen(alpha)};
return ret;
}
struct Word NewWordEmpty(const struct NumeralSystem ns, const size_t maxLength) {
struct Word ret;
ret.ns = ns;
ret.data = calloc(maxLength + 1, sizeof(char));
ret._internal = calloc(maxLength + 1, sizeof(unsigned int));
ret.maxLength = maxLength;
*ret._internal = 0;
*ret.data = *ret.ns.alphabet;
ret.length = 1;
return ret;
}
struct Word NewWordPreset(const struct NumeralSystem ns, const char *data) {
struct Word ret;
ret.length = strlen(data);
const size_t maxLength = ret.length + MARGIN;
ret.ns = ns;
ret.data = calloc(maxLength + 1, sizeof(char));
ret._internal = calloc(maxLength + 1, sizeof(unsigned int));
ret.maxLength = maxLength;
memmove(ret.data, data, ret.length);
for (size_t i = 0; i < ret.length; ++i) {
const char *found = strchr(ns.alphabet, ret.data[i]);
if (found == NULL) return NULL;
ret._internal[i] = found - ns.alphabet;
}
return ret;
}
void EnlargeWord(struct Word *wrd) { // here, wrd->length - wrd->maxLength == 1
const size_t newSize = wrd->maxLength + MARGIN;
wrd->data = realloc(wrd->data, newSize * sizeof(char));
wrd->_internal = realloc(wrd->_internal, newSize * sizeof(int));
memset(wrd->data + wrd->maxLength + 1, 0, MARGIN);
memset(wrd->_internal + wrd->maxLength + 1, 0, MARGIN);
wrd->maxLength = newSize;
}
void DestroyWord(struct Word *wrd) {
free(wrd->data), free(wrd->_internal);
}
struct Word *next(struct Word *wrd) {
int len = (int)(wrd->length - 1); // this can be negative, see below
// handle the overflow if current digit is equal to the last_digit of the alphabet
// 1. last_digit -> first_digit
// 2. go to previous position
while ((len >= 0) && (wrd->_internal[len] == wrd->ns.base - 1)) {
wrd->_internal[len] = 0;
wrd->data[len--] = *wrd->ns.alphabet;
}
// if all the digits in the word were equal to the last_digit of the alphabet,
// 'len' will be exactly (-1), and the word's length must increase
if (len == -1) {
wrd->data[wrd->length++] = *wrd->ns.alphabet;
// UH-OH, we're about to run out of bounds soon!
if (wrd->length > wrd->maxLength)
EnlargeWord(wrd);
return wrd;
}
// if 'len' is still nonnegative, it's the position of the digit
// that we haven't increased yet
wrd->data[len] = wrd->ns.alphabet[++wrd->_internal[len]];
return wrd;
}
int main(void) {
const struct NumeralSystem ns = NewSystem("abcdef");
struct Word wrd = NewWordPreset(ns, "deadbeef");
printf("%s\n", wrd.data);
for (unsigned int i = 0; i < 30; ++i)
printf("%s\n", next(&wrd)->data);
DestroyWord(&wrd);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.