本文精心挑选了许多优秀的Unicode小技巧、软件包和资源。

译者 | 弯月,责编 | 郭芮

出品 | CSDN(ID:CSDNnews)

以下为译文:

Unicode非常了不起!在Unicode出现之前,国际交流是一团糟——每个人都在ASCII码表的后半部分区域(称为“代码页”)定义了自己的扩展和字符集,从而导致各种冲突。想想就知道,德国人要与韩国人只使用127个字符组成的代码页进行交流会有多么困难。

——幸亏有了Unicode标准和统一的交流规范。

Unicode 8.0根据129多种书写体系,标准化了超过120,000个字符,其中包括现代字符、古代字符,甚至还包括人类尚未解密的文字。Unicode能处理从左到右和从右到左两种书写方式,支持组合标记,还支持多种文化、政治、宗教方面的字符,甚至还有表情符号。

Unicode太了不起了,我们对它的崇拜犹如滔滔江水绵绵不绝。

Unicode的背景

Unicode标准支持什么字符?

Unicode标准定义了今日所有主流的书写语言中用到的字符。Unicode支持的书写体系包括欧洲的语系、中东的从右至左书写的语系,以及亚洲的多种语系。

Unicode标准还包含了标点符号、声调符号、数学符号、科技符号、箭头、各种图形符号、表情符号,等等。Unicode为声调符号(用来改变其他字符的符号,如波浪线~)单独提供了代码,这些代码可以与基础字符组合使用,来表示有声调的字符(如ñ)。Unicode标准9.0版总共提供了128,172个字符的代码,其中包括了全世界的字符、图形和符号。

绝大部分的常用字符都能映射到最前面的64K个代码点上,这一区域叫做基本多文种平面(basic multilingual plane,简称为BMP)。还有十六个补充平面用来编码其他字符,目前尚有850,000个未使用的代码点。人们还在考虑在以后的版本中添加更多的字符。

Unicode标准还保留了一些代码点供私人使用。供应商或最终用户可以在内部利用这些代码点表示他们自己的字符和符号,或者通过特殊的字体来使用。BMP上有6,400个私有代码点,如果不够的话,补充平面上还有131,068个私有代码点可供使用。

Unicode字符编码

字符编码标准不仅定义了每个字符的唯一标识(即字符的数字值,或者叫做代码点),也定义了怎样用比特来表示这个值。

Unicode标准定义了三种编码形式,允许同一个数据以一字节、两字节或四字节的格式来传输(即每个代码单元可以是8比特、16比特或32比特)。同一个字符集可以使用所有三种编码形式,它们之间可以互相转换,而不会丢失数据。Unicode联盟建议根据实际需要,选择任何一种方便的编码方式来实现Unicode标准。

UTF-8在HTML和类似协议上非常常用。UTF-8使用变长编码。它的优点是,对应于ASCII字符集的那些Unicode字符的字节值与它们在ASCII中的值完全相同,因此使用UTF-8编码的Unicode字符可以在绝大多数已有软件上使用,无需对软件做出任何修改。

UTF-16在许多需要平衡性能和存储效率的环境中非常常用。它足够紧凑,所有常用的字符都可以用一个16比特的代码单元来表示,其他字符可以使用一对16比特代码单元来表示。

UTF-32在无需顾虑内存空间的情况下使用,它是定长编码,每个字符只有一个代码单元。每个Unicode字符编码成一个32比特代码单元。

在所有三种编码中,每个字符最多需要4个字节(32比特)表示。

数字问题

