如何用一个最小的BYTE 数组存放下列数据

northwolves 2005-11-15 09:52:49
发了一个小小软件,"快速分解质因数 ",http://www.kehui.net/index.php/download/read/1/1109


有个问题想请大家给予帮助:

使用BYTE 数组存放下列数据(比如1-10000内的素数),用一个过程可以读取并显示,如何能做到运行最快,代码最短,数组最小?


2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017 2027 2029 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137 2141 2143 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 2293 2297 2309 2311 2333 2339 2341 2347 2351 2357 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693 2699 2707 2711 2713 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791 2797 2801 2803 2819 2833 2837 2843 2851 2857 2861 2879 2887 2897 2903 2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 3001 3011 3019 3023 3037 3041 3049 3061 3067 3079 3083 3089 3109 3119 3121 3137 3163 3167 3169 3181 3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 3259 3271 3299 3301 3307 3313 3319 3323 3329 3331 3343 3347 3359 3361 3371 3373 3389 3391 3407 3413 3433 3449 3457 3461 3463 3467 3469 3491 3499 3511 3517 3527 3529 3533 3539 3541 3547 3557 3559 3571 3581 3583 3593 3607 3613 3617 3623 3631 3637 3643 3659 3671 3673 3677 3691 3697 3701 3709 3719 3727 3733 3739 3761 3767 3769 3779 3793 3797 3803 3821 3823 3833 3847 3851 3853 3863 3877 3881 3889 3907 3911 3917 3919 3923 3929 3931 3943 3947 3967 3989 4001 4003 4007 4013 4019 4021 4027 4049 4051 4057 4073 4079 4091 4093 4099 4111 4127 4129 4133 4139 4153 4157 4159 4177 4201 4211 4217 4219 4229 4231 4241 4243 4253 4259 4261 4271 4273 4283 4289 4297 4327 4337 4339 4349 4357 4363 4373 4391 4397 4409 4421 4423 4441 4447 4451 4457 4463 4481 4483 4493 4507 4513 4517 4519 4523 4547 4549 4561 4567 4583 4591 4597 4603 4621 4637 4639 4643 4649 4651 4657 4663 4673 4679 4691 4703 4721 4723 4729 4733 4751 4759 4783 4787 4789 4793 4799 4801 4813 4817 4831 4861 4871 4877 4889 4903 4909 4919 4931 4933 4937 4943 4951 4957 4967 4969 4973 4987 4993 4999 5003 5009 5011 5021 5023 5039 5051 5059 5077 5081 5087 5099 5101 5107 5113 5119 5147 5153 5167 5171 5179 5189 5197 5209 5227 5231 5233 5237 5261 5273 5279 5281 5297 5303 5309 5323 5333 5347 5351 5381 5387 5393 5399 5407 5413 5417 5419 5431 5437 5441 5443 5449 5471 5477 5479 5483 5501 5503 5507 5519 5521 5527 5531 5557 5563 5569 5573 5581 5591 5623 5639 5641 5647 5651 5653 5657 5659 5669 5683 5689 5693 5701 5711 5717 5737 5741 5743 5749 5779 5783 5791 5801 5807 5813 5821 5827 5839 5843 5849 5851 5857 5861 5867 5869 5879 5881 5897 5903 5923 5927 5939 5953 5981 5987 6007 6011 6029 6037 6043 6047 6053 6067 6073 6079 6089 6091 6101 6113 6121 6131 6133 6143 6151 6163 6173 6197 6199 6203 6211 6217 6221 6229 6247 6257 6263 6269 6271 6277 6287 6299 6301 6311 6317 6323 6329 6337 6343 6353 6359 6361 6367 6373 6379 6389 6397 6421 6427 6449 6451 6469 6473 6481 6491 6521 6529 6547 6551 6553 6563 6569 6571 6577 6581 6599 6607 6619 6637 6653 6659 6661 6673 6679 6689 6691 6701 6703 6709 6719 6733 6737 6761 6763 6779 6781 6791 6793 6803 6823 6827 6829 6833 6841 6857 6863 6869 6871 6883 6899 6907 6911 6917 6947 6949 6959 6961 6967 6971 6977 6983 6991 6997 7001 7013 7019 7027 7039 7043 7057 7069 7079 7103 7109 7121 7127 7129 7151 7159 7177 7187 7193 7207 7211 7213 7219 7229 7237 7243 7247 7253 7283 7297 7307 7309 7321 7331 7333 7349 7351 7369 7393 7411 7417 7433 7451 7457 7459 7477 7481 7487 7489 7499 7507 7517 7523 7529 7537 7541 7547 7549 7559 7561 7573 7577 7583 7589 7591 7603 7607 7621 7639 7643 7649 7669 7673 7681 7687 7691 7699 7703 7717 7723 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 7927 7933 7937 7949 7951 7963 7993 8009 8011 8017 8039 8053 8059 8069 8081 8087 8089 8093 8101 8111 8117 8123 8147 8161 8167 8171 8179 8191 8209 8219 8221 8231 8233 8237 8243 8263 8269 8273 8287 8291 8293 8297 8311 8317 8329 8353 8363 8369 8377 8387 8389 8419 8423 8429 8431 8443 8447 8461 8467 8501 8513 8521 8527 8537 8539 8543 8563 8573 8581 8597 8599 8609 8623 8627 8629 8641 8647 8663 8669 8677 8681 8689 8693 8699 8707 8713 8719 8731 8737 8741 8747 8753 8761 8779 8783 8803 8807 8819 8821 8831 8837 8839 8849 8861 8863 8867 8887 8893 8923 8929 8933 8941 8951 8963 8969 8971 8999 9001 9007 9011 9013 9029 9041 9043 9049 9059 9067 9091 9103 9109 9127 9133 9137 9151 9157 9161 9173 9181 9187 9199 9203 9209 9221 9227 9239 9241 9257 9277 9281 9283 9293 9311 9319 9323 9337 9341 9343 9349 9371 9377 9391 9397 9403 9413 9419 9421 9431 9433 9437 9439 9461 9463 9467 9473 9479 9491 9497 9511 9521 9533 9539 9547 9551 9587 9601 9613 9619 9623 9629 9631 9643 9649 9661 9677 9679 9689 9697 9719 9721 9733 9739 9743 9749 9767 9769 9781 9787 9791 9803 9811 9817 9829 9833 9839 9851 9857 9859 9871 9883 9887 9901 9907 9923 9929 9931 9941 9949 9967 9973
...全文
1157 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
northwolves 2005-11-21
  • 打赏
  • 举报
