首页 > 其他分享 >[20230922]dc命令复杂学习3.txt

[20230922]dc命令复杂学习3.txt

时间:2023-10-07 21:26:37浏览次数:35  
标签:20230922 la -- bc dc 堆栈 txt

[20230922]dc命令复杂学习3.txt

1.问题提出:
--//前一段时间简单学习了dc,累加的例子:
$ cat a.txt
1111
2222
3333
4444

$ cat a.txt | dc -f - -e "[+z1<r]srz1<rp"
11110

$ dc -f a.txt -e "[+z1<r]srz1<rp"
11110

--//实际上如果累加数据量很大,这样的执行效率很低的,因为每次都要判断堆栈是否还有数据(z命令,队列越长执行效率越低)
--//实际上开始我就想,如果根据开始插入堆栈的数量生成对应的数量的字符'+' ( 注:生成+的数量等于插入堆栈的数量-1),
--//那不是更加简单呢? 自己再做一些尝试:

2.尝试实现:
$ dc -f a.txt -e "zp"
4

$ (cat a.txt ; seq 2 $(dc -f a.txt -e "zp"| tr -d '\r') | xargs -IQ echo + ; echo pq ) | dc -f -
11110
--//注:我的测试在cygwin下,dc -f a.txt -e "zp"的输出结果多了1个\r字符,必须删除它。

--//我上面的例子使用seq 生成对应+,如何全部使用dc实现呢?
--//先做z操作插入堆栈的数量,然后产生对应数量的+就可以了.改写如下:

$ cat a.txt | dc -f - -e "z [+  la  1 - sa la  1<r  ]sr sa la 1<r pq"
11110

$ dc -f a.txt -e "z [+  la  1 - sa la  1<r  ]sr sa la 1<r pq"
11110

--//简单解析,不作记录我估计以后自己都看不懂代码表示怎么:
--//z 插入当前堆栈的数量到堆栈顶部,在该例子是4.
--//[+  la  1 - sa la  1<r  ]sr 将[]括号的内容保存到寄存器r.以后循环执行里面的内容,同时出堆栈.
--//sa  保存堆栈顶部的值到寄存器a,同时出堆栈.这里寄存器a保存的值开始是4.
--//la  把寄存器a的内容放入堆栈,这里寄存器a=4的值放入堆栈.
--//1<r 插入1到堆栈 做比较如果1 < 4 ,调用寄存器r的内容执行.形成递规.注意执行<时,堆栈顶部的比较的2个值同时出堆栈.

--//单独解析: [+  la  1 - sa la  1<r  ]
--// +   对当前堆栈顶部的2个数值做一次加法运算.
--// la  把寄存器a的内容放入堆栈.
--// 1 - 把1放入堆栈.并且与前面放入寄存器a的内容放入堆栈的值做减法运算.也就是做循环.
--// sa  保存堆栈顶部的值到寄存器a,同时出堆栈.
--// la  把寄存器a的内容放入堆栈
--// 1<r 插入1到堆栈 做比较如果1 < 寄存器a的值 ,调用寄存器r的内容执行.形成递规.注意执行<时,堆栈顶部的比较的2个值同时出堆栈.  

--//加入一个显示整个堆栈的命令f就很清楚了.

$ dc -f a.txt -e "z [  +  la  1 - sa la   1 f 61P 61P 61P 61P 10P <r ]sr sa la  1 f 61P 61P 61P 61P 10P <r pq"
1
4
4444
3333
2222
1111
====
1
3
7777
2222
1111
====
1
2
9999
1111
====
1
1
11110
====
11110


--//如果算法改一下,要输出对应数量的字符+,该如何操作呢?
--//+的ascii码=43 ,注:在vim下在移动到+字符下按ga,在vim的提示行显示对应ascii码值(10,16,8进制). 空格的ascii=32,换行的
--//ascii=10.

$ cat a.txt | dc -f - -e "z [43P  la  1 - sa la  1<r  ]sr sa la 1<r "
+++

--//注意我的以上测试并没有改变dc插入堆栈的值.你最后加入f显示整个堆栈.
$ cat a.txt | dc -f - -e "z [43P  la  1 - sa la  1<r  ]sr sa la 1<r 10P f"
+++
4444
3333
2222
1111

--//使用空格分开呢?
$ dc -f a.txt -e "z [43P 32P  la  1 - sa la  1<r  ]sr sa la 1<r "
+ + +

--//这样也可以写成如下:

$ (cat a.txt ; dc -f a.txt -e "z [43P 32P  la  1 - sa la  1<r  ]sr sa la 1<r 10P"; echo pq ) | dc -f -
11110

3.测试执行效率:

--//测试这样改进的执行效率如何?家里没有linux的环境,使用cygwin 在windows下测试:
--//cygwin的执行效率并不是很高.

$ seq 100000 > b.txt

