精华内容
下载资源
问答
  • AME统计025|实验组和对照组的样本量一定要“均衡”才行? 原创2015-10-27胡志德AME科研时间 “随机、对照、重复、均衡”是统计学和流行病学老师在课堂上经常强调的内容之一。受此影响,很多同行在开展科研的...

    AME统计025|实验组和对照组的样本量一定要“均衡”才行?

     

    “随机、对照、重复、均衡”是统计学和流行病学老师在课堂上经常强调的内容之一。受此影响,很多同行在开展科研的过程中不分青红皂白地遵循这四大原则。特别是对于“均衡”这一概念,很多研究者总是觉得要是实验组和对照组不平衡(样本量相差甚远)的话,研究结果就不够可靠。殊不知,并非所有的研究都要遵循“均衡”原则的。而且,部分研究如果严格遵循“均衡”原则的话,不仅无助于研究质量的提升,反而会削弱研究的论证强度。

     

    实际上,“均衡”这一原则主要是针对干预性研究提出来的,旨在维持较高的统计效能。而在医学研究领域,除了干预性研究(比如随机对照试验)外,还有观察性研究和诊断准确性试验,这些研究就不需要研究者老老实实地遵循“均衡”原则了。对于观察性研究和诊断准确性试验而言,最重要的设计要点之一就是要体现“真实世界”,或者说样本来源及构成比要接近于临床实际。

     

    1、诊断准确性试验

     

    理想的诊断准确性试验属于单门设计,即设立统一的纳入排除标准,连续或随机招募所有符合条件的病人,然后根据金标准将病人分为疾病组和对照组(非疾病组),然后采用受试者工作特征曲线(ROC)或四格表评价某一手段对疾病的鉴别能力。此外,为了保证研究质量,提升论证强度,还应该遵循双盲、统一金标准、全部接受金标准、金标准独立等原则。从上述设计原则我们不难看出,实验组和对照组是自然形成的,无需刻意将比例控制在1:1。

     

    比如:某研究分析了 NT-proBNP 在呼吸困难人群中对心力衰竭的诊断价值(J Am Coll Cardiol 2010; 55:2062-2076.),在设立了统一的纳入标准(因呼吸困难而就诊)和排除标准(外伤)后,研究者采用连续招募的方式募集到了 1641 例呼吸困难的人群,并采用金标准将病人划分为心衰病人(n=568)和非心衰病人(n=1073)。在此研究中,实验组(心衰病人)和对照组(非心衰病人)的样本之比大约是 1:2 左右。

     

    按照“均衡”原则来衡量的话,这项研究有一个明显的设计缺陷:试验组和对照组的样本量居然不均衡。J Am Coll Cardiol 这种丧心病狂到令人发指的杂志怎么会接受这样一篇用脚拇指都能看出的有漏洞的论文呢?

     

    实际上,试验组和对照组不平衡的问题并不是这项研究的缺陷,反而是研究的亮点。我们知道,在诊断试验中,诊断敏感性和特异性与诊断界值的取舍密切相关,而诊断界值的取舍又在很大程度上取决于待评价试验结果在实验组和对照组中的分布状况。如果刻意将实验组和对照组比例控制到 1:1,当然也能进行诊断准确性方面的统计学分析,但是问题在于,这种统计分析结果不具备外推性(clinical application),或者说其结论不能直接用于指导临床工作,因为实验组和对照组的比例完全是虚拟的,与真实世界的情况相差甚远。在真实世界中,如果您接诊了 1641 个因呼吸困难而就诊的人群的话,确实只能观察到约 568 例心衰病人。因此,基于这样一个人群的研究结果,显然才会具有外推性。实际上,这种实验设计理念在诊断准确性试验质量评价工具(QUADAS)中也得到了充分的体现。感兴趣的读者可以阅读 QUADAS 的相关内容。

     

    2、队列研究

     

    队列研究主要有两种,一种是研究疾病发生风险,另一种则是研究疾病的预后。我们以前一种队列研究为例,重点谈一谈实验组和对照组是否需要平衡的问题。

     

    2012 年的 BMJ 杂志刊登了一篇文章,分析类风湿因子(RF)与类风湿关节炎(RA)发病风险的关系。该研究于 1982 年左右纳入了 9712 名无 RA 的普通人群进行了分析,检测了这些人群当时的 RF 水平,随后对这些研究对象进行了长达 28 年的随访,发现有 183 人发展为 RA,之后研究者采用了 Kaplan-Meier 法和 Cox 模型分析了基线 RF 与未来 RA 发病风险的关系。在这个研究中,实验组就是在随访过程中发生 RA 的患者(n=183),对照组则是剩下的人群(n=9529),两者的样本量可谓相差甚远。但是就这样一个不“均衡”的研究,却能“堂而皇之”地发表在大名鼎鼎的 BMJ 上,因为这样的研究设计才是真实世界的研究!

     

    众所周知,在队列研究中,一般采用 Kaplan-Meier 法和 Cox 模型去分析暴露因素与结局事件之间的关系,通过 Cox 模型中的风险比(HR)来反映暴露因素与结局事件之间的关系密切程度。HR 具有极为重要的临床价值,因为它直接反映了暴露因素与结局事件的关联性。比如:与 RF<25 IU/ml 的患者相比,RF>100 IU/ml 的个体的 HR 为 5,其对应的临床解释为:RF>100 IU/ml 的个体在未来三十年内发生 RA 的风险是 RF<25 IU/ml 的人群的 5 倍。

     

    在 Cox 模型中,HR 在很大程度上受样本构成比的影响。假如在上述研究中,我们刻意将实验组和对照组的比例控制在 1:1(采用巢式病例对照研究的模式),当然也能用 Cox 模型算出一个 HR,但是这个 HR 显然不能外推,不能用于临床实践,因为这个 HR 是经虚拟世界的研究出来的,在这个虚拟世界中,RA 和对照组的构成比是 1:1,即有一半的研究对象在随访过程中发生了 RA!而在真实世界中,在三十年的随访过程中,发生 RA 的仅为少数。

     

    3、基于回顾性资料的观察性研究或诊断准确性试验也应该尽量体现真实世界

     

    前面两个例子都是基于前瞻性资料的研究,在这些研究中,真实世界尚未开始,因为研究者可以采用各种方法去确保研究对象、研究过程接近于真实世界。但是如果是基于回顾性资料的研究,真实世界早已一去不复返,又该怎么办呢?笔者认为,即使是基于回顾性资料的研究,也应该尽量将研究设计得接近真实世界。

     

    笔者以 2015 年发表在 Am J Cardiol(2015; 115:57-61.)上面的一篇基于回顾性资料的队列研究来谈谈如何在此类研究中体现真实世界。研究者欲研究中性粒细胞/淋巴细胞比值(NLR)与心力衰竭患者预后的关系,因此从所在医院的电子病历库中提取 2007 年至 2010 年期间求治于克利夫兰诊所的所有进展期心力衰竭患者的病历资料,共计 549 份。进一步分析后,发现其中有 22 份病例上没有 NLR 的结果,因此只能对剩下的 527 份病例进行分析。研究者通过社保系统查询到了这 527 名研究对象的远期预后,发现在随访期间共有 121 例患者接受了心脏移植,158 例患者死亡。经过一系列统计分析后,作者发现基线 NLR 与患者的远期预后密切相关,NLR 大于 5.4 的患者,发生全因死亡的风险是 NLR 小于 3 的患者的 2.16 倍。

     

    这是一项基于回顾性资料的队列研究(回顾性队列研究),从中我们可以看出,为了保证研究对象接近于真实世界,作者可谓煞费苦心!最重要的措施就是纳入所有病例,向读者和审稿人传递一个信息:虽然我们的研究不是真实世界的研究,但是我们想了很多办法去回溯真实世界,目前的研究对象和真实世界已经很接近了。的确,在 549 份病例中,只遗漏了 22 份病例,其对结果的影响是很小的。

     

    国内杂志上刊登的很多研究,往往没有花笔墨去介绍研究是否接近于真实世界,只是轻描淡写地写一句“选取某段时间在医院就诊的患某种疾病的患者 200 名”。问题在于:这 200 名患者是如何获得的?随机选取还是随意选取?能否代表真实世界中这个疾病的状况呢?

     

    4、总结

     

    “均衡”原则主要是针对干预性研究提出来的,如果研究者开展的是观察性研究或者诊断性试验,则没有必要遵循这一原则。观察性研究和诊断准确性试验最重要的是要体现真实世界,即实验组和对照组应该是自然形成的,无需刻意将其比例控制在 1:1!

    http://mp.weixin.qq.com/s?__biz=MzA4MzU2NjUyNA==&mid=403622821&idx=5&sn=c4a6f1c1abba84ecfe01df963892b3b2&scene=21#wechat_redirect

    转载于:https://www.cnblogs.com/shuaihe/p/6592893.html

    展开全文
  • 对照组: 施以旧模型的训练集合; 划分原则: 分离目标群体,然后将目标群体对半分开,一半做实验组,一半做对照组; 用一个例子演示划分: 问题需求:利用A/B测试验证在特定群体(青年人)中新的推荐模型A的效果; ...

    难度系数(5分制): 2
    实验组: 施以新模型的训练集合;
    对照组: 施以旧模型的训练集合;
    划分原则:
    分离目标群体,然后将目标群体对半分开,一半做实验组,一半做对照组;
    用一个例子演示划分:
    问题需求:利用A/B测试验证在特定群体(青年人)中新的推荐模型A的效果;
    划分样例:标记所有青年人,按照所有青年人ID对半划分对比效果;
    错误划分:
    全部用户对半划分(没有区分目标群体);
    划分目标用户中的一半人数为实验组,剩下全为对照组(将导致对照组结果被稀释);
    全体用户分为两半,从前一半中划分目标群体为实验组,剩下一半均为对照组(将导致对照组结果被稀释,存在偏差);

    展开全文
  • 我们有一T处理单元和C控制单元,总共N = T + C单元 我们形成n对,其中n ≤ T, n ≤ C 每对由一个处理单元和一个控制单元组成 通常,我们限制每个处理的单元在所有对中最多显示一次 可选地,我们可以以相同的方式...
  • 下面设立一个对照组做个小测试,对比一下两者( 我的环境是xp+VMWARE+UBUNTU+GCC ):   source code: char str1[] = "hhhhhh"; char str2[10] = "asd"; char str3[10] = "asdasdasda"; printf(...

    很适合新手(我也是新手),涉及知识点有sizeof、strlen、堆空间、栈空间、编译原理(都很肤浅)。

     

    最初不打算写这个的,只为学习一个小知识点,但就是因为思维太发散偷笑,就把整个主题都改了——谁说只能以专业知识为主题的?

    至于为什么弄这么个题目,完全有感而发,个中细节,且听我细细道来~~

     

    因为很久不用,记忆模糊,被sizeof和strlen搞得稍微糊涂。

    现在对比一下两者区别:

     

    性质:前者是操作符,后者是库

     

    功能:前者可对type操作,后者只能对以'\0'结尾的string(包括数组char[])操作。

     

    之前造成我误解的就在这,sizeof一个字符串或者整形数组,是要乘以type大小的,而strlen是单纯的字符串长度,而恰巧,sizeof(char)又是1,二者就更容易混淆了。

     

    下面设立一个对照组做个小测试,对比一下两者(我的环境是xp+VMWARE+UBUNTU+GCC):

     

    source code:

            char str1[] = "hhhhhh";
            char str2[10] = "asd";
            char str3[10] = "asdasdasda";
    
            printf("the length of str1 is %d\n",strlen(str1));
            printf("the sizeof   str1 is %d\n",sizeof(str1));
            printf("the length of str2 is %d\n",strlen(str2));
            printf("the sizeof   str2 is %d\n",sizeof(str2));
            printf("the length of str3 is %d\n",strlen(str3));
            printf("the sizeof   str3 is %d\n",sizeof(str3));
    
    
    //字符串结束符为'\0',下面输入的下标为结束符应在的位置:
            printf("the end of str1 is %d\n",str1[6]);
            printf("the end of str2 is %d\n",str2[3]);
            printf("the end of str3 is %d\n",str3[10]);
    
    //列出三个数组所占用地址空间范围。
            printf("the address of str1[0] is %p\n",&str1[0]);
            printf("the address of str1[6] is %p\n",&str1[6]);
            printf("the address of str3[0] is %p\n",&str3[0]);
            printf("the address of str3[9] is %p\n",&str3[9]);
            printf("the address of str2[0] is %p\n",&str2[0]);
            printf("the address of str2[9] is %p\n",&str2[9]);
    
    
    

     

     

     

    Resault Print:
    
    the length of str1 is 6
    the sizeof   str1 is 7
    //没有把申请的空间占满的前提下:sizeof作为空间大小,是计算了那个结束符的。
    the length of str2 is 3
    the sizeof   str2 is 10
    //str2直接定义了大小10:sizeof完整的显示了空间大小,而strlen只给出了字符串的长度3
    the length of str3 is 16
    the sizeof   str3 is 10
    //看到str3的长度已经明显不对了,按要求是10,此处达到了16
    
    the end of str1 is 0
    the end of str2 is 0
    the end of str3 is 104
    //因为涉嫌出界,所以这个str3[10]不是结束符0而是(int)104,用%c控制输出是h,这个h是巧合么?其实根本就是str1中的内容~!
    //比较简单的方法,如果把str1中的内容改了(例:"dddddd"),发现相应str3[10]也变了
    //注意两点:首先,str3[10]是str1中的h;其次,str1的长度是6,str3的(strlen认为的)“长度”是16,正好是10+6,
    //加上sizeof(str3)为10这个事实,这验证了strlen是只认'\0'结束符的。
    
    //至于原因
    //因为这些是栈空间的分配了吧,连续分配的,并且向低地址扩展(其实至少在本例,向低地址扩展的说法是错的,
    //这种错误是基于“windows下栈空间是向低地址空间扩展的”产生的,后边会解释,这只是思考的一个过程,必然有不完善),
    //所以str3出界了(相对高地址)以后是str1,至于为什么str2跳了过去。
    
    the address of str1[0] is 0xbf919755
    the address of str1[6] is 0xbf91975b
    the address of str2[0] is 0xbf919741
    the address of str2[9] is 0xbf91974a
    
    //这个规律很容易理解,在数组内,因为原则上,下标不过就是数组起始地址+“i”,所以自然是递增的。
    //但是数组之间(也就是各变量之间)的地址是递减的。(同上,这些想法在本例都错了,后边会有验证)
    //总结起来就是一增一减
    
    the address of str3[0] is 0xbf91974b
    the address of str3[9] is 0xbf919754

     

    这结果里,其实是有bug的:

     

    回过头去,把str2改长,不管怎么改,发现了一个非常奇怪的规律:str2地址最低,str3其次,但是str3的尾部总能“接壤”str1的头部。

    其实不难想到,本例有个特别之处就是:str2和str3是声明时直接定义了固定长度,str1是用一个字符串来定义的

     

    想起来了一个概念,其实就是栈空间和堆空间的区别?(其实不是堆,后边还会解释,这里应该只是编译器优化了一下顺序)

     

    回头去在str2之前定义另一个占用堆空间的字符串,最好在后边也试一个,按编译器的一些特性——比如栈空间在编译时先分配(这也应了栈空间地址比堆空间地址低了,因为编译时先分配的嘛)——在str2与str3的前边和后边定义变量应该是一样的效果,重新修改部分代码,声明定义改成:

            char str1[] = "dddddd";
            char str4[] = "hello";
            char str2[10] = "asdasdads";
            char str3[10] = "asdasdasda";
            char str5[] = "world";
    

    地址输出语句:

            printf("the address of str1[0] is %p\n",&str1[0]);
            printf("the address of str1[6] is %p\n",&str1[6]);
            printf("the address of str4[0] is %p\n",&str4[0]);
            printf("the address of str4[5] is %p\n",&str4[5]);
            printf("the address of str2[0] is %p\n",&str2[0]);
            printf("the address of str2[9] is %p\n",&str2[9]);
            printf("the address of str3[0] is %p\n",&str3[0]);
            printf("the address of str3[9] is %p\n",&str3[9]);
            printf("the address of str5[0] is %p\n",&str5[0]);
            printf("the address of str5[5] is %p\n",&str5[5]);
    //长度为5的字符串之所以下标也到5,是考虑了结束符占用的一个地址。 
    

    打印结果为:

     

    the address of str1[0] is 0xbfc4e1e9
    the address of str1[6] is 0xbfc4e1ef
    
    the address of str4[0] is 0xbfc4e1f0
    the address of str4[5] is 0xbfc4e1f5
    
    //中间的str2和str3占用栈空间,其余堆空间(堆空间的判断和定义暂时持保留意见)
    the address of str2[0] is 0xbfc4e1d5
    the address of str2[9] is 0xbfc4e1de
    the address of str3[0] is 0xbfc4e1df
    the address of str3[9] is 0xbfc4e1e8
    
    the address of str5[0] is 0xbfc4e1f6
    the address of str5[5] is 0xbfc4e1fb

    那么,堆和栈区分开了(关于本例是不是用到了堆空间,还是全是栈?还是持保留意见,详见后边分析),那么在栈内,数组和普通变量是否也要分开呢?答案也是肯定的

    验证如下:

    各变量和数组变量总的定义如下:

            int i = 10;
            long  int l = 10;
            long long int ll = 100;
            double d = 2.2;
            float f = 1.1;
            char c = 'c';
            short s = 2;
            int before = 4;
            char str1[] = "dddddd";
            char str4[] = "hello";
            int middle = 5;
            char str2[10] = "asdasdads";
            char str3[10] = "asdasdasda";
            char str5[] = "world";
            double end = 2.2;
    
    

     

    (int)before、(int)middle和(double)end穿插数组前中后,打印输出的代码省略:

    结果:数组的地址全部大于普通变量,验证!

    (数组地址的打印结果也省略,因为重点是有新发现)

     

    the address of i is 0xbfc5e90c
    the address of l is 0xbfc5e910
    the address of ll is 0xbfc5e8f0
    the address of d is 0xbfc5e8f8
    the address of f is 0xbfc5e914
    the address of c is 0xbfc5e924
    the address of s is 0xbfc5e922
    the address of before is 0xbfc5e918
    the address of middle is 0xbfc5e91c
    the address of end is 0xbfc5e900

     

    通过观察可以发现两个小规律,就是:

    1.各变量也是分类“组团”(比如两个double型的地址连着——尾数8f8和900)往栈里插的,这很合乎逻辑,因为好管理嘛,编译器肯定有一定规则。

    2.哪种类型的变量地址更低,不是定义顺序说了算的。和组团插入一个思路——编译器按固定规则去找(相信编译原理都有相关解释,不过我现在不了解)

     

    到此,问题似乎基本解决?

     

    不过,关于堆和栈的区分,可能还是不准确~!如果简单的把“动态”分配大小的

    char str1[] = "hhhhhh";

    当做占用堆空间,而把“固定长度”固定大小的

    char str2[10] = "asdasdads";

    当做占用栈空间,那么至少知道malloc是堆空间的:

    char *str = malloc(sizeof(char)*10);

     

    malloc分配的空间地址也应该和所谓的占用堆空间的str1、str4、str5地址很近才对,可是试过了才知道,

    <span style="color:#000000">the address of str[0] is 0x8220008
    
    the address of str[10] is 0x8220012
    the address of str1[0] is 0xbf8071b9
    the address of str1[5] is 0xbf8071be</span>
    
    

     

    这个malloc分配的空间,不仅不和他们沾边,和整个程序中所有变量的地址都相去甚远。

    再联想各种单变量被编译器各种组合各种排序,推断各字符数组(之前认为的堆空间和栈空间两种数组),不过就是对定义过长度和没定义(也许算隐含定义)过长度的数组的一种整合排序,总体来讲他们都在栈中,都是自动分配,这样想比较靠谱。之前的误区是字符串常量的问题,不过并不是C++,不是直接用指针指向字符串常量,都是定义的char数组,所以char数组之间互相是没有差别的,其实地址也挨得很近,只不过被编译器优化排序了。不同类型也是同理,都是被编译器优化了一下排列顺序。

    字符串常量自身应该在常量区,不同于字符数组。

     

     

    事实上,linux下的栈空间增长顺序还是没能准确说出来,也许之前以为的正序,反过来看就是倒序了?谁知道到底是数组优先还是普通变量优先。不过至少,在同类型中,还是按定义顺序而增长地址的。

    没有指导理论,光凭规律总结,那么假设堆、栈空间就是这样分开的,根据空间的“抱团”分区原则,结合的这么紧密,那么除了malloc分配的空间,几乎可以肯定其他都在栈空间了~~~

     

     

    最后~忘了静态存储区(static storage area)了,区分于堆区和栈区,这又是一个单独的区域,保存自动全局变量和static变量(static也包括全局和局部)。静态区的主要特征是生命周期长,可以超越局部函数体对栈变量的限制,而局部栈变量生命周期是很短的。

    一小例:

     

    #include<stdio.h>
    #define _PRINT_H_
    int global = 100;
    
    main(){
            int stack = 10;
    //自由设置下面几个堆区的大小,查看分配规律
            char *heap1 = (char*)malloc(10*sizeof(char));
            char *heap2 = (char*)malloc(1*sizeof(char));
            char *heap3 = (char*)malloc(1000*sizeof(char));
            char *heap4 = (char*)malloc(10*sizeof(char));
    
            int i = 0;
            {
                    static  int localStatic = 6;
                    int localStack =8;
    #ifdef _PRINT_H_
            printf("the address of localStack  is %p\n",&localStack);
            printf("the address of localStatic  is %p\n",&localStatic);
    #endif
            }
    #ifdef _PRINT_H_
            printf("the address of global is %p\n",&global);
            printf("the address of stack is %p\n",&stack);
            printf("the address of heap1 isn't %p\n",&heap1);
    //将由malloc分配的(由heap1指向的)空间命名为heap area1
            printf("the address of heap area1 isn't %p\n",&heap1);
            printf("the address of heap area1 is %p\n",heap1);
            printf("the address of heap area2 is %p\n",heap2);
            printf("the address of heap area3 is %p\n",heap3);
            printf("the address of heap area4 is %p\n",heap4);
    #endif
    }
    
    打印结果:
    the address of localStack  is 0xbf841a54
    the address of localStatic  is 0x804a01c
    the address of global is 0x804a018
    the address of stack is 0xbf841a4c
    the address of heap1 isn't 0xbf841a50
    //申请堆再小,也要隔开0x10,也许堆中划分块最小就是16byte。
    the address of heap area1 is 0x8e30008
    the address of heap area2 is 0x8e30018
    the address of heap area3 is 0x8e30028
    the address of heap area4 is 0x8e30418
    
    
    

    可以看到,其实分了三个区域,global和localstatic是一起的,静态存储区(static storage area);

     

    localstack和各种其他自定义变量(省略了,随便几个int i)是栈区(stack area);

    heap1和heap2等指向的malloc分配区域是堆区(heap area),有些乱,但是通过地址可以看出是属于一个范围内。。注意heap1和heap2本身是存在栈区的,他们是指针。

    ps:根据malloc的分配方式的特性(先申请,按大小找空闲空间,一般是找链表,最先找到满足需求的空间、或者找到满足要求的最小空间分配,从上例可以看到最小分配的堆空间可能是16byte),他们有可能是不连续的,但是至少有很大的可能,地址比较近的(相比栈空间地址,就近太多了),如果分配的空间本身又不大,看起来就更连续了。

    另外,根据局部变量覆盖全局变量的原则,即使把变量“stack”和“localstack”起同样的名字,他们也是两个地址,可试~

    ===================================================================================================================================

    CONCLUSION:虽然“结论”不停的被推翻,并且最后的也不一定权威,但是至少一些发现的很多规律还是没错的,至少在本环境内。

    串了这么多知识点,结果还是不够用,还有一大堆知识点要学习。所以说,比较合理的对照组设计能带出很多问题,也是我之前修改u-boot时发现的,有时候,犯一个错误,能帮你发现并避免另一个错误!编程时遇到的巧合太多了,不设立合理的对照组根本无法发现,不深挖细节根本无法理解。另外,虽然出现的意外能够应付,但也算是小吃一堑,这次对照组设立其实是简化了,在开始就能根据所要测试的N个条件设立2的N次方个实例的话会省很多功夫,很多东西也更为直观。

     

    除了对照组的设立,能从单纯对比strlen与sizeof的单位,发展到研究strlen对结束符的判定,再到观察对比数组地址,到最后的堆栈空间,还有windows与linux栈指针的增长方向,堆栈等存储区域划分,串烧这么多知识点,最重要的还是举一反三、顺藤摸瓜的发散思维方式,鄙人觉得这对学习,尤其是学习比较复杂、有无限复杂知识链条的软件开发来说是非常有用的技能。所以才有了这个主题。

     

     

    不过有些问题既然发现了,后续还是要学习研究的,技能也需要提升:比如gdb、objdump等工具的使用,windows下栈的增长是向下还是向上,这个内存分配的具体阶段和过程,编译原理相关知识的掌握。

    稍后我会进行相关方面的学习和探讨~~~~~~~~~

     

    另外,觉得一大串打印有些乱的,可以弄个debug宏。

     

     

     

    展开全文
  • keyCode对照表及JS监听组合按键

    万次阅读 2017-03-28 19:21:51
    keyCode对照表 字母和数字键的键码值(keyCode) 按键 数字键盘上的键的键码值 功能键的键码值 控制键的键码值 多媒体的键码值 onkeyup的缺陷处理 JS监听组合按键 拓展 shortcuts

    keyCode对照表

    1、 字母和数字键的键码值(keyCode)

    按键键码按键键码按键键码按键键码
    A65J74S83149
    B66K75T84250
    C67L76U85351
    D68M77V86452
    E69N78W87553
    F70O79X88654
    G71P80Y89755
    H72Q81Z89856
    I73R82048957

    2、数字键盘上的键的键码值

    按键键码按键键码
    0968104
    1979105
    298*106
    399+107
    4100Enter108
    5101-109
    6102.110
    7103/111

    3、功能键的键码值

    按键键码按键键码
    F1112F7118
    F2113F8119
    F3114F9120
    F4115F10121
    F5116F11122
    F6117F12123

    4.、控制键的键码值(keyCode)

    按键键码按键键码按键键码按键键码
    BackSpace8Esc27Right Arrow39-_189
    Tab9Spacebar32Down Arrow40.>190
    Clear12Page Up33Insert45/?191
    Enter13Page Down34Delete46`~192
    Shift16End35Num Lock144[{219
    Control17Home36;:186/|220
    Alt18Left Arrow37=+187]}221
    Cape Lock20Up Arrow38,<188'"222

    5、多媒体键的键码值(keyCode)

    按键键码
    音量加175
    音量减174
    停止179
    静音193
    浏览器172
    邮件180
    搜索170
    收藏171

    onkeyup的缺陷处理

    场景说明:在html的input框中限制指定内容输入,例如只允许输入数字(其他情况都是正则表达式变化)。方法很多,以如下代码为例:

    <!DOCTYPE>
    <html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    <input type="text" onkeyup='this.value=this.value.replace(/[^\w_]/g,"");'/>
    </body>
    

    代码缺陷:上边代码中,input框只能输入数字(本文想阐述的不是这个),但是该方法有个缺陷,当用户输入数字后想修改时,键盘的←键无法使光标向左移动,即便鼠标点击,使光标到指定位置,在按下键盘任意键修改时,光标还是会跑到最右端。
    解决方案及原理:onkeyup中代码是键盘每一次按下放开之后将input框中的value按照正则处理,不符合正则的替换成“”,也就是去掉,具体可以查看js的replace函数。那么上述代码缺陷就可以从keyCode入手。代码如下

    <!DOCTYPE>
    <html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    <input type="text"  onkeyup='if(event.keyCode!=8 && event.keyCode!=37 && event.keyCode!=16 && event.keyCode!=20 && event.keyCode!=39 && (event.keyCode<48 || event.keyCode>105) && (!event.shiftKey && event.keyCode != 189))this.value=this.value.replace(/[^\w_]/g,"");'/>
    </body>
    

    代码说明:上边event.keyCode后边的数字代表的是键盘对应的按键,可以查看上边的keyCode对照表。上边代码中是按下键盘上数字按键,Backspace按键,←,→按键时,不作正则处理,从而避免了第一段代码的问题。

    JS监听组合按键

    组合按键一般分以下两种:
    两位组合建,如:ctrl(cmd)+ 其他按键,alt+其他按键,shift+其他按键
    三位组合键,如:ctrl(cmd)+ shift + 其他按键,Ctrl(cmd)+ alt + 其他按键
    在组合键中,js的event中有以下几种属性:ctrlKey(metaKey)、altKey、shiftKey
    以下以按下Shift+1组合键为例(其他的类似):

    <!DOCTYPE>
    <html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    <input type="text" onkeyup="test()"/>
    </body>
    <script>
    function test(){
    	if(event.shiftKey && event.keyCode == 49){
    		alert(1);
    	}
    }
    </script>
    
    

    代码说明:执行上述代码后,按下组合键Shift+1在input框中输出!同时,会alert出1。但是个人在测试过程中有个疑问,就是组合键的Shift+其他按键,js如何区分中英文的。

    拓展 shortcuts

    shortcuts.js可以在网页中增加组合按键,使组合按键更丰富。
    具体使用方法,及更多信息,可以在下面下载链接中下载之后,尝试下。
    点我,shortcuts.js下载地址

    展开全文
  • ,英文称completely random design,是指不加任何条件限制应用随机数字表或随机排列表将观察对象随机地分配到试验组和对照组进行实验观察的一种设计方法,是用 随机化的方式来控制误差变异 ,认为经过随机化处理后,...
  • 车上控制器中英文对照

    千次阅读 2017-03-22 11:08:02
    ABS 防抱死刹车系统(Antilock Brake System) AP 加速踏板(Accelerator Pedal) AC 空调(Air Condition) ...ACC 自适应巡航控制(Adaptive Cruise Control) AEBS 高级紧急刹车系统(Advanced Emergency Braking
  • ASCLL码对照表01(控制字符)

    千次阅读 2018-11-03 09:57:27
    ASCII控制字符 二进制 十进制 十六进制 缩写 可以显示的表示法 名称/意义 0000 0000 0 00 NUL ␀ 空字符(Null) 0000 0001 1 01 SOH ␁ 标题开始 0000 0010 2 02 STX ␂ 本文开始 0000 0011 3 03 ETX...
  • Windows控制面板中英文对照

    千次阅读 2018-09-17 11:09:39
    控制面板项的规范名称 操作中心 Microsoft.ActionCenter 管理工具 Microsoft.AdministrativeTools 自动播放 Microsoft.AutoPlay 指纹识别设备 Microsoft.BiometricDevices Bitlocker驱动器加密 Microsoft....
  • 对照组中,继续进行现有的理疗程序(每周两天,每次45分钟)。 对照组的现有程序未添加任何内容。 改良的阿什沃思量表(MAS),小儿伯格平衡量表(PBBS),躯干控制测量量表(TCMS),1分钟步行测验(1MWT),...
  • 摘要:本文主要介绍进程的基本属性,基本属性包括:进程ID、父进程ID、进程ID、会话和控制终端.
  • 计算机常用算法对照表整理

    千次阅读 2017-07-26 10:58:01
    常用对照:NLP CRF算法: 中文名称条件随机场算法,外文名称conditional random field algorithm,是一种数学算法,是2001年提出的,基于遵循马尔可夫性的概率图模型。 全部对照第一部分、计算机算法常用术语中英...
  • ASSIC表对照

    千次阅读 2017-01-20 13:21:06
    ASSIC码对照表 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 0 NUT 32 (space) 64 @ 96 、 1 SOH 33 ...
  • Linux 用户和用户管理

    千次阅读 2016-08-24 21:29:05
    用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪,并控制他们对系统资源的访问;另一方面也可以帮助用户组织文件,并为用户提供安全性保护。每个用户账号都拥有一个惟一的用户名和各自的口令。用户在...
  • 下面是部分ASCII控制对照表,可以根据自己的需求设置不同的组合按键。 ASCII控制对照表 十进制 十六进制 控制字符 转义字符 说明 Ctrl + 下列字母 0 00 NUL \0...
  • ASCII码对照

    千次阅读 2013-11-13 10:52:26
    ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 0 NUT 32 (space) 64 @ 96 、 1 SOH 33 ! 65 A 97 a 2 STX 34 " 66 B 98 b 3 ETX 35 # 67 C 99 c 4
  • ascii对照

    千次阅读 2016-11-27 23:05:02
    ASCII控制字符 二进制 十进制 十六进制 缩写 名称/意义 0000 0000 0 0x00 NUL 空字符(Null) 0000 0001 1 0x01 SOH 标题开始 0000 0010 2 0x02 STX 本文开始 0000 0011 3 0x03 ETX 本文...
  • ASCll码对照

    千次阅读 2011-10-09 13:45:36
    ASCII码对照
  • ASCILL对照

    千次阅读 2013-11-29 18:34:00
    群分隔符 0001 1110 30 1E RS ␞ 记录分隔符 0001 1111 31 1F US ␟ 单元分隔符 0111 1111 127 ...
  • VC6.0常见英文错误对照

    千次阅读 2014-03-26 14:59:53
     stopping compilation 中文对照:(编译错误)错误太多,停止编译 分析:修改之前的错误,再次编译 fatal error C1004: unexpected end of file found 中文对照:(编译错误)文件未结束 分析:一个...
  • ASCCII 对照

    千次阅读 2009-05-30 10:50:00
    ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符0NUT32(space)64@96、1SOH33!65A97a2STX34”66B98b3ETX35#67C99c
  • Unicdoe【真正的完整码表】对照表(一)

    万次阅读 多人点赞 2013-06-07 22:13:26
    Unicdoe【真正的完整码表】对照表【 点击 】 开源工程ZipArchive,压缩中文文件名乱码问题【 点击 】 base64加密,解密,encode,decode,编码详解+实现【 点击 】  网络传输文本,urlEncode和urldecode的iOS实现...
  • 如果在转换中你需要更多的控制,在iOS4.1已经以后的版本中,你可以使用 asset reader  和 asset writer 对象串联的一个一个的转换。例如你可以使用这些对象选择在输出的文件中想要表示的轨道,指定你自己的输出...
  • ASCII 码对照

    万次阅读 多人点赞 2019-03-08 01:30:35
    ASCII(American Standard Code for Information Interchange,美国信息互换标准...ASCII 包含了 33 个控制字符(具有某些特殊功能但是无法显示的字符)和 95 个可显示字符。共收录了 128 个字符,用一个字节中较低...
  • 计算机专业术语对照

    千次阅读 2019-01-05 19:31:12
    计算机专业术语对照 A abstraction layer,抽象层 access,获取,存取 acoustic coupler,声音耦合器 Active Directory,活动目录 Acyclic Dependencies Principle,非循环依赖原则(ADP) acyclic digraph...
  • Batch Normalization论文翻译——中英文对照

    千次阅读 多人点赞 2017-09-28 15:59:10
    文章作者:Tyan 博客:noahsnail.com &nbsp;|&nbsp; CSDN &nbsp;|&nbsp; 简书 ...声明:作者翻译论文仅为学习,如有侵权请联系作者删除博文,谢谢!...Batch Normalization: Acceleratin...
  • 算法常用术语中英对照

    万次阅读 2018-11-19 23:12:06
    算法常用术语中英对照 Data Structures 基本数据结构 Dictionaries 字典 Priority Queues 堆 Graph Data Structures 图 Set Data Structures 集合 Kd-Trees 线段树 Numerical Problems 数值问题 Solving Linear ...
  • 常用ASCLL码对照

    千次阅读 2018-04-25 18:10:24
    常用对照表 FeedbackHTTP Content-typeHTML转义字符RGB颜色参考ASCII对照表HTTP状态码详解运算符优先级TCP/UDP常见端口参考网页字体参考ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符0NUT32(space...
  • 监控过程-项目管理

    千次阅读 2018-12-18 10:49:30
    监控过程包含跟踪、审查和调整项目进展与绩效,识别必要的计划变更并启动相 ...对照项目管理计划和项目绩效测量基准监督正在进行中的项目活动 对导致规避整体变更控制成配管理的因素加影响确保只有经批准的变更才能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,266
精华内容 16,106
关键字:

对照组控制组