news 2026/5/12 10:26:31

一个用postgresql的自定义函数求解数独的程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一个用postgresql的自定义函数求解数独的程序

从这个网页看到一个用postgresql的自定义函数求解数独的程序,其实核心还是一个利用递归CTE的SQL。
然后把两个计算行列宫的临时表做成物理表。
对问题表中的每行执行上述标量函数,效率和单独的SQL差不多。难题耗时比较长。

postgres@b3490d8427cd:~$ psql psql (17.7 (Debian 17.7-3.pgdg13+1)) Type "help" for help. postgres=# table sudoku9_9; postgres=# CREATE TABLE allnum AS SELECT generate_series(1, 9) AS num ; SELECT 9 postgres=# CREATE TABLE grid AS SELECT (i - 1) * 9 + j AS indexof ,i ,j ,(i - 1) / 3 * 3 + 1 + (j - 1) / 3 AS grp FROM allnum n1(i) ,allnum n2(j) ; SELECT 81 postgres=# CREATE OR REPLACE FUNCTION sudoku(text) RETURNS text LANGUAGE sql IMMUTABLE AS $$ WITH RECURSIVE _sudoku AS ( -- 初期値 SELECT $1 kekka -- 再帰with句で追加されていく行 UNION ALL( WITH latest AS ( SELECT kekka ,(ROW_NUMBER() OVER())::int parallelid FROM _sudoku ) ,gridnum AS ( SELECT latest.parallelid ,indexof, i, j, grp ,substr(latest.kekka, indexof, 1) AS num FROM latest, grid ) ,used AS ( SELECT gridnums.parallelid ,gridnums.indexof ,array_agg(DISTINCT usednums.num :: int) usednumarray FROM gridnum usednums ,gridnum gridnums WHERE usednums.num <> ' ' AND gridnums.num = ' ' AND usednums.parallelid = gridnums.parallelid AND( usednums.i = gridnums.i OR usednums.j = gridnums.j OR usednums.grp = gridnums.grp ) GROUP BY gridnums.parallelid ,gridnums.indexof ) ,insertnum AS ( SELECT parallelid ,indexof ,usednumarray ,DENSE_RANK() OVER( PARTITION BY used.parallelid ORDER BY ARRAY_LENGTH(used.usednumarray, 1) DESC, indexof ) AS insertorder FROM used ) SELECT overlay(latest.kekka placing allnum.num::text FROM insertnum.indexof FOR 1) AS kekka FROM latest ,allnum ,insertnum WHERE latest.parallelid = insertnum.parallelid AND insertnum.insertorder = 1 AND allnum.num <> ALL(insertnum.usednumarray) ) ) SELECT kekka FROM _sudoku WHERE strpos(kekka, ' ') = 0; $$ ; CREATE FUNCTION postgres=# CREATE TABLE sudoku_q AS SELECT 1 id, ' 6 3 1 9 5 2 31 14 678 786529 34567 93 1891456372 24 875 9'::text as question UNION SELECT 2, ' 7 3 6 9152 23 48 7418 65 7 9325 876 9341 9215 37 5 18296' UNION SELECT 3, ' 3 1967 4 8 2 34157 2 62315 68 9 13 68 9 258479 6 2 9143857' UNION SELECT 4, ' 9 8 7 42 6 3 7 1 2 5 836 992 651 475 63491831 8 7452 9521 63' UNION SELECT 5, ' 5 3 6 824 7 1 2954167 1 86 2954 6 7 9312 39784 563241 7 9 5283' ; SELECT 5 postgres=# SELECT * FROM sudoku_q ORDER BY id; id | question ----+----------------------------------------------------------------------------------- 1 | 6 3 1 9 5 2 31 14 678 786529 34567 93 1891456372 24 875 9 2 | 7 3 6 9152 23 48 7418 65 7 9325 876 9341 9215 37 5 18296 3 | 3 1967 4 8 2 34157 2 62315 68 9 13 68 9 258479 6 2 9143857 4 | 9 8 7 42 6 3 7 1 2 5 836 992 651 475 63491831 8 7452 9521 63 5 | 5 3 6 824 7 1 2954167 1 86 2954 6 7 9312 39784 563241 7 9 5283 (5 rows) postgres=# \timing Timing is on. postgres=# SELECT id, sudoku(question) FROM sudoku_q ORDER BY id; id | sudoku ----+----------------------------------------------------------------------------------- 1 | 472931658635842917918765423259314786143678295786529134567293841891456372324187569 2 | 694857123387142659152639784235481967418976532769325841876293415921564378543718296 3 | 458326719672914385913857426341579268896231574725468193137685942584792631269143857 4 | 235976841178342596694158327867419235541283679923765184752634918316897452489521763 5 | 635217849741893526982456731329541678178632954564789312213978465856324197497165283 (5 rows) Time: 35.973 ms postgres=# insert into sudoku_q SELECT 8 AS id, E'8 36 7 9 2 5 7 457 1 3 1 68 85 1 9 4 '; INSERT 0 1 Time: 3.909 ms postgres=# SELECT id, sudoku(question) FROM sudoku_q ORDER BY id; id | sudoku ----+----------------------------------------------------------------------------------- 1 | 472931658635842917918765423259314786143678295786529134567293841891456372324187569 2 | 694857123387142659152639784235481967418976532769325841876293415921564378543718296 3 | 458326719672914385913857426341579268896231574725468193137685942584792631269143857 4 | 235976841178342596694158327867419235541283679923765184752634918316897452489521763 5 | 635217849741893526982456731329541678178632954564789312213978465856324197497165283 8 | 812753649943682175675491283154237896369845721287169534521974368438526917796318452 (6 rows) Time: 4808.878 ms (00:04.809) postgres=#
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 3:08:01

生态林业旅游体验与森林保护攻略

生态林业旅游不是简单的进山看树&#xff0c;它是以森林生态系统为依托&#xff0c;在严格保护的前提下&#xff0c;通过科学规划和合理利用&#xff0c;让游客体验自然之美、感知生态价值&#xff0c;并促进区域可持续发展的一种旅游形式。它核心在于平衡“生态保护”、“旅游…

作者头像 李华
网站建设 2026/5/12 0:24:00

2026亚马逊自养号测评技术全解:五大核心维度构建安全运营体系

在跨境电商竞争白热化的2026年&#xff0c;亚马逊平台的流量分配机制愈发依赖用户行为数据&#xff0c;测评作为提升产品权重、突破流量瓶颈的核心手段&#xff0c;其技术迭代已进入精细化、智能化新阶段。自养号测评凭借其安全性、可控性和成本效益&#xff0c;成为卖家构建竞…

作者头像 李华