$ time dc -f b.txt -e "[+z1<r]srz1<rp"
5000050000

real    0m10.630s
user    0m0.000s
sys     0m0.015s

$ time dc -f b.txt -e "z [+  la  1 - sa la  1<r  ]sr sa la 1<r pq"
5000050000

real    0m0.648s
user    0m0.000s
sys     0m0.015s
--//明显快了一大截。测试使用bc看看

$ paste -sd+ b.txt | bc -l
(standard_in) 1: Function too big.

--//拚接为1行时太长了,实际上操作bc 1行接受的行长度存在限制,看下面的测试.

$ time ((sed -e 's/^/s+=/g'  b.txt ; echo s ) | bc -l)
5000050000

real    0m0.658s
user    0m0.061s
sys     0m0.045s

--//两者相差不大。
--//顺便测试一行最大容纳多少字符。

$ head -2499 b.txt | paste -sd+  | bc -l
3123750

$ head -2500 b.txt | paste -sd+  | bc -l
(standard_in) 1: Function too big.

$ head -2500 b.txt | paste -sd+  | wc
      1       1   11393

$ head -2499 b.txt | paste -sd+  | wc
      1       1   11388

--//我估计是超出bc一行能输入的字符数量的限制。因为head -2500 b.txt | paste -sd+可以正常执行。

$ time (head -2499 b.txt | paste -sd+  | bc -l)
3123750

real    0m0.535s
user    0m0.015s
sys     0m0.030s

$ time (head -2499 b.txt |  dc -f - -e "z [+  la  1 - sa la  1<r  ]sr sa la 1<r pq")
3123750

real    0m0.355s
user    0m0.000s
sys     0m0.046s

--//还是dc略胜一筹。我估计是因为bc的执行过程中使用paste拼接的原因。

$ head -2499 b.txt | paste -sd+ > c.txt
$ echo quit >> c.txt
$ time bc -l c.txt
3123750

real    0m0.146s
user    0m0.000s
sys     0m0.000s

$ head -2499 b.txt > c.txt
$ (dc -f c.txt -e "z [43P la  1 - sa la  1<r  ]sr sa la 1<r "; echo pq ) >> c.txt
$ time dc -f c.txt
3123750

real    0m0.192s
user    0m0.000s
sys     0m0.031s

--//在写好计算公式的情况下,两者差不多,bc也许更快一些。

4.补充说明:
--//测试看看dc 以及bc 一行能接受字符的限制的具体数值.
$ head -2499 b.txt | paste -sd+ > c.txt
$ time bc -l c.txt
3123750
quit

real    0m2.148s
user    0m0.000s
sys     0m0.000s

--//尝试修改c.txt 增加文件第一行字符数量.仅仅增加1个字符就出现如下错误。

$ time bc -l c.txt
quit
c.txt 2: Function too big.

real    0m2.140s
user    0m0.015s
sys     0m0.000s

$ wc  c.txt
    1     1 11389 c.txt

$ ls -l c.txt
-rw-r--r-- 1 Administrator None 11389 2023-09-23 20:29:27 c.txt
--//文件是linux格式,删除最后1个字符0x0a以及插入的字符,bc的一行输入缓存是11387字符。
--//多次尝试我发现实际上情况比我前面的测试要复杂:
$ head -5 e.txt
1
1
1
1
1

--//建立一个全部是数字1的文件。
$ wc  e.txt
40000 40000 80000 e.txt
--//共40000行。

$  paste -sd+ e.txt | bc -l
(standard_in) 1: Function too big.

$ head -8192 e.txt | paste -sd+ |bc -l
8192

$ head -8193 e.txt | paste -sd+ |bc -l
(standard_in) 2: Function too big.

$ head -8194 e.txt | paste -sd+ | wc
      1       1   16388
--//放弃探究,有点离题了。
--//测试dc的情况:

$ head -2499 b.txt | paste -sd' ' > d.txt
$ ls -l d.txt
-rw-r--r-- 1 Administrator None 11388 2023-09-23 20:32:51 d.txt

$ (dc -f d.txt -e "z [43P la  1 - sa la  1<r  ]sr sa la 1<r "; echo pq ) >> d.txt
$ time dc -f d.txt
3123750

real    0m0.181s
user    0m0.000s
sys     0m0.015s

--//增加1个字符看看,修改最后的2499 为 24991。

$ time dc -f d.txt
3146242

real    0m0.214s
user    0m0.000s
sys     0m0.015s

--//3123750 - 2499 +24991 = 3146242 , 结果正确。

$ paste -sd' ' b.txt > d.txt
$ (dc -f d.txt -e "z [43P la  1 - sa la  1<r  ]sr sa la 1<r "; echo pq ) >> d.txt
$ time dc -f d.txt
5000050000

real    0m0.461s
user    0m0.000s
sys     0m0.015s