回复
To 口香糖:

我曾经也为写这类程序而痴迷,随着计算的深入,不得不去看数论方面的书。等书看得差不多的时候就会发现这样的程序并没有太大意义。在10^8范围内你可能觉得计算速度已经够快,但是现在RSA密钥的计算是2^1024数量级。如果在筛法之上没有更大的突破大数分解的意义不是很大。
-------------------------------
赞同你的观点。针对大数,必须用其他手段,如福利液变换,费马定理还有俺们的剩余定理等,太高深了。
大家有兴趣可以看看:

http://primes.utm.edu
http://www.science-chat.org/group-4346-1001.html
daisy8675 2005-11-21
  • 打赏
  • 举报
回复
mark
northwolves 2005-11-21
  • 打赏
  • 举报
回复
用 Long 型数组存放,使用又快又方便,而且楼主给出的数据为 1229个×4字节=4916字节=4.8K
-----------------

我是想存到硬盘上
脆皮大雪糕 2005-11-21
  • 打赏
  • 举报
回复
我曾经也为写这类程序而痴迷,随着计算的深入,不得不去看数论方面的书。等书看得差不多的时候就会发现这样的程序并没有太大意义。在10^8范围内你可能觉得计算速度已经够快,但是现在RSA密钥的计算是2^1024数量级。如果在筛法之上没有更大的突破大数分解的意义不是很大。
vbman2003 2005-11-21
  • 打赏
  • 举报
回复
收藏学习
Tiger_Zhao 2005-11-21
  • 打赏
  • 举报
回复
用 Long 型数组存放,使用又快又方便,而且楼主给出的数据为 1229个×4字节=4916字节=4.8K
123BMW666 2005-11-21
  • 打赏
  • 举报
