- 在解析函数声明时调整了返回类型检查逻辑,先验证类型存在性再进行类型转换 - 新增对mixed类型的参数类型解析,映射到TYPE_VAR类型 - 添加对resource类型的错误处理机制 - 将原parseCallArgs方法替换为专门的parseNativeCallArgs方法用于本地函数调用 - 在C++主程序中添加php::request_init()初始化调用 - 新增埃拉托斯特尼筛法求素数示例程序及对应的vector扩展实现 - 添加vector.stub.php存根文件定义vector相关函数接口pull/1/head
parent
6878ecc517
commit
1fc07ee729
6 changed files with 161 additions and 3 deletions
@ -0,0 +1,51 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
|
||||||
|
// 埃拉托斯特尼筛法求素数 |
||||||
|
function sieveOfEratosthenes(int $limit) |
||||||
|
{ |
||||||
|
if ($limit < 2) return []; |
||||||
|
|
||||||
|
// 初始化布尔数组,索引代表数字,值代表是否为素数 |
||||||
|
$isPrime = array_fill(0, $limit + 1, true); |
||||||
|
$isPrime[0] = false; |
||||||
|
$isPrime[1] = false; // 0 和 1 不是素数 |
||||||
|
|
||||||
|
for ($i = 2; $i * $i <= $limit; $i++) { |
||||||
|
if ($isPrime[$i]) { |
||||||
|
// 标记 i 的所有倍数为非素数 |
||||||
|
for ($j = $i * $i; $j <= $limit; $j += $i) { |
||||||
|
$isPrime[$j] = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 收集所有素数 |
||||||
|
$primes = []; |
||||||
|
for ($num = 2; $num <= $limit; $num++) { |
||||||
|
if ($isPrime[$num]) { |
||||||
|
$primes[] = $num; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $primes; |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
global $argv; |
||||||
|
$n = isset($argv[2]) ? (int)$argv[2] : 10000000; |
||||||
|
$begin = microtime(true); |
||||||
|
// 参数校验 |
||||||
|
if ($n < 2) { |
||||||
|
fwrite(STDERR, "请输入一个大于等于2的整数作为上限。\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
$primes = sieveOfEratosthenes($n); |
||||||
|
var_dump(count($primes)); |
||||||
|
var_dump(microtime(true) - $begin); |
||||||
|
// 输出每个素数(每行一个) |
||||||
|
// foreach ($primes as $prime) { |
||||||
|
// echo $prime . "\n"; |
||||||
|
// } |
||||||
|
} |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
|
||||||
|
// 埃拉托斯特尼筛法求素数 |
||||||
|
function sieveOfEratosthenes(int $limit) |
||||||
|
{ |
||||||
|
if ($limit < 2) return []; |
||||||
|
|
||||||
|
// 初始化布尔数组,索引代表数字,值代表是否为素数 |
||||||
|
$isPrime = vector_new($limit + 1, true); |
||||||
|
|
||||||
|
// 0 和 1 不是素数 |
||||||
|
vector_set($isPrime, 0, false); |
||||||
|
vector_set($isPrime, 1, false); |
||||||
|
|
||||||
|
for ($i = 2; $i * $i <= $limit; $i++) { |
||||||
|
if (vector_get($isPrime, $i)) { |
||||||
|
// 标记 i 的所有倍数为非素数 |
||||||
|
for ($j = $i * $i; $j <= $limit; $j += $i) { |
||||||
|
vector_set($isPrime, $j, false); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 收集所有素数 |
||||||
|
$primes = []; |
||||||
|
for ($num = 2; $num <= $limit; $num++) { |
||||||
|
if (vector_get($isPrime, $num)) { |
||||||
|
$primes[] = $num; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $primes; |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
global $argv; |
||||||
|
$n = isset($argv[2]) ? (int)$argv[2] : 100000; |
||||||
|
$begin = microtime(true); |
||||||
|
// 参数校验 |
||||||
|
if ($n < 2) { |
||||||
|
fwrite(STDERR, "请输入一个大于等于2的整数作为上限。\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
$primes = sieveOfEratosthenes($n); |
||||||
|
var_dump(count($primes)); |
||||||
|
var_dump(microtime(true) - $begin); |
||||||
|
// 输出每个素数(每行一个) |
||||||
|
// foreach ($primes as $prime) { |
||||||
|
// echo $prime . "\n"; |
||||||
|
// } |
||||||
|
} |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
#include <phpx.h> |
||||||
|
|
||||||
|
using namespace php; |
||||||
|
|
||||||
|
class VectorBox : public Box { |
||||||
|
public: |
||||||
|
std::vector<bool> vec; |
||||||
|
VectorBox(size_t size, bool init) { |
||||||
|
vec.resize(size, init); |
||||||
|
} |
||||||
|
void checkOffset(Int offset) { |
||||||
|
if (offset >= vec.size()) { |
||||||
|
zend_throw_error(NULL, "index[%ld] is out of range()", offset); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
var php_vector_new(Int size, Bool init) { |
||||||
|
return {new VectorBox(size, init)}; |
||||||
|
} |
||||||
|
|
||||||
|
Bool php_vector_get(var box, Int offset) { |
||||||
|
auto vecbox = box.toBox<VectorBox>(); |
||||||
|
vecbox->checkOffset(offset); |
||||||
|
return vecbox->vec.at(offset); |
||||||
|
} |
||||||
|
|
||||||
|
void php_vector_set(var box, Int offset, Bool value) { |
||||||
|
auto vecbox = box.toBox<VectorBox>(); |
||||||
|
vecbox->checkOffset(offset); |
||||||
|
vecbox->vec.at(offset) = value; |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
<?php |
||||||
|
function vector_new(int $size, bool $init = false): mixed |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function vector_get(mixed $vector, int $offset): bool |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function vector_set(mixed $vector, int $offset, bool $value): void |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue