[英]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.