回复
xuexi
northwolves 2005-11-20
  • 打赏
  • 举报
回复
9
15 25
21 35 49
27 45 63 81
33 55 77 99 121
39 65 91 117 143 169
45 75 105 135 165 195 225
51 85 119 153 187 221 255 289
57 95 133 171 209 247 285 323 361
63 105 147 189 231 273 315 357 399 441
69 115 161 207 253 299 345 391 437 483 529
75 125 175 225 275 325 375 425 475 525 575 625
81 135 189 243 297 351 405 459 513 567 621 675 729
87 145 203 261 319 377 435 493 551 609 667 725 783 841
93 155 217 279 341 403 465 527 589 651 713 775 837 899 961
99 165 231 297 363 429 495 561 627 693 759 825 891 957 1023 1089

今天意外发现的一个有趣的情况,上面的奇数(33*33以内)三角形全是合数,不在上述范围内的奇数全是素数,无一例外.可惜对于素数的筛选并没什么有利条件.

三角是这样生成的:

Sub even(ByVal n As Long)
Dim i As Long, j As Long
For i = 1 To n
For j = 1 To i
Debug.Print (2 * i + 1) * (2 * j + 1);
Next
Debug.Print
Next
End Sub

Private Sub Command1_Click()
even 20
End Sub
KiteGirl 2005-11-20
  • 打赏
  • 举报
回复
最新进展:更新代码。
以tpPrimeFactor类型表示素数及级数,将n个p表示为p^n。减少了记录结果的数据空间。

2147483637=[ 3^3 13^1 6118187^1 ];
2147483638=[ 2^1 2969^1 361651^1 ];
2147483639=[ 7^1 17^1 18046081^1 ];
2147483640=[ 2^3 3^1 5^1 29^1 43^1 113^1 127^1 ];
2147483641=[ 2699^1 795659^1 ];
2147483642=[ 2^1 23^1 46684427^1 ];
2147483643=[ 3^1 715827881^1 ];
2147483644=[ 2^2 233^1 1103^1 2089^1 ];
2147483645=[ 5^1 19^1 22605091^1 ];
2147483646=[ 2^1 3^2 7^1 11^1 31^1 151^1 331^1 ];

增加数据类型tpPrimeFactor

Public Type tpPrimeFactor
pfPrime As Long '素数
pfCount As Byte '级数
End Type

改进后的NumberPrimeFactors函数:

Public Function NumberPrimeFactors(ByVal pNumber As Long) As tpPrimeFactor()
Dim tOutDatas() As tpPrimeFactor
Dim tOutDatas_Length As Long

Dim tAnalyzePrimes() As Long
Dim tAnalyzePrimes_Length As Long
Dim tAnalyzePrimes_Index As Long

Dim tNumber As Long

tNumber = pNumber

tAnalyzePrimes() = NumberAnalyzePrimes(tNumber)
tAnalyzePrimes_Length = UBound(tAnalyzePrimes())

tOutDatas_Length = tAnalyzePrimes_Length

ReDim tOutDatas(tOutDatas_Length)

For tAnalyzePrimes_Index = 0 To tAnalyzePrimes_Length

With tOutDatas(tAnalyzePrimes_Index)
.pfPrime = tAnalyzePrimes(tAnalyzePrimes_Index)
End With

If tNumber = tAnalyzePrimes(tAnalyzePrimes_Index) Then

With tOutDatas(tAnalyzePrimes_Index)

.pfCount = .pfCount + 1

End With

Exit For

End If

Do

If Not CBool(tNumber Mod tAnalyzePrimes(tAnalyzePrimes_Index)) Then

With tOutDatas(tAnalyzePrimes_Index)

.pfCount = .pfCount + 1

End With

tNumber = tNumber \ tAnalyzePrimes(tAnalyzePrimes_Index)

Else

If tNumber > 1 And tAnalyzePrimes_Index = tAnalyzePrimes_Length Then

tOutDatas_Length = tOutDatas_Length + 1

ReDim Preserve tOutDatas(tOutDatas_Length)

With tOutDatas(tOutDatas_Length)

.pfPrime = tNumber
.pfCount = .pfCount + 1

