duangsuse::Echo
806 subscribers
4.47K photos
137 videos
583 files
6.79K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): a19a0b
Download Telegram
羽毛的小白板
极端 https://www.zhihu.com/question/317346252
#backend #GeekApk #SQL select * from yourTable limit 14 offset (4-1)*14;

🤔 我之前设计的 GeekApk 还没写 Database service 层,可是我居然因为没写到最后就不知道这个东西... 虽然我知道 SQL LIMIT,但我所想的却是 先 LIMIT 查询了之后,结果上 JVM 再去 subsequence...

我甚至还真把这个当回事了,还以为得专门抽提一个函数完成分页功能(geekapk API 的分页是很灵活的,使用的参数基本等价于 LIMIT 和 OFFSET)

还有,我刚才居然以为 LIMIT OFFSET 的 LIMIT 是基于整个关系行表头位置来说的偏移量,也就是说得 SELECT * FROM _ LIMIT (4-2)*14 OFFSET (4-1)*14... 简直毫无脑子

A, B, C, ... 都是关系元组

Table = [A | B | C | D | E | F]
SELECT * FROM Table LIMIT 1;
[A]
SELECT * FROM Table LIMIT 1 OFFSET 2;
[B]

(define pageSize 3)
(define collect-page' (pageSize page)
SELECT * FROM Table
LIMIT ${pageSize} OFFSET ((${page}-1)*${pageSize}))
(define collect-page (n) (collect-page' pageSize n))

(collect-page 1) = SELECT * FROM Table LIMIT 3 OFFSET (1-1)*3
[A | B | C]

(collect-page 2) = SELECT * FROM Table LIMIT 3 OFFSET (2-1)*3
= [A | B | C <OFFSET:3> D | E | F] Read 3
= [D | E | F]

== UPDATE: 我刚才用 SQLite 3 测试了一下,SQLite 其实是从 0 开始索引的,所以上面的是错的,我应该再减去 1...
至于为什么他们自己的就没有问题,是因为第一个 (1-1) 碰巧是 0,forall n in {R}. 0*n = 0,但是如果不为零,就得考虑零基数组的问题了...

create table test(text name);
foreach(x in listOf('a', 'b', 'c', 'd')) insert into test values(x);
select * from test limit 3;
select * from test limit 1;
select * from test limit 1 offset 1;
select * from test limit 1 offset 0; -- no returning records

(没用到啥关系代数知识,一方面也是关系代数那点操作符不够,虽然可以自己造新含义...)
唉,看来我还是了解的不够仔细。
其实我也相当努力了... 可是,其实有些东西就是要花时间... 而且我现在还没有机会沾染计算机图形学和人工智能
duangsuse::Echo
😔 Sticker
所以 GeekApk v1b trivial 的不得了的权限验证和所谓高难度的分页,都是智障级别的.... 除了被不良工程的 GeekSpec、Spectrum,我不知道它还有什么可取之处... 只要我现在完成这个临时的版本,真该啥时候重写的。
This media is not supported in your browser
VIEW IN TELEGRAM
#DuangsuseSB 煞笔警告一次
duangsuse::Echo
#DuangsuseSB 煞笔警告一次
好吧,好吧,duangsuse 来恢复一下心情,顺便写今天最后一个代码:默写重写 @YuutaW 的 RandomPicture

完全默写,包括 Gradle 构建文件(除了 Vertx 的依赖关系 Coordinate 在外)
并且,不得使用 IDEA 等具有自动补齐功能的 IDE

== 首先,我们来玩个简单的文件排序游戏,因为 duangsuse 不是学算法的(我以后会学)所以不考虑算法层的东西,就快速排序吧(因为它不需要我花时间去记,皮一下哦)(反正怎么说我,交换、插入、选择排序里,我也只会快排、冒泡、简单选择,虽然 OI 基础里还有简单插入、希尔排序、堆排序)。

肯定要用 Kotlin 最好,Haskell?那玩意 IO 模块的 API 我还不是老熟,现在弄了又要花掉十几分钟时间。

首先,我们要这么定义我们的『顺序』(基于 Int 优先级):
优先级,0 为最高优先级,往后依次递减,排序时使用 greaterThan ([a|b],若 a greaterThan b,则交换顺序) 来比较

针对每个字符,使用求和函数归并出优先级:
[A-Z] 范围内,递减优先级(0..23)
[a-z] 范围内,递减优先级,比 [A-Z] 小(23..49)
[0-9] 范围内,比 [a-z] 小(49..59)
任意其他字符,不影响优先级(0)

首先我们定义快速排序函数:

fun <E> quickSort(compare: Comparator<E>)
= fun (items: List<E>, lhsStart: Int = 0, rhsEnd: Int = items.lastIndex) {
// recursion base: like [1] / [2]
if (items.size < 2) return items;

// select swap pivot
val pivot = items.size / 2
// recursion
val lhsSorted = quickSort(compare)(items[lhsStart..pivot], pivot, );
val rhsSorted = quickSort(compare)(items[pivot..rhsEnd], pivot, );

// exchange mybe?
if (compare(lhsSorted.last(), rhsSorted.first()) > 0) {
// lhs is greaterThan rhs, swap then
return rhsSorted + lhsSorted
} else { return lhsSorted + rhsSorted }
}

以上这个函数写了我差不多半个小时,但是没有成功,我始终忘记了应该怎么模拟调用栈来设计算法... 🤔
所以我索性直接抄了某本算法书上的算法,我说过我是本本主义者。

fun <E> List<E>.quickSort(cmp: Comparator<E>): List<E> {
if (this.size < 2) return listOf()
val pivot = this[this.size / 2]
val less = this.filter { cmp.compare(pivot, it) > 0 }
val more = this.filter { cmp.compare(pivot, it) < 0 }
return more.quickSort(cmp) + pivot + less.quickSort(cmp)
}

import java.text.Collator
val col = Collator.getInstance()
const val TEXT = "hello HELLO 810 114514 1919810 z ab cd dc"
TEXT.split(' ').quickSort(col)

[z, HELLO, dc, cd, ab, 1919810]


我开始居然忘记递归调用 quickSort 了... 最近思路有点崩溃,看不到数据的流动了。
然后居然又忘记了,基线条件,列表的大小必须得大于等于 2 才有顺序一说啊!
亏我还想画图分析来着... 回头发现自己连顺序是啥都忘记了
没有思路了... 大概是老了吧

我得恶补一下算法了... 我居然不知道,左边的必须全是比 pivot 小的元素、右边的全得是比 pivot 大的元素,才能交换啊!唉
可怜的、不是天才的 duangsuse,长得又不好看,emmmmm....

然后是 [A-Z] [a-z] [0-9] 的排序

class StringComparator: Comparator<String> {
override fun compare(r: String, l: String): Int = toLevel(r).compareTo(toLevel(l))
override fun equals(o: Any?) = o is StringComparator // Stateless comparator

companion object Helper {
fun toLevel(str: String) = str.fold(0, ::appendLevel)
private fun appendLevel(acc: Int, ch: Char) = acc + getCharLevel(ch)
fun getCharLevel(ch: Char): Int = when (ch) {
in 'A'..'Z' -> ch - 'A'
in 'a'..'z' -> ch - 'a' + 26
in '0'..'9' -> ch - '0' + ('a'-'0'+2)
else -> 0
}
}
}
}

且慢,那么,假若我们希望开头的字符优先级更高呢?
这就是我们用 fold 而不是 sum 的原因啊!

修改一下:

fun toLevel(str: String) = str.fold((0, str.size), ::appendLevel)
private fun appendLevel(acc: Int, chnk: (Char, Int)) = (acc + chnk.second * getCharLevel(chnk.first), chnk.second - 1)

:: 从第一个字符开始以字符串长度数,每个字符都递减,然后把当前字符的长度,乘当前字符的优先级

那么是测试时间了呢。
好了,我玩够了。


和画出 mindmap,给大家讲出『Vibrator 到 System Service』所有的知识点。

快快写完睡觉吧。
结果
TextSort.kt
2 KB
This media is not supported in your browser
VIEW IN TELEGRAM
https://github.com/duangsuse/RandomPicture 我必须得感谢自己,因为我使我自己发现了无计划死拖死缠的坏处和自己能力、记忆的有限... #life #tech #dev
RandomPicture.kt
3.8 KB
duangsuse::Echo
Photo
熬夜了一个通宵,真的是相当无聊,我感觉我学习的效率也很低下,差点连 Docker 都没学到!
校验:记下了一个名字:openjdk:8u171-jdk-alpine3.8
但是效果的确很差!而且熬夜导致身体变差

真的不值得死磕
#Kotlin #backend #JVM #Java 但我肯定我的思路是没问题的,很清晰,但是我没有在可以接受的时间、可以接受的抄代码/记忆量内完成... 成功反驳了对脑力有限论调加以批判的年轻人 🐸 #Moha 好暴力