如果结果中没有重复的元素,那么我将使用修改后的 埃拉托色尼筛 来标记所有最终序列号,然后创建序列本身的表。这里的C++小例子:
// globals
const int N0=4;
const int N1=6;
const int N2=N0*N1;
const int M=(N0+2)*(N0+2)*(N0+2)*N1;
int f0(int x) { x+=2; return x*x*x; } // x = <0,N0)
int f1(int x) { x+=1; return x; } // x = <0,N1)
int f2[N2],n; // x = <0,n )
// locals
int x,y;
BYTE soe[M+1];
AnsiString txt="";
// debug print series
for (txt+="f0(x) = ",x=0;x<N0;x++) { txt+=f0(x); txt+=" "; } txt+="\r\n";
for (txt+="f1(x) = ",x=0;x<N1;x++) { txt+=f1(x); txt+=" "; } txt+="\r\n";
tbeg();
// compute sieve
for (x=0;x<=M;x++) soe[x]=0;
for (x=0;x<N0;x++)
for (y=0;y<N1;y++)
soe[f0(x)*f1(y)]=1;
// reorder it to table
for (x=0,n=0;x<=M;x++)
if (soe[x]) { f2[n]=x; n++; }
tend(); txt+="computed in "+tstr(1)+"\r\n";
// debug print ordered series as function of x ... counting from 0
for (txt+="f2(x) = ",x=0;x<n;x++) { txt+=f2[x]; txt+=" "; } txt+="\r\n";
Form1->mm_log->Lines->Add(txt);
结果:
f0(x) = 8 27 64 125
f1(x) = 1 2 3 4 5 6
computed in [ 0.003 ms]
f2(x) = 8 16 24 27 32 40 48 54 64 81 108 125 128 135 162 192 250 256 320 375 384 500 625 750
只需忽略 tbeg(),tend(),tstr() 和字符串 Form1->mm_log,txt 的东西或重写到您的平台/IDE。这还没有优化,可以改进很多......例如,您可以使用每个筛子元素一位而不是BYTE,甚至避免使用内存中的整个筛子表(通过巧妙的排序/分区子结果)。
如果输出中存在重复项,那么您需要使用筛子作为元素的计数器,而不仅仅是布尔值并相应地重建它。