Unicode字符集被分成17个核心段,称为“平面”,每个平面又被分成若干区块。每个平面的空间足够容纳65,536(216)个代码点,因此总共有1,114,112个代码点。还有两个“私有区域”平面(#16和#17),可以按照使用者的意愿定义。这两个私有平面共包含131,072个代码点。

第一个平面叫做“基本多文种平面”,或者称为BMP。它包含代码点U+0000到U+FFFF,这个范围内包含了绝大部分常用字符。另外16个平面(U+010000到U+10FFFF)称为补充平面。

UTF-16代理对

“BMP之外的字符,例如U+1D306 tetragram for centre (????),在UTF-16编码中只能编码成两个16比特代码单元:0xD834 0xDF06。这种情况称为代理对(surrogate pair)。注意代理对只表示一个字符。

“代理对的第一个字符永远在0xD800到0xDBFF的范围内,称为高位代理,或者叫起始字节代理。代理对的第二个代码单元永远在0xDC00到0xDFFF的范围内,称为低位代理,或者叫末端代理。”

——Mathias Bynens

“代理对:一种表示方式,用于表示由两个16比特代码单元组成的单个抽象字符,其中第一个值称为高位代理代码单元,第二个值称为低位代理单位。代理对仅在UTF-16中使用。”

——Unicode 8.0 第3.9章,代理对(参见Unicode编码)

计算代理对

代理字符???? Pile of Poo (U+1F4A9) 在UTF-16中必须编码成代理对,即两个代理。要将代码点转换成代理对,可以使用以下算法(用JavaScript编写)。注意我们使用的是十六进制表示。

var High_Surrogate = function(Code_Point){ return Math.floor((Code_Point - 0x10000) / 0x400) + 0xD800 };var Low_Surrogate  = function(Code_Point){ return (Code_Point - 0x10000) % 0x400 + 0xDC00 };// Reverses The Conversionvar Code_Point = function(High_Surrogate, Low_Surrogate){return (High_Surrogate - 0xD800) * 0x400 + Low_Surrogate - 0xDC00 + 0x10000;};
 > var codepoint = 0x1F4A9;                       // 0x1F4A9 == 128169> High_Surrogate(codepoint).toString(16)"d83d"                                          // 0xD83D == 55357> Low_Surrogate(codepoint).toString(16)"dca9"                                          // 0xDCA9 == 56489> String.fromCharCode(  High_Surrogate(codepoint) , Low_Surrogate(codepoint) );"????"
> String.fromCodePoint(0x1F4A9)"????"> '\ud83d\udca9'"????"

组合和解组合

Unicode包括了一种修改字符形状的机制,大幅扩展了Unicode支持的字符量。使用声调符号进行组合就是其中一种方式。声调符号写在主字符的后面。多个声调符号可以叠在同一个字符上。对于绝大部分常用的字母声调组合,Unicode还包括了预先组合好的版本。

特定的字符序列也可以用单个字符表示,称为“预组合字符”(或者叫组合字符,可以解组合的字符)。例如,字符“ü”可以编码成单个代码单元U+00FC “ü”,也可以编码成基本字符U+0075 “u”后接无空白字符U+0308 “¨”。Unicode标准中设置的预组合字符是为了兼容Latin 1等标准,后者包含了许多预组合字符,如“ü”和“ñ”。

预组合字符可以进行接组合,以保持一致性,或用于分析。例如,需要将一组名称转换为英文字母时,可以将字符“ü”解组合为“u”后接非空白字符“¨”。解组合后的结果很容易处理,因为该组合字符可以处理成“u”后接一个修饰字符。这样很容易进行按字母顺序排序等,因为修饰字符不会影响字母顺序。Unicode标准为所有预组合字符定义了解组合方式(https://unicode.org/versions/Unicode8.0.0/ch03.pdf#page=44)。它还定义了正规化的方式,以便为字符提供唯一的表示方法。

Unicode之谜

来自Mark Davis的《Unicode之谜》幻灯片(https://macchiato.com/slides/UnicodeMyths.pdf)。

  • Unicode只不过是16比特编码。一些人误认为Unicode只不过是16比特编码,每个字符占用16比特,因此一共有65,536个可能的字符。实际上这是不正确的。这样是关于Unicode的最大误解,所以也难怪一些人会这么想。

  • 任何未分配的代码点都可以用于内部用途?错。最终,那些未分配的地方都会被某个字符使用。你应该使用私有用途代码点,或非字符代码点。

  • 每个Unicode代码点都表示一个字符?错。有许多非字符代码点(FFFE,FFFF,1FFFE,……)还有许多代理代码点、私有代码点和未分配的代码点,还有控制和格式“字符(RLM,ZWNJ,……)

  • 字符映射是一对一的?错。映射关系也可能是:

  • 一对多:(ß → SS )

  • 上下文相关:(…Σ ↔ …ς 和 …ΣΤ… ↔ …στ… )

  • 语言相关:( I ↔ ı 和 İ ↔ i )

实用Unicode编码手册

编码类型编码

神奇的字符列表

特殊字符

详情可以参照Unicode联盟发布的《通用标点符号表》(https://www.unicode.org/charts/PDF/U2000.pdf)。

等等,你说什么?

变量标识符可以包含空白!

U+3164 HANGUL FILLER 字符显示为占据空间的空白字符。如果渲染器不支持,则会渲染成完全不可见(也不会占据任何空间,即“零宽度”)。这就是说,永远不会看到丑陋的字符替代符号(�)。

我不知道为什么U+3164被设计成这种行为。有意思的是,U+3164是在Unicode 1.1版本(1993年)加入的,所以联盟一定是花了很多时间思考它。下面是几个例子:

> var ᅟ = 'foo';
undefined
> ᅟ
'foo'> var ㅤ= alert;
undefined
> var foo = 'bar'
undefined
> if ( foo ===ㅤ`baz` ){}     // alert
undefined> var varㅤfooㅤ\u{A60C}ㅤπ = 'bar';
undefined
> varㅤfooㅤꘌㅤπ
'bar'

注意:我在Ubuntu和OSX下测试了下述程序的渲染结果:Node,PHP,Ruby,Python3.5,Scala,Vim,Cat,Chrome+GitHub gist。Atom是唯一无法正确渲染,将其显示成空方块的程序。我还没有测试Emacs和Sublime。据我的理解,Unicode联盟不会改变或重命名字符或代码点,但有可能会改变字符属性,如ID_Start或ID_Continue等。

修饰符

零宽度连接符(ZWJ)是个不可打印字符,用于某些复杂语系的计算机排版系统中,如阿拉伯语系、印度语系等。将ZWJ放在两个本来不会连接的字符之间,将会导致它们以连接的形式打印。

零宽度不连接符(ZWNJ)是个不可打印字符,那些使用连接的书写系统的计算机化。将ZWNJ放在两个本来会连接在一起的字符之间,会导致它们以本来的形式打印。空格字符也有同样的效果,但ZWNJ的作用是它能保证输出的两个字符尽可能靠近,或者连接一个词及其语素。

> 'a'"a"> 'a\u{0308}'"ä"> 'a\u{20DE}\u{0308}'"a⃞̈"> 'a\u{20DE}\u{0308}\u{20DD}'"a⃞̈⃝"// Modifying Invisible Characters
> '\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}'"‎‎‎‎‎‎‎‎‎‎"> '\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}\u{200E}'.length10

大写变换冲突

小写变换冲突

奇怪现象和排查方法

  • 字符串长度通常由统计代码点的个数来计算。这就是说,代理对会被统计成两个字符。多个声调符号会叠放在同一个字符上,例如a + ̈ == ̈a,从而增加长度,但它们只会产生一个字符。

  • 类似地,字符串翻转通常非常困难。同样,代理对和带有声调符号的字符必须作为整体进行翻转。ES Reverser提供了一个非常好的解决方法。

  • 字符映射是一对一的?错。映射关系也可能是:

  • 一对多:(ß → SS )

  • 上下文相关:(…Σ ↔ …ς 和 …ΣΤ… ↔ …στ… )

  • 语言相关:( I ↔ ı 和 İ ↔ i )

一对多映射

绝大多数字符,在大写的时候表示一对多关系;另一些字符小写的时候表示一对多关系。

优秀的软件包和库

  • PhantomScript::ghost: :flashlight: 不可见的JavaScript代码执行和社会工程工具。

  • ESReverser:用JavaScript编写的支持Unicode的字符串翻转。

  • mimic:Unicode的恶作剧。

  • python-ftfy:输入Unicode文本,输出更一致、更不容易出现显示错误的表现形式。

  • vim-troll-stopper:防止Unicode的捣乱字符搞乱你的代码。

表情符号

  • Unicode联盟的表情符号表(https://www.unicode.org/emoji/charts/full-emoji-list.html)

  • Emojipedia(https://emojipedia.org/):关于特定表情符号的信息,新闻博客。

  • World Translation Foundation(https://www.emojifoundation.com/):宣传、探索,还可以将文本翻译成用表情符号表示的形式。

  • Can I Emoji? (https://caniemoji.com/android-2/):显示当前iOS、Android和Windows对于表情符号的原生支持情况。

  • 怎样注册一个表情符号URL(https://www.name.com/blog/how-tos/2015/12/want-an-emoji-url-this-is-how-you-register-one/)

多样性

Unicode联盟在支持人类的多样性和多元文化方面做出了很多努力。这里是联盟提供的多样性报告(https://unicode.org/reports/tr51/#Diversity)。

现在表情符号已经支持混合型别,比如同性家庭、握手、接吻等。真正轰动的是表情符号组合序列。基本上来说:

此外,表情符号现在还支持肤色修饰字符了。

“有五个符号修饰字符可以为Unicode 8.0版(2015年中期)中发布的人类的表情符号提供一系列的肤色。这些字符基于Fitzpatrick度量(皮肤学上的著名标准,网上也有许多例子,比如FitzpatrickSkinType.pdf)定义的六种肤色。不同的实现的精确颜色可能不同。”

——Unicode联盟的多样性报告

只需要在所需的表情符号后面接上肤色修饰字符 \u{1F466}\u{1F3FE} 即可。

有创意的变量名和方法名

示例采用JavaScript(ES6)编写。

一般而言,带有ID_START属性的字符可以用在变量名开头,而带有ID_CONTINUE属性的字符可以用在变量名中除了首字符之外的其他位置。

function rand(μ,σ){ ... };String.prototype.reverseⵑ = function(){..};Number.prototype.isTrueɁ = function(){..};var WhatDoesThisDoɁɁɁɁ = 42

下面是Mathias Bynes(https://mathiasbynens.be/notes/javascript-identifiers#examples)提供的一些极富创意的变量名:

// How convenient!
var π = Math.PI;// Sometimes, you just have to use the Bad Parts of JavaScript:
var ಠ_ಠ = eval;// Code, Y U NO WORK?!
var ლ_ಠ益ಠ_ლ = 42;// How about a JavaScript library for functional programming?
var λ = function() {};// Obfuscate boring variable names for great justice
var \u006C\u006F\u006C\u0077\u0061\u0074 = 'heh';// …or just make up random ones
var Ꙭൽↈⴱ = 'huh';// While perfectly valid, this doesn’t work in most browsers:
var foo\u200Cbar = 42;// This is *not* a bitwise left shift (`<<`):
var 〱〱 = 2;
// This is, though:
〱〱 << 〱〱; // 8// Give yourself a discount:
var price_9̶9̶_89 = 'cheap';// Fun with Roman numerals
var Ⅳ = 4;
var Ⅴ = 5;
Ⅳ + Ⅴ; // 9// Cthulhu was here
var Hͫ̆̒̐ͣ̊̄ͯ͗͏̵̗̻̰̠̬͝ͅE̴̷̬͎̱̘͇͍̾ͦ͊͒͊̓̓̐_̫̠̱̩̭̤͈̑̎̋ͮͩ̒͑̾͋͘Ç̳͕̯̭̱̲̣̠̜͋̍O̴̦̗̯̹̼ͭ̐ͨ̊̈͘͠M̶̝̠̭̭̤̻͓͑̓̊ͣͤ̎͟͠E̢̞̮̹͍̞̳̣ͣͪ͐̈T̡̯̳̭̜̠͕͌̈́̽̿ͤ̿̅̑Ḧ̱̱̺̰̳̹̘̰́̏ͪ̂̽͂̀͠ = 'Zalgo';

下面是David Walsh提供的一些Unicode CSS类名(https://davidwalsh.name/unicode-css-classes):

<!-- place this within the document head -->
<meta charset="UTF-8" /><!-- error message -->
<div class="ಠ_ಠ">You do not have access to this page.</div><!-- success message -->
<div class="❤">Your changes have been saved successfully!</div>
.ಠ_ಠ {border: 1px solid #f00;
}.❤ {background: lightgreen;
}

递归的HTML标签重命名脚本

如果你想把所有HTML标签重命名,使之看上去像什么都没有,那么可以使用以下的脚本。

但要注意,HTML并不会支持所有的Unicode字符。

// U+1160 HANGUL JUNGSEONG FILLER
transformAllTags('ᅠ');// An actual HTML element node designed to look like a comment node, using the U+01C3 LATIN LETTER RETROFLEX CLICK
//    <ǃ-- name="viewport" content="width=device-width"></ǃ-->
transformAllTags('ǃ--');// or even <ᅠ⃝
transformAllTags('\u{1160}\u{20dd}');// and for a bonus, all existing tag names will have each character ensquared. h⃞t⃞m⃞l⃞
transformAllTags();function transformAllTags (newName){// querySelectorAll doesn't actually return an array.Array.from(document.querySelectorAll('*')).forEach(function(x){transformTag(x, newName);});
}function wonky(str){return str.split('').join('\u{20de}') + '\u{20de}';
}function transformTag(tagIdOrElem, tagType){var elem = (tagIdOrElem instanceof HTMLElement) ? tagIdOrElem : document.getElementById(tagIdOrElem);if(!elem || !(elem instanceof HTMLElement))return;var children = elem.childNodes;var parent = elem.parentNode;var newNode = document.createElement(tagType||wonky(elem.tagName));for(var a=0;a<elem.attributes.length;a++){newNode.setAttribute(elem.attributes[a].nodeName, elem.attributes[a].value);}for(var i= 0,clen=children.length;i<clen;i++){newNode.appendChild(children[0]); //0...always point to the first non-moved element}newNode.style.cssText = elem.style.cssText;parent.replaceChild(newNode,elem);
}

下面是确定能够支持的字符:

function testBegin(str){try{eval(`document.createElement( '${str}' );`)return true;}catch(e){ return false; }
}function testContinue(str){try{eval(`document.createElement( 'a${str}' );`)return true;}catch(e){ return false; }
}

下面是一些基本的结果:

// Test if dashes can start an HTML Tag
> testBegin('-')
< false> testContinue('-')
< true> testBegin('ᅠ-')    // Prepend dash with U+1160 HANGUL JUNGSEONG FILLER
< true

Unicode字体

单一的TrueType / OpenType 字体格式无法支持所有UTF-8字符,因为字体文件有最大65535个字形的限制。UTF-8的字形超过了110万,因此你需要一个font-family才能覆盖所有字体。

  • https://en.wikipedia.org/wiki/Unicode_font#List_of_Unicode_fonts

  • https://www.unifont.org/fontguide/

Unicode标准的原则

Unicode标准设定了下述基本原则:

  • 通用原则——曾经出现过的一切书写系统都应该在标准中体现。

  • 逻辑顺序——在双向文本中,字符以逻辑顺序存储,而不是表现顺序存储。

  • 效率——文档必须是高效的、完整的。

  • 统一——不同文化或语言使用同一个字符时,应该仅存储一次。

  • 记录字符而不是字形——应当对字符进行编码,而不是字形。字形就是字符的实际图形表示。

  • 动态组合——新的字符可以与已有的标准化后的字符进行组合。例如,字符“Ä”可以用字符“A”和分音符“¨”组合而成。

  • 语义——包含的字符必须有明确定义,必须与其他字符有明确的区别。

  • 稳定——字符一旦被定义,就永远不能被移除,其代码点也不能被挪作他用。如果出错,则应该将代码点标记为弃用。

  • 纯文本——标准中的字符应当是纯文本,永远不应该包含标记或元字符。

  • 可转换——每一种编码都应该可以用Unicode编码表示。

原文:https://wisdom.engineering/awesome-unicode/

本文为 CSDN 翻译,转载请注明来源出处。

【End】

Python的C位稳了!微软正式拥抱Python !

https://edu.csdn.net/topic/python115?utm_source=csdn_bw

Python系列学习成长课来了!15年经验专家、CSDN特级讲师亲自授课,还等什么?立即扫码报名学习:

热 文 推 荐 

☞库克:苹果从没有垄断;微信搜索升级;微软发布首款支持 Linux 的 Office 应用 | 极客头条

☞学编程不如学自动化?

☞程序员生存指南:如何在技术浪潮中屹立不倒?

☞GitHub 有望在中国开设子公司?

☞国产数据库年终大盘点!

☞华为诺亚方舟开源预训练模型“哪吒”,4项任务均达到SOTA

☞HDC.Cloud | 开赛了!和队友一起“跑”赢这趟编程马拉松!

☞云计算管理工具:根植热土

点击阅读原文,即刻报名!

你点的每个“在看”,我都认真当成了喜欢

了不起的 Unicode!相关推荐

  1. 商汤联手华科:提出文字检测模型GNNets,新颖模块可解决几何分布难题

    加入「公开课」交流群,获取更多学习资料.课程及热招岗位等信息 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100) [导读]今年的ICCV,商汤科技及联合实验室共有57篇论文入选I ...

  2. 百度重新定义「智能屏」,瞄准10后

    加入「公开课」交流群,获取更多学习资料.课程及热招岗位等信息 记者 | 阿司匹林 作为中国智能音箱主力推手中的一员,百度从 2017 年已经开始布局.根据数据机构Strategy Analytics发 ...

  3. 混合推荐系统就是多个推荐系统“大杂烩”吗?

    作者丨gongyouliu 编辑丨zandy [导读]在本篇文章中,我们会介绍混合推荐系统(Hybrid Recommender Systems),就是利用多种推荐算法配合起来做推荐,期望避免单个推荐 ...

  4. 4大主流CPU处理器技术架构,不知道就out了!

    作者 | 王艺威 责编 | 阿秃 RISC(精简指令集计算机)是一种执行较少类型计算机指令的微处理器,起源于80年代的MIPS主机(即RISC机),RISC机中采用的微处理器统称RISC处理器.这样一 ...

  5. 20行代码发一篇NeurIPS:梯度共享已经不安全了

    整理 | 夕颜,Jane 出品 | AI科技大本营(ID:rgznai100) [导读]12 月 8 日-14 日,NeurIPS 2019 在加拿大温哥华举行,和往常一样,今年大会吸引了数万名专家参 ...

  6. 19年NAACL纪实:自然语言处理的实用性见解 | CSDN博文精选

    作者 | Nikita Zhiltsov 翻译 | 王威力 校对 | 李海明 本文为你概述处理不同NLP问题时的具有卓越性能的方法.技术和框架等. 计算语言:人类语言技术学会北美分会2019年年会(N ...

  7. 操作系统三十年的兴衰史

    加入「公开课」交流群,获取更多学习资料.课程及热招岗位等信息 作者 | Jeremy Reimer 译者 | 苏本如 责编 | 屠敏 来源 | CSDN(ID:CSDNnews) 提及桌面操作系统,想 ...

  8. windows核心编程-第二章 Unicode

    第2章U n i c o d e 随着M i c r o s o f t公司的Wi n d o w s操作系统在全世界日益广泛的流行,对于软件开发人员来说,将目标瞄准国际上的各个不同市场,已经成为一个 ...

  9. VB中Unicode vs Ansi-From alpsong(阿尔卑斯之歌)

    Unicode vs Ansi Visual Basic 32-bit 版本的字串处理采用 Unicode,也就是说字串在 VB 内部是以 Unicode 的格式来存放. 何谓 Unicode?简单的 ...

最新文章

  1. Caffe + ROS + OpenCV + Qt creator
  2. JSTL标签引入(web基础学习笔记十八)
  3. Vector和ArrayList区别
  4. oracle主从表分离怎么实时更新数据_高可用数据库主从复制延时的解决方案
  5. MKL学习——功能简介
  6. python解acm题_python ACM ,持续更新中。。。。。。。。。。。。
  7. 信息编码:字符串和文本
  8. 二维随机变量及其分布函数
  9. Kotlin 势必取代 Java?
  10. Hive 操作(一)
  11. 基于JAVA宠物店管理系统设计与实现计算机毕业设计源码+数据库+lw文档+系统+部署
  12. 实体映射最强工具类:MapStruct 真香!
  13. 干货丨荧光定量pcr应用于各个领域的分类疑难问题解答
  14. 呼和浩特民族学院计算机系宿舍,呼和浩特民族学院有个“励志寝室”
  15. 如何实现在线视频播放?
  16. js的event loop/js内存泄漏
  17. python.plt 画三维图像
  18. 数据库查询某行 或者 某列转换为数组方法,数据库脱机原理
  19. 巴斯勒相机acA1300-60gm
  20. python+django企业员工绩效考核管理系统vue

热门文章

  1. 修改JSONArray里所有key的值
  2. 专业 英语 心智 口才
  3. 第2章 数据库系统体系结构
  4. 利用MPI解决N体问题
  5. [二分搜索|快速选择] leetcode 4 寻找两个正序数组的中位数
  6. win10和win7游戏测试软件,Win10系统和Win7玩游戏哪个更快?评测在这里!
  7. Sublime Text使用正则表达式进行替换
  8. ef设置非自增长id_Ef core 如何设置主键
  9. bat替换文件中的字符串_JavaScript 中替换字符串的几种方法
  10. sobel,canny(可滑动调节阈值)边缘检测算法opencv-python实战