End With

End If

Exit Do

End If

Loop

Next

NumberPrimeFactors = tOutDatas()
End Function
northwolves 2005-11-20
  • 打赏
  • 举报
回复
I have found some code written by C which can list prime numbers from 0 to 10^8 within 1.2 seconds.
Though I have accelerated my codes nearly ten times(
http://blog.csdn.net/northwolves/archive/2005/11/19/533038.aspx),the best way to solve this by VB is to compile it to dll then cite it in VB perhaps. No language can exceed it.
KiteGirl 2005-11-19
  • 打赏
  • 举报
回复
下面这个测试代码更能说明问题:
分解2147483546 - 2147483646的质因数素数成分。
Private Sub Command8_Click()
Dim tLongs() As Long
Dim tIndex As Long
Dim tIndex2 As Long
For tIndex = 2147483546 To 2147483646
Text1.Text = Text1.Text & tIndex & "["
tLongs() = NumberAnalyzePrimes(tIndex)
For tIndex2 = 0 To UBound(tLongs())
Text1.Text = Text1.Text & " " & tLongs(tIndex2)
Next
Text1.Text = Text1.Text & " ];" & vbCrLf
Next
End Sub

结果是:
2147483613[ 3 11 2953 22037 ];
2147483614[ 2 101 ];
2147483615[ 5 31 ];
2147483616[ 2 3 2731 8191 ];
2147483617[ 6733 ];
2147483618[ 2 7 367 ];
2147483619[ 3 23 353 29389 ];
2147483620[ 2 5 4603 23327 ];
2147483621[ 14741 ];
2147483622[ 2 3 17 467 45083 ];
2147483623[ 79 967 28111 ];
2147483624[ 2 11 13 ];
2147483625[ 3 5 7 199 4111 ];
2147483626[ 2 19 37 ];
2147483627[ 47 53 ];
2147483628[ 2 3 ];
2147483629[ 2147483629 ]; '它是一个素数
2147483630[ 2 5 6553 32771 ];
2147483631[ 3 137 263 19867 ];
2147483632[ 2 7 73 ];
2147483633[ 5843 ];
2147483634[ 2 3 12097 29587 ];
2147483635[ 5 11 337 ];
2147483636[ 2 ];
2147483637[ 3 13 ];
2147483638[ 2 2969 ];
2147483639[ 7 17 ];
2147483640[ 2 3 5 29 43 113 127 ];
2147483641[ 2699 ];
2147483642[ 2 23 ];
2147483643[ 3 ];
2147483644[ 2 233 1103 2089 ];
2147483645[ 5 19 ];
2147483646[ 2 3 7 11 31 151 331 ];

在递增的For循环里,算到2147483646至少在long类型里就是到头了,否则要溢出。long的最大极限2147483647本身是个素数。如果你有100000000范围内的素数表,你可以分解10000000000000000以内的质因数。
KiteGirl 2005-11-19
  • 打赏
  • 举报
回复
呵呵!下面这个代码离快速分解质因数只有一步之遥了……

Private Sub Command8_Click()
Dim tLongs() As Long
Dim tIndex As Long
Dim tIndex2 As Long
For tIndex = 0 To 100
Text1.Text = Text1.Text & tIndex & "["
tLongs() = NumberAnalyzePrimes(tIndex)
For tIndex2 = 0 To UBound(tLongs())
Text1.Text = Text1.Text & " " & tLongs(tIndex2)
Next
Text1.Text = Text1.Text & " ];" & vbCrLf
Next
End Sub

NumberAnalyzePrimes函数可以求出long类型范围内任意正整数由哪些素数相乘,但还不是分解质因数。根据它得出的结果分解质因数已经是相当简单的事情了(简单到我都懒得写了)。比如100可以分解成2,5两种素数,但每一种素数的具体数量还需要另外的过程去求一下。

NumberIsPrime函数可以判断long类型范围内任意正整数是否是素数。它的特点是可以直接求99000000-100000000之间的素数,而不需要把99000000之前的算出来。NumberIsPrime函数求素数不如PrimeNumbersGet快,99000000-100000000之间素数表需要13秒时间。但是这个方法不占用大量的内存空间。

NumberAnalyzePrimes函数和NumberIsPrime函数的代价是需要一个26K字节左右内存空间存储65536以内的素数表。在第一次使用这两个函数其中任意一个的时候,以PrimeNumbersGet创建这个基本素数表。之后再使用这些函数,将直接从素数表里读取而不是计算这些基本素数。

这里用到一个规律就是:求n以内的任意一个数是否素数,或是分解质因数,只要Sqr(n)以内的素数表就够了。因此,求2^32以内的任意一个整数是否素数只要2^16以内的素数表就可以了,这就是为什么基本素数表是65536以内素数的原因。


modUltraPrimeNumbers.bas模块

Option Explicit

Private priPrimesTable() As Long '
Private priPrimesTable_Enabled As Boolean '
Private priPrimesTable_Length As Long '

Public Function NumberAnalyzePrimes(ByVal pNumber As Long) As Long()
'
Dim tOutLongs() As Long
Dim tOutLongs_Index As Long

PrimesTableCreate

Dim tPrimesTable_Index As Long
Dim tPrimesTable_Limit As Long

tPrimesTable_Limit = Sqr(pNumber) + 1

Dim tCheck_LoopEnd As Boolean
Dim tCheck_FindPrime As Boolean

For tPrimesTable_Index = 1 To priPrimesTable_Length

tCheck_FindPrime = Not CBool(pNumber Mod priPrimesTable(tPrimesTable_Index))
tCheck_LoopEnd = priPrimesTable(tPrimesTable_Index) > tPrimesTable_Limit

If tCheck_FindPrime Then

ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = priPrimesTable(tPrimesTable_Index)
tOutLongs_Index = tOutLongs_Index + 1

End If
If tCheck_LoopEnd Then Exit For
Next

If Not CBool(tOutLongs_Index) Then
ReDim tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = pNumber
End If

NumberAnalyzePrimes = tOutLongs()
End Function

Public Function NumberIsPrime(ByVal pNumber As Long) As Boolean
Dim tOutBool As Boolean

PrimesTableCreate

Dim tPrimesTable_Index As Long
Dim tPrimesTable_Limit As Long

tPrimesTable_Limit = Sqr(pNumber) + 1

Dim tCheck_LoopEnd As Boolean

For tPrimesTable_Index = 1 To priPrimesTable_Length
tOutBool = CBool(pNumber Mod priPrimesTable(tPrimesTable_Index))
tCheck_LoopEnd = priPrimesTable(tPrimesTable_Index) > tPrimesTable_Limit
tCheck_LoopEnd = tCheck_LoopEnd Or (Not tOutBool)
If tCheck_LoopEnd Then Exit For
Next

NumberIsPrime = tOutBool
End Function

Public Function PrimeNumbersGet(ByVal pLimit As Long) As Long()
Dim tOutLongs() As Long
Dim tOutLongs_Index As Long

Dim tLineDatas() As Boolean
Dim tLineDatas_Index As Long
Dim tLineDatas_Index_Over As Long

ReDim tLineDatas(pLimit)

Dim tStep_Index As Long
Dim tStep_Start As Long

tLineDatas_Index_Over = Sqr(pLimit) + 1

For tLineDatas_Index = 2 To tLineDatas_Index_Over
If Not tLineDatas(tLineDatas_Index) Then
tStep_Start = tLineDatas_Index + tLineDatas_Index
For tStep_Index = tStep_Start To pLimit Step tLineDatas_Index
tLineDatas(tStep_Index) = True
Next
End If
Next

tOutLongs_Index = 2

ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(0) = 1: tOutLongs(1) = 2

For tLineDatas_Index = 3 To pLimit Step 2
If Not tLineDatas(tLineDatas_Index) Then
ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = tLineDatas_Index
tOutLongs_Index = tOutLongs_Index + 1
End If
Next

PrimeNumbersGet = tOutLongs()
End Function

Private Sub PrimesTableCreate()
If Not priPrimesTable_Enabled Then
priPrimesTable() = PrimeNumbersGet(65536)
priPrimesTable_Length = UBound(priPrimesTable())
priPrimesTable_Enabled = True
End If
End Sub
northwolves 2005-11-19
  • 打赏
  • 举报
回复
To jiangsheng(蒋晟.MSMVP2004Jan)

Thanks a lot for your article above.I have read it in about 1997,but I can't search it from GOOGLE now.
I remember that someone have said the following conditions is "n is prime if and only if":

In class one, count the number of combinations of x > 0 and y > 0 that are solutions to 4x^2 + y^2 = n.
In class two, count the number of combinations of x > 0 and y > 0 that are solutions to 3x^2 + y^2 = n.
In class three, count the number of combinations of x > 0, y > 0, and x>y that are solutions to 3x^2 - y^2 = n.
If the count was even, delete the number from the list.

I think that the last class is hard to use for enuming the prime numbers.Any idea?
Summer006 2005-11-19
  • 打赏
  • 举报
回复
感觉这是近期来看到的技术水平含量最高的一个问题讨论贴。

对在此讨论的各位表示景仰~!打搅了。。。。。
KiteGirl 2005-11-19
  • 打赏
  • 举报
回复
测试代码:寻找2147483646以下最大的素数(long类型的最大极限2147483647恰好是一个素数,因此从2147483646开始向下)。

Private Sub Command7_Click()
Dim tPrimes() As Long
Dim tPrimes_Index As Long
Dim tIndex As Long
Dim tTemp As Boolean
tTemp = NumberIsPrime(10)

OnTimer = Timer

For tIndex = 2147483646 To 10 Step -1
If NumberIsPrime(tIndex) Then
Text1.Text = tIndex
Exit For
End If
Next
Text1.Text = Text1.Text & " " & Timer - OnTimer

End Sub


下面是modUltraPrimeNumbers.bas模块
'NumberIsPrime判断long类型范围内任意一个大于3的正整数是否是素数(该函数测量数值与内存容量无关)。
'PrimeNumbersGet获得pLimit范围内的素数表(“枪毙法”,需要占用pLimit*4的内存空间。)。

Option Explicit

Private NumberIsPrime_PBT() As Long
Private NumberIsPrime_PBT_Enabled As Boolean
Private NumberIsPrime_PBT_Length As Long

Public Function NumberIsPrime(ByVal pNumber As Long) As Boolean
Dim tOutBool As Boolean

If Not NumberIsPrime_PBT_Enabled Then
NumberIsPrime_PBT() = PrimeNumbersGet(65536)
NumberIsPrime_PBT_Length = UBound(NumberIsPrime_PBT())
NumberIsPrime_PBT_Enabled = True
End If

Dim tPBT_Index As Long
Dim tPBT_Limit As Long

tPBT_Limit = Sqr(pNumber) + 1

Dim tCheck_LoopEnd As Boolean

For tPBT_Index = 1 To NumberIsPrime_PBT_Length
tOutBool = CBool(pNumber Mod NumberIsPrime_PBT(tPBT_Index))
tCheck_LoopEnd = NumberIsPrime_PBT(tPBT_Index) > tPBT_Limit
tCheck_LoopEnd = tCheck_LoopEnd Or (Not tOutBool)
If tCheck_LoopEnd Then Exit For
Next

NumberIsPrime = tOutBool
End Function

Public Function PrimeNumbersGet(ByVal pLimit As Long) As Long()
Dim tOutLongs() As Long
Dim tOutLongs_Index As Long

Dim tLineDatas() As Boolean
Dim tLineDatas_Index As Long
Dim tLineDatas_Index_Over As Long

ReDim tLineDatas(pLimit)

Dim tStep_Index As Long
Dim tStep_Start As Long

tLineDatas_Index_Over = Sqr(pLimit) + 1

For tLineDatas_Index = 2 To tLineDatas_Index_Over
If Not tLineDatas(tLineDatas_Index) Then
tStep_Start = tLineDatas_Index + tLineDatas_Index
For tStep_Index = tStep_Start To pLimit Step tLineDatas_Index
tLineDatas(tStep_Index) = True
Next
End If
Next

tOutLongs_Index = 2

ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(0) = 1: tOutLongs(1) = 2

For tLineDatas_Index = 3 To pLimit Step 2
If Not tLineDatas(tLineDatas_Index) Then
ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = tLineDatas_Index
tOutLongs_Index = tOutLongs_Index + 1
End If
Next

PrimeNumbersGet = tOutLongs()
End Function

蒋晟 2005-11-19
  • 打赏
  • 举报
回复
you should download the source code in C and take a look.
KiteGirl 2005-11-19
  • 打赏
  • 举报
回复
快速分解质因数函数的最终结果:

测试代码:

Private Sub Command9_Click()
Dim tLongs() As Long
Dim tIndex As Long
Dim tIndex2 As Long
Dim tString As String
For tIndex = 2147483546 To 2147483646
'For tIndex = 2 To 100
tString = tString & tIndex & "["
tLongs() = NumberPrimeFactors(tIndex)
For tIndex2 = 0 To UBound(tLongs())
tString = tString & " " & tLongs(tIndex2)
Next
tString = tString & " ];" & vbCrLf
Next
Text1.Text = tString
End Sub

计算结果:

[上略]
2147483636[ 2 2 536870909 ];
2147483637[ 3 3 3 13 6118187 ];
2147483638[ 2 2969 361651 ];
2147483639[ 7 17 18046081 ];
2147483640[ 2 2 2 3 5 29 43 113 127 ];
2147483641[ 2699 795659 ];
2147483642[ 2 23 46684427 ];
2147483643[ 3 715827881 ];
2147483644[ 2 2 233 1103 2089 ];
2147483645[ 5 19 22605091 ];
2147483646[ 2 3 3 7 11 31 151 331 ];

modUltraPrimeNumbers.bas模块内容

Option Explicit

Private priPrimesTable() As Long '
Private priPrimesTable_Enabled As Boolean '
Private priPrimesTable_Length As Long '

Public Function NumberPrimeFactors(ByVal pNumber As Long) As Long()
Dim tOutLongs() As Long
Dim tOutLongs_Length As Long

Dim tAnalyzePrimes() As Long
Dim tAnalyzePrimes_Length As Long
Dim tAnalyzePrimes_Index As Long

Dim tNumber As Long

tNumber = pNumber

tAnalyzePrimes() = NumberAnalyzePrimes(tNumber)
tAnalyzePrimes_Length = UBound(tAnalyzePrimes())

For tAnalyzePrimes_Index = 0 To tAnalyzePrimes_Length
If tNumber = tAnalyzePrimes(tAnalyzePrimes_Index) Then
ReDim Preserve tOutLongs(tOutLongs_Length)
tOutLongs(tOutLongs_Length) = tAnalyzePrimes(tAnalyzePrimes_Index)
tOutLongs_Length = tOutLongs_Length + 1
Exit For
End If
Do
If Not CBool(tNumber Mod tAnalyzePrimes(tAnalyzePrimes_Index)) Then
ReDim Preserve tOutLongs(tOutLongs_Length)
tOutLongs(tOutLongs_Length) = tAnalyzePrimes(tAnalyzePrimes_Index)
tNumber = tNumber \ tAnalyzePrimes(tAnalyzePrimes_Index)
tOutLongs_Length = tOutLongs_Length + 1
Else
If tNumber > 1 And tAnalyzePrimes_Index = tAnalyzePrimes_Length Then
ReDim Preserve tOutLongs(tOutLongs_Length)
tOutLongs(tOutLongs_Length) = tNumber
End If
Exit Do
End If
Loop
Next
NumberPrimeFactors = tOutLongs()
End Function

Public Function NumberAnalyzePrimes(ByVal pNumber As Long) As Long()

Dim tOutLongs() As Long
Dim tOutLongs_Index As Long

PrimesTableCreate

Dim tPrimesTable_Index As Long
Dim tPrimesTable_Limit As Long

tPrimesTable_Limit = Sqr(pNumber) + 1

Dim tCheck_LoopEnd As Boolean
Dim tCheck_FindPrime As Boolean

For tPrimesTable_Index = 1 To priPrimesTable_Length

tCheck_FindPrime = Not CBool(pNumber Mod priPrimesTable(tPrimesTable_Index))
tCheck_LoopEnd = priPrimesTable(tPrimesTable_Index) > tPrimesTable_Limit

If tCheck_FindPrime Then

ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = priPrimesTable(tPrimesTable_Index)
tOutLongs_Index = tOutLongs_Index + 1

End If

If tCheck_LoopEnd Then Exit For
Next

If Not CBool(tOutLongs_Index) Then
ReDim tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = pNumber
End If

NumberAnalyzePrimes = tOutLongs()
End Function

Public Function NumberIsPrime(ByVal pNumber As Long) As Boolean
Dim tOutBool As Boolean

PrimesTableCreate

Dim tPrimesTable_Index As Long
Dim tPrimesTable_Limit As Long

tPrimesTable_Limit = Sqr(pNumber) + 1

Dim tCheck_LoopEnd As Boolean

For tPrimesTable_Index = 1 To priPrimesTable_Length
tOutBool = CBool(pNumber Mod priPrimesTable(tPrimesTable_Index))
tCheck_LoopEnd = priPrimesTable(tPrimesTable_Index) > tPrimesTable_Limit
tCheck_LoopEnd = tCheck_LoopEnd Or (Not tOutBool)
If tCheck_LoopEnd Then Exit For
Next

NumberIsPrime = tOutBool
End Function

Public Function PrimeNumbersGet(ByVal pLimit As Long) As Long()
Dim tOutLongs() As Long
Dim tOutLongs_Index As Long

Dim tLineDatas() As Boolean
Dim tLineDatas_Index As Long
Dim tLineDatas_Index_Over As Long

ReDim tLineDatas(pLimit)

Dim tStep_Index As Long
Dim tStep_Start As Long

tLineDatas_Index_Over = Sqr(pLimit) + 1

For tLineDatas_Index = 2 To tLineDatas_Index_Over
If Not tLineDatas(tLineDatas_Index) Then
tStep_Start = tLineDatas_Index + tLineDatas_Index
For tStep_Index = tStep_Start To pLimit Step tLineDatas_Index
tLineDatas(tStep_Index) = True
Next
End If
Next

tOutLongs_Index = 2

ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(0) = 1: tOutLongs(1) = 2

For tLineDatas_Index = 3 To pLimit Step 2
If Not tLineDatas(tLineDatas_Index) Then
ReDim Preserve tOutLongs(tOutLongs_Index)
tOutLongs(tOutLongs_Index) = tLineDatas_Index
tOutLongs_Index = tOutLongs_Index + 1
End If
Next

PrimeNumbersGet = tOutLongs()
End Function

Private Sub PrimesTableCreate()
If Not priPrimesTable_Enabled Then
priPrimesTable() = PrimeNumbersGet(65536)
priPrimesTable_Length = UBound(priPrimesTable())
priPrimesTable_Enabled = True
End If
End Sub
northwolves 2005-11-18
  • 打赏
  • 举报
回复
非常感谢 KiteGirl(小仙妹) 和 jiangsheng(蒋晟.MSMVP2004Jan) 给予的启发,特此将改进后的代码与大家共享。
http://blog.csdn.net/northwolves/archive/2005/11/18/532695.aspx

代码执行结果(编译前):

n=100,prime count=25, The calulating time is 0.0000 seconds.
n=1000,prime count=168, The calulating time is 0.0000 seconds.
n=10000,prime count=1229, The calulating time is 0.0000 seconds.
n=100000,prime count=9592, The calulating time is 0.0002 seconds.
n=1000000,prime count=78498, The calulating time is 0.2269 seconds.
n=10000000,prime count=664579, The calulating time is 2.0719 seconds.
n=100000000,prime count=5761455, The calulating time is 15.2344 seconds.
wangtopcool 2005-11-18
  • 打赏
  • 举报
回复
学习...
KiteGirl 2005-11-18
  • 打赏
  • 举报
回复
另外呢,想知道某个数是不是素数和想求某个范围内的素数是不同的。
想判断一个数N是不是素数,只要将N与SQR(N)以内的素数依次取余就可以了。
根据这个道理,求2147483647(long类型的极限)以内的的任何一个数字是不是素数,只要有46341以内的素数表就够了。46341以内的素数有4792个。
加载更多回复(21)

7,759

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