我刚刚在C中写了一个单词列表生成器,大约需要2天。我使用专用的int数组来存储索引,并使用数字基础的概念递增它们。这是我的源代码:
/*
* Generates word lists from a character set
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int power(int x, int y);
void ntoarray(int n, int base, int seq[], int len);
void setchar(char charset[], char word[], int indices[]);
int main(int argc, char *argv[])
{
// checks arguments
if (argc != 4)
{
printf("Usage: %s start_length end_length charset", argv[0]);
return 1;
}
else
{
// loops from start length to end length
for (int lenword = atoi(argv[1]), lim = atoi(argv[2]); lenword <= lim; lenword++)
{
// pointer to character set
char *charset = argv[3];
// length of the character set
int lencharset = strlen(charset);
// array for the word
char word[lenword + 1];
word[lenword] = '\0';
// array for storing the indices to generate the word from the character set
int indices[lenword];
// number to convert to required base
int n = 0;
// repetition is allowed so the number of times to loop is number^choice
for (int i = 0; i < power(lencharset, lenword); i++)
{
// converts number to an integer array with length of the charset as the base
ntoarray(n++, lencharset, indices, lenword);
// sets the word according to the indices array
setchar(charset, word, indices);
// prints the word
printf("%s\n", word);
}
}
return 0;
}
}
// simple power algorithm which raises x to the power y
int power(int x, int y)
{
int n = 1;
for (int i = 0; i < y; i++)
n *= x;
return n;
}
// converts n to the required base and stores it in an integer array
void ntoarray(int n, int base, int seq[], int len)
{
int i = len - 1;
memset(seq, 0, sizeof(int) * len);
while (i >= 0 && n >= base)
{
int r = n % base;
n /= base;
seq[i--] = r;
}
seq[i] = n;
}
// sets the word by combining the data from the indices array and the charset array
void setchar(char charset[], char word[], int indices[])
{
int len = strlen(word);
for (int i = 0; i < len; i++)
{
word[i] = charset[indices[i]];
}
}
现在我使用类似的想法在python3中重写了它,但它只花了大约一个小时。
"""
Generates word lists from a character set.
"""
import argparse
def main():
# checks arguments
parser = argparse.ArgumentParser()
parser.add_argument("start_length", help = "starting length for your words", type = int)
parser.add_argument("end_length", help = "ending length for your words", type = int)
parser.add_argument("charset", help = "character set to be used", type = str)
args = parser.parse_args()
charset = args.charset
len_charset = len(charset)
# loops from start_length to end_length
for length in range(args.start_length, args.end_length + 1):
# initializes indices list
indices = [0] * length
# prints the word
print(genword(charset, indices))
# increments the indices list and prints the word until the limit
# repetition is allowed so the number of loops is base ^ length - 1 (-1 for the printed word)
for i in range(len_charset ** length - 1):
inc_seq(indices, len_charset)
print(genword(charset, indices))
def inc_seq(seq, base, index=-1):
"""
Increments a number sequence with a specified base by one.
"""
if seq[index] < base - 1:
seq[index] += 1
else:
inc_seq(seq, base, index - 1)
seq[index] = 0
def genword(charset, indices):
"""
Generates a word by combining a character set and a list of indices.
"""
return "".join([charset[i] for i in indices])
if __name__ == "__main__":
main()
有一个显着的区别:在C中,我增加了一个中间数n并用它来修改int数组;在python中,我利用负指数的力量直接增加了int列表。
我主要通过自学(即阅读书籍和使用在线资源)学习编码,但我还不知道如何正确分析算法。所以我的问题是:在时间和空间方面哪个版本更有效?