这样嵌套的重复代码,有什么方法可以优化吗?
除了for之外,还有什么地方是可以改进优化的吗?
新手一枚,还请大佬们多敲打
8 个解决方案
#1
没懂你的意思,你是想优化for的次数,还是迭代?
#2
这个for循环明显太重复了
#3
百度搜“字典法”
#4
你是要动态的生成排列组合吧!回溯法。
建议你看看这个文章:
https://blog.csdn.net/goldenhawking/article/details/80037669
Pn,m排列、Cnm组合,级联for循环展开,都可以用类似的思路。文章中最后有级联for的例子。
建议你看看这个文章:
https://blog.csdn.net/goldenhawking/article/details/80037669
Pn,m排列、Cnm组合,级联for循环展开,都可以用类似的思路。文章中最后有级联for的例子。
#5
#include <vector>
#include <stdio.h>
struct tag_FOR_State
{
std::vector<unsigned long long> vec_buf;
std::vector<unsigned long long> vec_bz;
int swim;
bool finished;
};
int fnm(const unsigned long long n[/*m*/], int m, std::vector<std::vector <unsigned long long> > & vec_output, tag_FOR_State * state, int limit/* = 0*/)
{
std::vector<unsigned long long> & vec_buf = state->vec_buf,
&vec_bz = state->vec_bz;
int &swim = state->swim;
bool &finished = state->finished;
if (vec_bz.size() == 0)
{
for (int i = 0; i<m; ++i) vec_buf.push_back(0);
vec_bz.push_back(0);
swim = 0;
finished = false;
}
if (finished == true)
return 0;
int group = 0;
do
{
unsigned long long ch = 0;
if (swim<m)
{
vec_buf[swim] = ch;
++swim;
}
if (swim == m)
{
vec_output.push_back(vec_buf);
++group;
bool hit = false;
do
{
--swim;
if (swim >= 0)
{
unsigned long long nextv = vec_buf[swim];
do
{
++nextv;
if (nextv >= n[swim])
break;
hit = true;
} while (hit == false);
if (hit == true)
{
vec_buf[swim] = nextv;
++swim;
}
}
else
finished = true;
} while (finished == false && hit == false);
if (group >= limit && limit>0)
break;
}
} while (finished == false);
return group;
}
int fnm_next(const unsigned long long n[/*m*/], int m, std::vector<std::vector <unsigned long long> > & vec_output, tag_FOR_State * state, int limit/* = 0*/)
{
std::vector<unsigned long long> & vec_buf = state->vec_buf,
&vec_bz = state->vec_bz;
int &swim = state->swim;
bool &finished = state->finished;
if (vec_bz.size() == 0)
{
for (int i = 0; i<m; ++i) vec_buf.push_back(0);
vec_bz.push_back(0);
swim = 0;
finished = false;
}
if (finished == true)
return 0;
int group = 0;
do
{
unsigned long long ch = 0;
if (swim<m)
{
vec_buf[swim] = ch;
++swim;
}
if (swim == m)
{
memcpy(vec_output[group].data(), vec_buf.data(), m * sizeof(unsigned long long));
++group;
bool hit = false;
do
{
--swim;
if (swim >= 0)
{
unsigned long long nextv = vec_buf[swim];
do
{
++nextv;
if (nextv >= n[swim])
break;
hit = true;
} while (hit == false);
if (hit == true)
{
vec_buf[swim] = nextv;
++swim;
}
}
else
finished = true;
} while (finished == false && hit == false);
if (group >= limit && limit>0)
break;
}
} while (finished == false);
return group;
}
int main()
{
tag_FOR_State state;
const unsigned long long n[] = { 26,26,10,4,10 };
const int m = sizeof(n)/sizeof(n[0]);
std::vector<std::vector<unsigned long long> > vec_res;
int nret = fnm(n, m, vec_res, &state, 1024);
while (nret)
{
for (int i = 0; i < nret; ++i)
printf("%c%c%c%c%c\r",
char(vec_res[i][0] + 'a'),
char(vec_res[i][1] + 'A'),
char(vec_res[i][2] + '!'),
char(vec_res[i][3] + '@'),
char(vec_res[i][4] + '0')
);
nret = fnm_next(n, m, vec_res, &state, 1024);
}
return 0;
}
#6
递归
#include "stdafx.h"
#include <string>
#define LastIndex 3
char a[] = "ddws";
char b[] = "aaaa";
void Next(int index);
int main()
{
Next(0);
return 0;
}
void Next(int index)
{
if (index > LastIndex)
{
if (strcmp(a, b) == 0)
{
printf("密码是%s", b);
}
return;
}
while (b[index] <= 'z')
{
int i = index;
while (++i <= LastIndex)
{
b[i] = 'a';
}
Next(index + 1);
b[index]++;
}
}
#include "stdafx.h"
#include <string>
#define LastIndex 3
char a[] = "ddws";
char b[] = "aaaa";
void Next(int index);
int main()
{
Next(0);
return 0;
}
void Next(int index)
{
if (index > LastIndex)
{
if (strcmp(a, b) == 0)
{
printf("密码是%s", b);
}
return;
}
while (b[index] <= 'z')
{
int i = index;
while (++i <= LastIndex)
{
b[i] = 'a';
}
Next(index + 1);
b[index]++;
}
}
#7
这样相当于26进制数的递增吧。
#include <string>
#define LEN 4
void main() {
char pwd[LEN + 1] = "sdfa";
char str[LEN + 1] = "aaaa";
while ( str[LEN] <= 'z' && strcmp( str, pwd ) != 0 ) {
for ( int i = 0; i < LEN; ++i ) {
if ( ++str[i] > 'z' ) {
str[i] = 'a';
}
else {
break;
}
}
}
printf( "%s\n", str );
getchar();
}
#8
while (++i <= LastIndex)
这个为什么用while而不用if呢?
#1
没懂你的意思,你是想优化for的次数,还是迭代?
#2
这个for循环明显太重复了
#3
百度搜“字典法”
#4
你是要动态的生成排列组合吧!回溯法。
建议你看看这个文章:
https://blog.csdn.net/goldenhawking/article/details/80037669
Pn,m排列、Cnm组合,级联for循环展开,都可以用类似的思路。文章中最后有级联for的例子。
建议你看看这个文章:
https://blog.csdn.net/goldenhawking/article/details/80037669
Pn,m排列、Cnm组合,级联for循环展开,都可以用类似的思路。文章中最后有级联for的例子。
#5
#include <vector>
#include <stdio.h>
struct tag_FOR_State
{
std::vector<unsigned long long> vec_buf;
std::vector<unsigned long long> vec_bz;
int swim;
bool finished;
};
int fnm(const unsigned long long n[/*m*/], int m, std::vector<std::vector <unsigned long long> > & vec_output, tag_FOR_State * state, int limit/* = 0*/)
{
std::vector<unsigned long long> & vec_buf = state->vec_buf,
&vec_bz = state->vec_bz;
int &swim = state->swim;
bool &finished = state->finished;
if (vec_bz.size() == 0)
{
for (int i = 0; i<m; ++i) vec_buf.push_back(0);
vec_bz.push_back(0);
swim = 0;
finished = false;
}
if (finished == true)
return 0;
int group = 0;
do
{
unsigned long long ch = 0;
if (swim<m)
{
vec_buf[swim] = ch;
++swim;
}
if (swim == m)
{
vec_output.push_back(vec_buf);
++group;
bool hit = false;
do
{
--swim;
if (swim >= 0)
{
unsigned long long nextv = vec_buf[swim];
do
{
++nextv;
if (nextv >= n[swim])
break;
hit = true;
} while (hit == false);
if (hit == true)
{
vec_buf[swim] = nextv;
++swim;
}
}
else
finished = true;
} while (finished == false && hit == false);
if (group >= limit && limit>0)
break;
}
} while (finished == false);
return group;
}
int fnm_next(const unsigned long long n[/*m*/], int m, std::vector<std::vector <unsigned long long> > & vec_output, tag_FOR_State * state, int limit/* = 0*/)
{
std::vector<unsigned long long> & vec_buf = state->vec_buf,
&vec_bz = state->vec_bz;
int &swim = state->swim;
bool &finished = state->finished;
if (vec_bz.size() == 0)
{
for (int i = 0; i<m; ++i) vec_buf.push_back(0);
vec_bz.push_back(0);
swim = 0;
finished = false;
}
if (finished == true)
return 0;
int group = 0;
do
{
unsigned long long ch = 0;
if (swim<m)
{
vec_buf[swim] = ch;
++swim;
}
if (swim == m)
{
memcpy(vec_output[group].data(), vec_buf.data(), m * sizeof(unsigned long long));
++group;
bool hit = false;
do
{
--swim;
if (swim >= 0)
{
unsigned long long nextv = vec_buf[swim];
do
{
++nextv;
if (nextv >= n[swim])
break;
hit = true;
} while (hit == false);
if (hit == true)
{
vec_buf[swim] = nextv;
++swim;
}
}
else
finished = true;
} while (finished == false && hit == false);
if (group >= limit && limit>0)
break;
}
} while (finished == false);
return group;
}
int main()
{
tag_FOR_State state;
const unsigned long long n[] = { 26,26,10,4,10 };
const int m = sizeof(n)/sizeof(n[0]);
std::vector<std::vector<unsigned long long> > vec_res;
int nret = fnm(n, m, vec_res, &state, 1024);
while (nret)
{
for (int i = 0; i < nret; ++i)
printf("%c%c%c%c%c\r",
char(vec_res[i][0] + 'a'),
char(vec_res[i][1] + 'A'),
char(vec_res[i][2] + '!'),
char(vec_res[i][3] + '@'),
char(vec_res[i][4] + '0')
);
nret = fnm_next(n, m, vec_res, &state, 1024);
}
return 0;
}
#6
递归
#include "stdafx.h"
#include <string>
#define LastIndex 3
char a[] = "ddws";
char b[] = "aaaa";
void Next(int index);
int main()
{
Next(0);
return 0;
}
void Next(int index)
{
if (index > LastIndex)
{
if (strcmp(a, b) == 0)
{
printf("密码是%s", b);
}
return;
}
while (b[index] <= 'z')
{
int i = index;
while (++i <= LastIndex)
{
b[i] = 'a';
}
Next(index + 1);
b[index]++;
}
}
#include "stdafx.h"
#include <string>
#define LastIndex 3
char a[] = "ddws";
char b[] = "aaaa";
void Next(int index);
int main()
{
Next(0);
return 0;
}
void Next(int index)
{
if (index > LastIndex)
{
if (strcmp(a, b) == 0)
{
printf("密码是%s", b);
}
return;
}
while (b[index] <= 'z')
{
int i = index;
while (++i <= LastIndex)
{
b[i] = 'a';
}
Next(index + 1);
b[index]++;
}
}
#7
这样相当于26进制数的递增吧。
#include <string>
#define LEN 4
void main() {
char pwd[LEN + 1] = "sdfa";
char str[LEN + 1] = "aaaa";
while ( str[LEN] <= 'z' && strcmp( str, pwd ) != 0 ) {
for ( int i = 0; i < LEN; ++i ) {
if ( ++str[i] > 'z' ) {
str[i] = 'a';
}
else {
break;
}
}
}
printf( "%s\n", str );
getchar();
}
#8
while (++i <= LastIndex)
这个为什么用while而不用if呢?