$ ls -l d.txt
-rw-r--r-- 1 Administrator None 688897 2023-09-23 20:41:58 d.txt

$ cat d.txt | dc -f -
5000050000

--//dc没有这个限制,甚至bash shell命令行的限制。
--//bash shell命令行的限制我记忆里各个版本不一致,好像最大可以达到128K,有一些甚至2621440。我不测试了。

$ getconf -a | grep -i arg
_POSIX_ARG_MAX                      4096
NL_ARGMAX                           9
ARG_MAX                             32000

$ getconf ARG_MAX
32000

--//我的cygwin测试环境32000.

标签:20230922,la,--,bc,dc,堆栈,txt
From: https://www.cnblogs.com/lfree/p/17747499.html

相关文章

  • Exception in thread "main" java.lang.UnsupportedClassVersionError: org/example/J
    问题描述使用hadoop在虚拟机里面运行打包的程序出错:问题解决真的服了,貌似是jdk的版本啥的问题,搜了好多,就是解决不了,求助求助啊!......
  • 实践一下前几天的wordCount案例
    1、自己准备一个数据量比较小的txt文件然后将其上传到虚拟机本地:之后上传到hdfs里面:2、编写代码1、引入相关依赖<dependencies><!--https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common--><dependency><groupId>org.a......
  • 初始化LTDC
    1,初始化GPIO2.LTDC初始化voidBSP_LTDC_Init(void){/*LTDC像素时钟域通过PLLSAI进行配置*/RCC_PLLSAIConfig(200,20,2);RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div4);RCC_PLLSAICmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY)==RESET......
  • 题解 P9701【[GDCPC2023] Classic Problem】
    题如其名,确实挺经典的。我们称边权在输入中给定的边为特殊边,其它边为平凡边。称特殊边涉及到的点为特殊点,其它点为平凡点。显然,对于连续的若干平凡点\([l,r]\),他们内部的最优连边方式就是连成一条链,花费\(r-l\)的代价。我们先把这样的代价加到答案中,然后将极长连续平凡点缩成......
  • 【Citrix篇】2-Citrix ADC/Gateway远程代码执行XSS漏洞修复方案
    、一、前言    最近我们根据修复了CVE-2023-3519漏洞,仍有部分安全厂商扫描出XSS漏洞,我们从400获悉该XSS漏洞不存在风险的,但是可拒绝请求,拦截掉。【Citrix篇】1-CitrixADC/Gateway远程代码执行漏洞CVE-2023-3519和升级方法二、漏洞详情    我们根据构建XSS语句,发现Citrix......
  • 题解 P9695【[GDCPC2023] Traveling in Cells】
    显然,询问的答案即为\(x\)所在的极长的满足颜色均在\(\mathbb{A}\)内的连续段的权值和。如果我们能维护对颜色的单点修改,以及求出某个位置所在极长连续段的左右端点\(l,r\),只需要树状数组即可求出答案。一个朴素的想法是对每种颜色开一棵线段树,单点修改是平凡的,极长连续段左......
  • 题解 P9702【[GDCPC2023] Computational Geometry】
    这题一看就不是计算几何,考虑区间DP。设凸多边形的\(n\)个顶点依次为\(P_1,P_2,\cdots,P_n\)。设\(f_{i,j}\)在\(i<j\)时表示\(P_i,P_{i+1},\cdots,P_{j-1},P_j\)组成的多边形的直径的平方,在\(i>j\)时表示\(P_i,P_{i+1},\cdots,P_n,P_1,\cdots,P_{j-1},P_j\)组......
  • 题解 P9697【[GDCPC2023] Canvas】
    好题。后面的操作会覆盖前面的操作,这东西不好处理,我们不妨时光倒流,将问题转化为一个位置一旦被填了数,就再也不会变了。如果解决了这个问题,只需将操作序列倒过来,就得到了原问题的解。显然,所有\(x_i=y_i=2\)的操作会最先被执行,所有\(x_i=y_i=1\)的操作会最后被执行。只需要给......
  • MapReduce学习二之WordCount案例
    一、案例概述1、第一步--变成偏移量的K1,V1(这一步不需要我们自己写)2、进入Map阶段输出新的<K2,V2>的键值对;3、Shuffle阶段分区、排序、规约、分组输出新的键值对:4、Reduce阶段转换为<K3,V3>的新的形式的键值对;利用TextOutputFormat的类实现结果的输出;二、具体实践1......
  • GDCPC2023 J X Equals Y
    洛谷传送门Gym传送门当时在GDCPC现场是这题首杀。20min就会了,但是2h才有电脑写(观察到至多\(50\)组数据满足\(\max(x,y)>10^6\),考虑一些根号做法。当\(f(x,a)\)的长度\(\ge3\)时,\(a\le\sqrt{x}\),因此可以暴力做,先找出所有\(f(x,a)\),再找出所有\(f(y,b......