当我有20个字符串(字符串行)和26个字母时,我遇到了问题。现在它打印acaaaaaaaaaaaaaaaaaa为那个例子,26个字母是字母表。排列的数量要大到存储。他将要求1048576排列的最高排列。我想打印第n个(强度)排列。
如何解决跳过数量大的堆栈溢出问题?我已经尝试将int更改为long long。我已经使用printf查看排列的数量,并且我得到了与int一样长的相同数字。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ALPHA 28
typedef struct {
int yourpass;
char letters[ALPHA];
int temp;
int skips;
} password;
//declare functions
void FindVariations(int passlength, int strength, password *combo, int j, int x);
void magical(password *combo, int passlength);
int main() {
int i, j, d, cases, passlength;
int strength;
password* combo;
combo = malloc(ALPHA*sizeof(password));
// enter number of passwords to compute
scanf("%d", &cases);
for (i=0; i<cases; i++) {
//enter number of strings/length of password
scanf(" %d ", &passlength);
// input the letters for password
for (j=0; j<passlength; j++) {
scanf(" %s ", combo[j].letters);
combo[j].temp = strlen(combo[j].letters);
}
scanf("%d", &strength);
// find the total nnumber of permutations
magical(combo, passlength);
// find the permutation to print
FindVariations( passlength, strength, combo, 1, 0);
// print the wanted password
for(d=0; d<passlength; d++) {
printf("%c", combo[d].letters[combo[d].yourpass]);
}
printf("\n");
}
free(combo);
return 0;
}
void magical(password *combo, int passlength) {
int i;
int total=0;
for(i=(passlength-1); i>=0; i--) {
if(i==(passlength-1)) {
combo[i].skips=1;
total=combo[i].temp;
}
else {
combo[i].skips=total;
total*= combo[i].temp;
}
}
}
void FindVariations(int passlength, int strength, password *combo, int j, int x) {
combo[x].yourpass = 0;
if(x==passlength){
return;
}
if (x<passlength) {
while(j<=strength-combo[x].skips) {
combo[x].yourpass+=1;
j+=combo[x].skips;
}
}
FindVariations( passlength, strength, combo, j, x+1);
}
答案 0 :(得分:3)
你明白堆栈溢出是什么吗?在你的情况下,这不是存储大数字的问题。这是通过使用大量递归函数调用来使用大量内存的问题。
每次进行函数调用时,编译器都会将函数的参数和内部变量的空间添加到程序的堆栈内存中。如果在函数调用中执行了很多函数调用,这会使程序的堆栈内存超出其允许的限制,从而产生堆栈溢出错误。
但是,对于程序而言,一旦进行FindVariations
函数调用,就不需要先前的变量值,因此实际上并不需要内存开销是由递归函数调用引起的。这称为Tail Recursion。
防止堆栈溢出的最简单方法是将递归解决方案转换为迭代解决方案。
void FindVariations(int passlength, int strength, password *combo, int j, int x)
{
for (combo[x].yourpass = 0; x < passlength; x++)
{
while(j <= strength-combo[x].skips)
{
combo[x].yourpass+=1;
j+=combo[x].skips;
}
}
}