- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要尽可能快地生成所有 permutations整数 0
, 1
, 2
, ...
, n - 1
结果为 NumPy形状数组 (factorial(n), n)
,或遍历此类数组的大部分以节省内存。
NumPy 中是否有一些内置函数可以执行此操作?或者一些功能的组合。
使用 itertools.permutations(...)
太慢了,我需要一个更快的方法。
最佳答案
由于我没有找到一个好的/足够快的解决方案,我决定使用 Numba JIT/AOT 代码编译器/优化器从头开始实现整个排列算法。
对于足够大的 25x-50x
,我的下一个基于 numba 的解决方案比使用 n
执行相同的任务快 itertools.permutations(...)
倍。查看代码后的时间。
如果一次迭代 1 个排列,我的代码仅比 1.25x
快 itertools.permutations(...)
,但根据最初的问题,我需要所有排列的整个数组或至少迭代大块。
我已经实现了在 numba 模式下使用 numba 和 no-numba 模式以及 JIT 和 AOT 变体的可能性。此外,还可以选择是一次迭代一个排列( iter_ = True, iter_batches = False
)还是一次批量排列( iter_ = True, iter_batches = True
)或返回所有排列的整个数组而无需迭代( iter_ = False
)。也可以调整批量大小,例如由 batch_size = 1000
。
中央内部函数是 next_batch(...)
,它实际上实现了在给定前一个排列的情况下生成下一个排列的整个算法。它是 numba 函数中唯一的 JITed/AOTed,其余是辅助纯 Python 包装器。
我的计时不是很精确,因为我的笔记本电脑的 CPU 在过热时会在随机时间点 2.2x
次减速(这种情况经常发生)。
Try it online!
# Needs: python -m pip install numba numpy timerit
def permutations(
n, *, iter_ = True, numba_ = True, numba_aot = False,
batch_size = 1000, iter_batches = False, state = {},
):
key = (bool(numba_), bool(numba_aot))
if key in state:
return state[key](int(n), bool(iter_), int(batch_size), bool(iter_batches))
def prepare(numba_, numba_aot):
import numpy as np
def next_batch(a, r):
c, n = r.shape[0], r.shape[1]
for ic in range(c):
r[ic] = a
a = r[ic]
for i in range(n - 2, -1, -1):
if a[i] < a[i + 1]:
break
else:
assert False # Already last permutation
for j in range(n - 1, i, -1):
if a[i] < a[j]:
break
a[i], a[j] = a[j], a[i]
for k in range(1, (n - i + 1) >> 1):
a[i + k], a[n - k] = a[n - k], a[i + k]
def factorial(n):
res = 1
for i in range(2, n + 1):
res *= i
return res
def permutations_iter(nxb, n, batch_size, iter_batches):
a = np.arange(n, dtype = np.uint8)
if iter_batches:
yield a[None, :]
else:
yield a
if n <= 1:
return
total = factorial(n)
for i in range(1, total, batch_size):
batch = np.empty((min(batch_size, total - i), n), dtype = np.uint8)
nxb(a, batch)
if iter_batches:
yield batch
else:
yield from iter(batch)
a = batch[-1]
def permutations_arr(nxb, n, batch_size):
total = factorial(n)
res = np.empty((total, n), dtype = np.uint8)
res[0] = np.arange(n, dtype = np.uint8)
for i in range(1, total, batch_size):
nxb(res[i - 1], res[i : i + min(batch_size, total - i)])
return res
if not numba_:
return lambda n, it, bs, ib: permutations_iter(next_batch, n, bs, ib) if it else permutations_arr(next_batch, n, bs)
else:
if not numba_aot:
import numba
nxb = numba.njit('void(u1[:], u1[:, :])', cache = True)(next_batch)
else:
import numba, numba.pycc
cc = numba.pycc.CC('permutations_numba')
cc.export('next_batch', 'void(u1[:], u1[:, :])')(next_batch)
cc.compile()
from permutations_numba import next_batch as nxb
return lambda n, it, bs, ib: permutations_iter(nxb, n, bs, ib) if it else permutations_arr(nxb, n, bs)
state[key] = prepare(numba_, numba_aot)
return state[key](int(n), bool(iter_), int(batch_size), bool(iter_batches))
def test():
import numpy as np, itertools
from timerit import Timerit
Timerit._default_asciimode = True
# Heat-up / pre-compile
permutations(2, numba_ = False)
permutations(2, numba_ = True)
for n in range(12):
num = 99 if n <= 7 else 15 if n <= 8 else 3 if n <= 9 else 1
print('-' * 60 + f'\nn = {str(n).rjust(2)}')
print(f'itertools : ', end = '', flush = True)
for t in Timerit(num = num, verbose = 1):
with t:
ref = np.array(list(itertools.permutations(range(n))), dtype = np.uint8)
if n <= 9:
print(f'python_array : ', end = '', flush = True)
for t in Timerit(num = num, verbose = 1):
with t:
curpa = permutations(n, iter_ = False, numba_ = False)
assert np.array_equal(ref, curpa)
for batch_size in [10, 100, 1000, 10000]:
print(f'batch_size = {str(batch_size).rjust(5)}')
print(f'numba_iter : ', end = '', flush = True)
for t in Timerit(num = num, verbose = 1):
with t:
curi = np.array(list(permutations(n, iter_ = True, numba_ = True, batch_size = batch_size)))
assert np.array_equal(ref, curi)
print(f'numba_iter_batches : ', end = '', flush = True)
for t in Timerit(num = num, verbose = 1):
with t:
curib = np.concatenate(list(permutations(n, iter_ = True, numba_ = True, batch_size = batch_size, iter_batches = True)))
assert np.array_equal(ref, curib)
print(f'numba_array : ', end = '', flush = True)
for t in Timerit(num = num, verbose = 1):
with t:
cura = permutations(n, iter_ = False, numba_ = True, batch_size = batch_size)
assert np.array_equal(ref, cura)
if __name__ == '__main__':
test()
输出(时间):
------------------------------------------------------------
n = 0
itertools : Timed best=8.210 us, mean=8.335 +- 0.4 us
python_array : Timed best=14.881 us, mean=15.457 +- 0.5 us
batch_size = 10
numba_iter : Timed best=15.908 us, mean=16.126 +- 0.3 us
numba_iter_batches : Timed best=17.447 us, mean=17.929 +- 0.3 us
numba_array : Timed best=15.394 us, mean=15.519 +- 0.3 us
batch_size = 100
numba_iter : Timed best=15.908 us, mean=16.250 +- 0.3 us
numba_iter_batches : Timed best=17.447 us, mean=18.038 +- 0.2 us
numba_array : Timed best=15.394 us, mean=15.519 +- 0.3 us
batch_size = 1000
numba_iter : Timed best=15.908 us, mean=16.328 +- 0.3 us
numba_iter_batches : Timed best=17.960 us, mean=18.069 +- 0.2 us
numba_array : Timed best=15.394 us, mean=15.441 +- 0.1 us
batch_size = 10000
numba_iter : Timed best=15.908 us, mean=16.328 +- 0.2 us
numba_iter_batches : Timed best=17.448 us, mean=17.976 +- 0.2 us
numba_array : Timed best=14.881 us, mean=15.410 +- 0.3 us
------------------------------------------------------------
n = 1
itertools : Timed best=7.697 us, mean=7.790 +- 0.3 us
python_array : Timed best=14.882 us, mean=15.488 +- 0.3 us
batch_size = 10
numba_iter : Timed best=15.908 us, mean=16.064 +- 0.3 us
numba_iter_batches : Timed best=17.960 us, mean=18.318 +- 0.3 us
numba_array : Timed best=14.881 us, mean=15.348 +- 0.3 us
batch_size = 100
numba_iter : Timed best=15.908 us, mean=16.203 +- 0.3 us
numba_iter_batches : Timed best=17.960 us, mean=18.054 +- 0.2 us
numba_array : Timed best=15.394 us, mean=15.472 +- 0.2 us
batch_size = 1000
numba_iter : Timed best=15.908 us, mean=16.421 +- 0.1 us
numba_iter_batches : Timed best=17.960 us, mean=18.147 +- 0.3 us
numba_array : Timed best=14.882 us, mean=15.379 +- 0.2 us
batch_size = 10000
numba_iter : Timed best=15.908 us, mean=16.095 +- 0.2 us
numba_iter_batches : Timed best=17.960 us, mean=18.132 +- 0.3 us
numba_array : Timed best=14.881 us, mean=15.395 +- 0.3 us
------------------------------------------------------------
n = 2
itertools : Timed best=8.723 us, mean=8.786 +- 0.2 us
python_array : Timed best=29.250 us, mean=29.670 +- 0.4 us
batch_size = 10
numba_iter : Timed best=34.381 us, mean=35.035 +- 0.7 us
numba_iter_batches : Timed best=30.276 us, mean=30.790 +- 0.4 us
numba_array : Timed best=22.579 us, mean=22.672 +- 0.2 us
batch_size = 100
numba_iter : Timed best=34.381 us, mean=34.584 +- 0.3 us
numba_iter_batches : Timed best=30.277 us, mean=30.836 +- 0.2 us
numba_array : Timed best=22.066 us, mean=22.595 +- 0.2 us
batch_size = 1000
numba_iter : Timed best=34.381 us, mean=34.739 +- 0.4 us
numba_iter_batches : Timed best=30.277 us, mean=30.851 +- 0.3 us
numba_array : Timed best=22.579 us, mean=22.626 +- 0.1 us
batch_size = 10000
numba_iter : Timed best=34.381 us, mean=34.786 +- 0.4 us
numba_iter_batches : Timed best=30.276 us, mean=30.650 +- 0.3 us
numba_array : Timed best=22.066 us, mean=22.641 +- 0.3 us
------------------------------------------------------------
n = 3
itertools : Timed best=12.829 us, mean=13.093 +- 0.3 us
python_array : Timed best=62.606 us, mean=63.461 +- 0.6 us
batch_size = 10
numba_iter : Timed best=39.513 us, mean=40.120 +- 0.4 us
numba_iter_batches : Timed best=31.302 us, mean=31.661 +- 0.2 us
numba_array : Timed best=22.579 us, mean=23.077 +- 0.3 us
batch_size = 100
numba_iter : Timed best=39.513 us, mean=40.042 +- 0.2 us
numba_iter_batches : Timed best=31.302 us, mean=31.629 +- 0.3 us
numba_array : Timed best=22.579 us, mean=23.154 +- 0.2 us
batch_size = 1000
numba_iter : Timed best=39.513 us, mean=39.840 +- 0.4 us
numba_iter_batches : Timed best=31.302 us, mean=31.629 +- 0.4 us
numba_array : Timed best=22.579 us, mean=23.170 +- 0.2 us
batch_size = 10000
numba_iter : Timed best=39.513 us, mean=40.120 +- 0.5 us
numba_iter_batches : Timed best=30.789 us, mean=31.412 +- 0.3 us
numba_array : Timed best=23.092 us, mean=23.232 +- 0.3 us
------------------------------------------------------------
n = 4
itertools : Timed best=34.381 us, mean=34.911 +- 0.4 us
python_array : Timed best=207.830 us, mean=209.152 +- 1.0 us
batch_size = 10
numba_iter : Timed best=82.619 us, mean=83.054 +- 0.7 us
numba_iter_batches : Timed best=44.645 us, mean=44.754 +- 0.2 us
numba_array : Timed best=31.302 us, mean=31.458 +- 0.2 us
batch_size = 100
numba_iter : Timed best=63.632 us, mean=64.036 +- 0.4 us
numba_iter_batches : Timed best=32.329 us, mean=32.889 +- 0.2 us
numba_array : Timed best=24.118 us, mean=24.600 +- 0.3 us
batch_size = 1000
numba_iter : Timed best=63.632 us, mean=64.083 +- 0.5 us
numba_iter_batches : Timed best=32.329 us, mean=32.904 +- 0.3 us
numba_array : Timed best=24.118 us, mean=24.569 +- 0.3 us
batch_size = 10000
numba_iter : Timed best=63.119 us, mean=63.927 +- 0.4 us
numba_iter_batches : Timed best=32.329 us, mean=32.889 +- 0.5 us
numba_array : Timed best=24.118 us, mean=24.461 +- 0.3 us
------------------------------------------------------------
n = 5
itertools : Timed best=156.001 us, mean=166.311 +- 20.5 us
python_array : Timed best=0.999 ms, mean=1.002 +- 0.0 ms
batch_size = 10
numba_iter : Timed best=293.528 us, mean=294.461 +- 0.8 us
numba_iter_batches : Timed best=102.632 us, mean=103.254 +- 0.4 us
numba_array : Timed best=64.145 us, mean=64.985 +- 0.5 us
batch_size = 100
numba_iter : Timed best=198.080 us, mean=199.107 +- 0.8 us
numba_iter_batches : Timed best=44.132 us, mean=44.894 +- 0.4 us
numba_array : Timed best=33.355 us, mean=33.884 +- 0.3 us
batch_size = 1000
numba_iter : Timed best=186.791 us, mean=187.522 +- 0.4 us
numba_iter_batches : Timed best=37.973 us, mean=38.471 +- 0.3 us
numba_array : Timed best=29.763 us, mean=30.183 +- 0.3 us
batch_size = 10000
numba_iter : Timed best=186.790 us, mean=187.646 +- 0.7 us
numba_iter_batches : Timed best=37.974 us, mean=38.534 +- 0.3 us
numba_array : Timed best=29.763 us, mean=30.245 +- 0.3 us
------------------------------------------------------------
n = 6
itertools : Timed best=0.991 ms, mean=1.007 +- 0.0 ms
python_array : Timed best=5.873 ms, mean=6.012 +- 0.0 ms
batch_size = 10
numba_iter : Timed best=1.668 ms, mean=1.673 +- 0.0 ms
numba_iter_batches : Timed best=503.411 us, mean=506.506 +- 1.2 us
numba_array : Timed best=293.015 us, mean=296.047 +- 1.2 us
batch_size = 100
numba_iter : Timed best=1.036 ms, mean=1.145 +- 0.3 ms
numba_iter_batches : Timed best=120.593 us, mean=132.878 +- 23.0 us
numba_array : Timed best=93.908 us, mean=97.438 +- 2.4 us
batch_size = 1000
numba_iter : Timed best=962.178 us, mean=976.624 +- 23.9 us
numba_iter_batches : Timed best=78.001 us, mean=82.992 +- 7.7 us
numba_array : Timed best=68.250 us, mean=69.852 +- 4.3 us
batch_size = 10000
numba_iter : Timed best=963.717 us, mean=977.044 +- 27.3 us
numba_iter_batches : Timed best=77.487 us, mean=80.084 +- 7.5 us
numba_array : Timed best=68.250 us, mean=69.634 +- 4.4 us
------------------------------------------------------------
n = 7
itertools : Timed best=8.502 ms, mean=8.579 +- 0.0 ms
python_array : Timed best=41.690 ms, mean=42.358 +- 0.8 ms
batch_size = 10
numba_iter : Timed best=11.523 ms, mean=11.646 +- 0.2 ms
numba_iter_batches : Timed best=3.407 ms, mean=3.497 +- 0.1 ms
numba_array : Timed best=1.944 ms, mean=1.975 +- 0.0 ms
batch_size = 100
numba_iter : Timed best=7.050 ms, mean=7.397 +- 0.3 ms
numba_iter_batches : Timed best=659.925 us, mean=668.198 +- 5.9 us
numba_array : Timed best=503.411 us, mean=506.086 +- 3.3 us
batch_size = 1000
numba_iter : Timed best=6.576 ms, mean=6.630 +- 0.0 ms
numba_iter_batches : Timed best=382.305 us, mean=389.707 +- 4.4 us
numba_array : Timed best=354.081 us, mean=360.364 +- 4.3 us
batch_size = 10000
numba_iter : Timed best=6.463 ms, mean=6.504 +- 0.0 ms
numba_iter_batches : Timed best=349.976 us, mean=352.091 +- 1.5 us
numba_array : Timed best=330.989 us, mean=337.194 +- 1.8 us
------------------------------------------------------------
n = 8
itertools : Timed best=71.003 ms, mean=71.824 +- 0.5 ms
python_array : Timed best=331.176 ms, mean=339.746 +- 7.3 ms
batch_size = 10
numba_iter : Timed best=99.929 ms, mean=101.098 +- 1.3 ms
numba_iter_batches : Timed best=27.489 ms, mean=27.905 +- 0.3 ms
numba_array : Timed best=15.370 ms, mean=15.560 +- 0.1 ms
batch_size = 100
numba_iter : Timed best=62.168 ms, mean=62.765 +- 0.7 ms
numba_iter_batches : Timed best=5.083 ms, mean=5.119 +- 0.0 ms
numba_array : Timed best=3.824 ms, mean=3.842 +- 0.0 ms
batch_size = 1000
numba_iter : Timed best=57.706 ms, mean=57.935 +- 0.2 ms
numba_iter_batches : Timed best=2.824 ms, mean=2.832 +- 0.0 ms
numba_array : Timed best=2.656 ms, mean=2.670 +- 0.0 ms
batch_size = 10000
numba_iter : Timed best=57.457 ms, mean=60.128 +- 2.1 ms
numba_iter_batches : Timed best=2.615 ms, mean=2.635 +- 0.0 ms
numba_array : Timed best=2.550 ms, mean=2.565 +- 0.0 ms
------------------------------------------------------------
n = 9
itertools : Timed best=724.017 ms, mean=724.017 +- 0.0 ms
python_array : Timed best=3.071 s, mean=3.071 +- 0.0 s
batch_size = 10
numba_iter : Timed best=950.892 ms, mean=950.892 +- 0.0 ms
numba_iter_batches : Timed best=261.376 ms, mean=261.376 +- 0.0 ms
numba_array : Timed best=145.207 ms, mean=145.207 +- 0.0 ms
batch_size = 100
numba_iter : Timed best=584.761 ms, mean=584.761 +- 0.0 ms
numba_iter_batches : Timed best=50.632 ms, mean=50.632 +- 0.0 ms
numba_array : Timed best=39.945 ms, mean=39.945 +- 0.0 ms
batch_size = 1000
numba_iter : Timed best=535.190 ms, mean=535.190 +- 0.0 ms
numba_iter_batches : Timed best=29.557 ms, mean=29.557 +- 0.0 ms
numba_array : Timed best=26.541 ms, mean=26.541 +- 0.0 ms
batch_size = 10000
numba_iter : Timed best=533.592 ms, mean=533.592 +- 0.0 ms
numba_iter_batches : Timed best=27.507 ms, mean=27.507 +- 0.0 ms
numba_array : Timed best=25.115 ms, mean=25.115 +- 0.0 ms
------------------------------------------------------------
n = 10
itertools : Timed best=15.483 s, mean=15.483 +- 0.0 s
batch_size = 10
numba_iter : Timed best=24.163 s, mean=24.163 +- 0.0 s
numba_iter_batches : Timed best=6.039 s, mean=6.039 +- 0.0 s
numba_array : Timed best=3.246 s, mean=3.246 +- 0.0 s
batch_size = 100
numba_iter : Timed best=13.891 s, mean=13.891 +- 0.0 s
numba_iter_batches : Timed best=1.136 s, mean=1.136 +- 0.0 s
numba_array : Timed best=890.228 ms, mean=890.228 +- 0.0 ms
batch_size = 1000
numba_iter : Timed best=12.768 s, mean=12.768 +- 0.0 s
numba_iter_batches : Timed best=693.685 ms, mean=693.685 +- 0.0 ms
numba_array : Timed best=658.007 ms, mean=658.007 +- 0.0 ms
batch_size = 10000
numba_iter : Timed best=11.175 s, mean=11.175 +- 0.0 s
numba_iter_batches : Timed best=278.304 ms, mean=278.304 +- 0.0 ms
numba_array : Timed best=251.208 ms, mean=251.208 +- 0.0 ms
------------------------------------------------------------
n = 11
itertools : Timed best=95.118 s, mean=95.118 +- 0.0 s
batch_size = 10
numba_iter : Timed best=124.414 s, mean=124.414 +- 0.0 s
numba_iter_batches : Timed best=75.427 s, mean=75.427 +- 0.0 s
numba_array : Timed best=28.079 s, mean=28.079 +- 0.0 s
batch_size = 100
numba_iter : Timed best=70.749 s, mean=70.749 +- 0.0 s
numba_iter_batches : Timed best=6.084 s, mean=6.084 +- 0.0 s
numba_array : Timed best=4.357 s, mean=4.357 +- 0.0 s
batch_size = 1000
numba_iter : Timed best=67.576 s, mean=67.576 +- 0.0 s
numba_iter_batches : Timed best=8.572 s, mean=8.572 +- 0.0 s
numba_array : Timed best=6.915 s, mean=6.915 +- 0.0 s
batch_size = 10000
numba_iter : Timed best=123.208 s, mean=123.208 +- 0.0 s
numba_iter_batches : Timed best=3.348 s, mean=3.348 +- 0.0 s
numba_array : Timed best=2.789 s, mean=2.789 +- 0.0 s
关于python - 有效地生成所有排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64291076/
我正在尝试使用以下 keytool 命令为我的应用程序生成 keystore : keytool -genkey -alias tomcat -keystore tomcat.keystore -ke
编辑:在西里尔正确解决问题后,我注意到只需将生成轴的函数放在用于生成标签的函数下面就可以解决问题。 我几乎读完了 O'Reilly 书中关于 D3.js 的教程,并在倒数第二页上制作了散点图,但是当添
虽然使用 GraphiQL 效果很好,但我的老板要求我实现一个用户界面,用户可以在其中通过 UI 元素(例如复选框、映射关系)检查呈现给他们的元素并获取数据,这样做将为该人生成 graphql 输入,
我尝试在 Netbean 6.8 中使用 ws-import 生成 Java 类。我想重新生成 jax-ws,因为在 ebay.api.paypalapi 包中发现了一个错误(我认为该错误是由于 Pa
我有一个 perl 脚本,它获取系统日期并将该日期写入文件名。 系统日期被分配给 TRH1 变量,然后它被设置为一个文件名。 $TRH1 =`date + %Y%m%d%H%M`; print "TR
我是 Haskell 的新手,需要帮助。我正在尝试构建一种必须具有某种唯一性的新数据类型,因此我决定使用 UUID 作为唯一标识符: data MyType = MyType { uuid ::
我制作了一个脚本,它可以根据 Mysql 数据库中的一些表生成 XML。 该脚本在 PHP 中运行。 public function getRawMaterials($apiKey, $format
所以这是我的项目中的一个问题。 In this task, we will use OpenSSL to generate digital signatures. Please prepare a f
我在 SAS LIFEREG 中有一个加速故障时间模型,我想绘制它。因为 SAS 在绘图方面非常糟糕,我想实际重新生成 R 中曲线的数据并将它们绘制在那里。 SAS 提出了一个尺度(在指数分布固定为
我正在为 Django 后端制作一个样板,并且我需要能够使它到达下一个下载它的人显然无法访问我的 secret key 的地方,或者拥有不同的 key 。我一直在研究一些选项,并在这个过程中进行了实验
我正在创建一个生成采购订单的应用程序。我可以根据用户输入的详细信息创建文本文件。我想生成一个看起来比普通文本文件好得多的 Excel。有没有可以在我的应用程序中使用的开源库? 最佳答案 目前还没有任何
我正在尝试使用 ScalaCheck 为 BST 创建一个 Gen,但是当我调用 .sample 方法时,它给了我 java.lang.NullPointerException。我哪里错了? seal
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我尝试编写一些代码,例如(在verilog中): parameter N = 128; if (encoder_in[0] == 1) begin 23 binary_out = 1;
我正忙于在 Grails 项目中进行从 MySQL 到 Postgres 的相当复杂的数据迁移。 我正在使用 GORM 在 PostGres 中生成模式,然后执行 MySQL -> mysqldump
如何使用纯 XSLT 生成 UUID?基本上是寻找一种使用 XSLT 创建独特序列的方法。该序列可以是任意长度。 我正在使用 XSLT 2.0。 最佳答案 这是一个good example 。基本上,
我尝试安装.app文件,但是当我安装并单击“同步”(在iTunes中)时,我开始在设备上开始安装,然后停止,这是一个问题,我不知道在哪里,但我看到了我无法解决的奇怪的事情: 最佳答案 似乎您没有在Xc
自从我生成 JavaDocs 以来已经有一段时间了,我确信这些选项在过去 10 年左右的时间里已经得到了改进。 我能否得到一些有关生成器的建议,该生成器将输出类似于 .Net 文档结构的 JavaDo
我想学习如何生成 PDF,我不想使用任何第三方工具,我想自己用代码创建它。到目前为止,我所看到的唯一示例是我通过在第 3 方 dll 上打开反射器查看的代码,以查看发生了什么。不幸的是,到目前为止我看
我正在从 Epplus 库生成 excel 条形图。 这是我成功生成的。 我的 table 是这样的 Mumbai Delhi Financial D
我是一名优秀的程序员,十分优秀!