请教如何查找最大值?
-
- 帖子: 229
- 注册时间: 2007-07-01 17:36
- 系统: (En):System
- 来自: (En):address
- 联系:
Re: 请教如何查找最大值?
按你的gawk版本,asort应该包含。
你看看,awk在你那是不是个alias,里面有参数--traditional 什么的?
因为asort是gawk的扩展,不包括在posix awk里,如果你用gawk的兼容模式参数,asort就不被包括了。
你看看,awk在你那是不是个alias,里面有参数--traditional 什么的?
因为asort是gawk的扩展,不包括在posix awk里,如果你用gawk的兼容模式参数,asort就不被包括了。
---
regards,
Kent
regards,
Kent
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
Re: 请教如何查找最大值?
kose3@kose3-desktop:~$ gawk '{for(i=2;i<=NF;i++) n[$i]=sqrt($i*$i);} END{l=asort(n,t); max=t[l]; print("maxABS: "max); if(max in n)print "Element: " max; if((0-max) in n) print "Element: "0-max } ' s2.t
maxABS: 32767.9
kose3@kose3-desktop:~$
有bug啊。
maxABS: 32767.9
kose3@kose3-desktop:~$
有bug啊。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
-
- 帖子: 229
- 注册时间: 2007-07-01 17:36
- 系统: (En):System
- 来自: (En):address
- 联系:
- lilydjwg
- 论坛版主
- 帖子: 4258
- 注册时间: 2009-04-11 23:46
- 系统: Arch Linux
- 联系:
Re: 请教如何查找最大值?
为什么有那么多 Python 代码,却没有人用 max?另外,文档说 list comprehension 比 map/filter 更快并且更易读:
[python]
#!/usr/bin/env python3
# vim:fileencoding=utf-8
import sys
sys.stdin.readline()
data = []
for l in sys.stdin:
data.extend([float(x) for x in l.strip().split()])
absdata = [abs(x) for x in data]
max = max(absdata)
if max in data:
print(max)
else:
print(-max)
[/python]
[python]
#!/usr/bin/env python3
# vim:fileencoding=utf-8
import sys
sys.stdin.readline()
data = []
for l in sys.stdin:
data.extend([float(x) for x in l.strip().split()])
absdata = [abs(x) for x in data]
max = max(absdata)
if max in data:
print(max)
else:
print(-max)
[/python]
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
Re: 请教如何查找最大值?
你用这个脚本生成一个五十万数字的文本, 再加上 两个好像 123456.1234567891234567890 和 -123456.1234567891234567891 试试,我的s2.t太大无法上传。sk1418 写了:你文件什么样的?
代码: 全选
#!/bin/bash
echo -n '输入要创建的文本名:'
read v_file_name
echo -n '输入需要的行数:'
read v_number_line
for i in $(seq $v_number_line);do
for ia in $(seq 5);do
a=$(($RANDOM%4))
case $a in
0)
b=$(($RANDOM))
;;
1)
b='-'$(($RANDOM))
;;
2)
b=0
while [[ $b -eq 0 ]];do
b=$((RANDOM))
done
b=$(($RANDOM))'.'$b
;;
3)
b=0
while [[ $b -eq 0 ]];do
b=$(($RANDOM))
done
b='-'$((RANDOM))'.'$b
;;
*)
echo error
exit 1
;;
esac
c=$c" "$b
done
echo -n "$i> 字节数: "
echo ${#c}
cat /dev/null |awk 'END{print e}' e="$c" >> $v_file_name
c=
done
上次由 fnan 在 2011-03-14 23:03,总共编辑 1 次。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
Re: 请教如何查找最大值?
kose3@kose3-desktop:~$ echo 123456.1234567891234567890 -123456.1234567891234567890 123456.123456789 |awk '{for(i=2;i<=NF;i++) n[$i]=sqrt($i*$i);} END{l=asort(n,t); max=t[l]; print("maxABS: "max); if(max in n)print "Element: " max; if((0-max) in n) print "Element: "0-max } '
maxABS: 123456
kose3@kose3-desktop:~$
可以看到数据变形了, 不能用浮点运算,不能用运算结果代替原数字。
maxABS: 123456
kose3@kose3-desktop:~$
可以看到数据变形了, 不能用浮点运算,不能用运算结果代替原数字。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
-
- 帖子: 229
- 注册时间: 2007-07-01 17:36
- 系统: (En):System
- 来自: (En):address
- 联系:
Re: 请教如何查找最大值?
应该是你这个数字精度太高了的原因。 awk默认是6位小数还是还是4位,记不得了。 不过可以设置科学计数法。但也得有个精度限制。你这个前提不知道精度到底有多少位。设置CONVFMT, OFMT也没啥用。用其它方法吧, 比如python的。fnan 写了:kose3@kose3-desktop:~$ echo 123456.1234567891234567890 -123456.1234567891234567890 123456.123456789 |awk '{for(i=2;i<=NF;i++) n[$i]=sqrt($i*$i);} END{l=asort(n,t); max=t[l]; print("maxABS: "max); if(max in n)print "Element: " max; if((0-max) in n) print "Element: "0-max } '
maxABS: 123456
kose3@kose3-desktop:~$
可以看到数据变形了, 不能用浮点运算,不能用运算结果代替原数字。
如果有人知道咋用awk解决你这个问题,我也想知道。

----
另外多谢lilydjwg提醒,坏习惯养成了,就不好改阿。。呵呵。 以后再写python的时候注意板一下坏毛病。
还有你的代码有颜色,挺好,怎么弄的? 但是美中不足,显示区域非常小,只有2-3行,用滚动条看起来很不方便阿,怎么能弄大?
---
regards,
Kent
regards,
Kent
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
Re: 请教如何查找最大值?
经测试, awk不能用于高精度的数字, 但类似lz的问题不处理高精度数字的程序是毫无意义的。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
- lilydjwg
- 论坛版主
- 帖子: 4258
- 注册时间: 2009-04-11 23:46
- 系统: Arch Linux
- 联系:
Re: 请教如何查找最大值?
sk1418 写了: 还有你的代码有颜色,挺好,怎么弄的? 但是美中不足,显示区域非常小,只有2-3行,用滚动条看起来很不方便阿,怎么能弄大?
代码: 全选
[python]abcdefg[/python]

- lilydjwg
- 论坛版主
- 帖子: 4258
- 注册时间: 2009-04-11 23:46
- 系统: Arch Linux
- 联系:
Re: 请教如何查找最大值?
Python 的精度应该是够了吧。fnan 写了:经测试, awk不能用于高精度的数字, 但类似lz的问题不处理高精度数字的程序是毫无意义的。
-
- 帖子: 229
- 注册时间: 2007-07-01 17:36
- 系统: (En):System
- 来自: (En):address
- 联系:
Re: 请教如何查找最大值?
问题是精度高不怕,得知道高到什么程度。fnan 写了:经测试, awk不能用于高精度的数字, 但类似lz的问题不处理高精度数字的程序是毫无意义的。
按我理解你这个要求,你拿到一个充满数字的文件,你都不知道精度最高是多少,这怎么处理?比如你说,保留小数后面10位什么的,也有个标准。
其实如果非用awk也能处理,把你的数字全作为字符串来处理,先比位数,长的大,一样的,从左往右比。怪麻烦的,而且没什么意义,就不写了。
用python吧,很多在别的语言里都溢出的数学运算,人家python就直接楞算就行,这曾经让我很吃惊。呵呵。
比如,你算个2的10000次方,python就直接2**10000
---
regards,
Kent
regards,
Kent
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
Re: 请教如何查找最大值?
写了个比较满意的bash脚本, 精度应该只受系统限制,速度也可接受,无限数字,能检查意外情况,也不过分复杂。
已处理了99947行。 用时0小时1分12秒
已处理了99989行。 用时0小时1分12秒
绝对值最大数: -123456789012345678901234567890.1234567890123456789012345678901234567891 和 123456789012345678901234567890.1234567890123456789012345678901234567891
总用时0小时1分12秒
共处理了100004 行。
kose5@kose5-Aspire-4552:~$
无疑python比bash好弄,不过想了解一下bash, 唯一方法是多折腾。
已处理了99947行。 用时0小时1分12秒
已处理了99989行。 用时0小时1分12秒
绝对值最大数: -123456789012345678901234567890.1234567890123456789012345678901234567891 和 123456789012345678901234567890.1234567890123456789012345678901234567891
总用时0小时1分12秒
共处理了100004 行。
kose5@kose5-Aspire-4552:~$
无疑python比bash好弄,不过想了解一下bash, 唯一方法是多折腾。
代码: 全选
#!/bin/bash
echo -n "输入要处理数字的文本地址: "
read v_file
if [[ "$(echo $v_file |cut -d'/' -f1)" = '~' ]];then
v_file=$PWD${v_file#\~}
fi
echo
echo -n "开始处理 $v_file 文本:"
lc=$(wc -l < $v_file)
echo " 总 $lc 行"
echo
if (grep -q '[^0-9. -]' $v_file);then
echo " 错误!有非数字字符!"
exit 1
fi
v_time1=$(date +%s)
v_numbers=
f_max()
{
v_numbers=$(echo $v_numbers|tr -s " " "\n"|sort -n|sed -ne '1p' -e '$p'|tr "\n" " ")
}
f_show_max()
{
v_a=$(echo $v_numbers |cut -d' ' -f1)
v_b=$(echo $v_numbers |cut -d' ' -f2)
va=${v_a#\-}
vb=${v_b#\-}
if [[ $(expr index $va '.') > 0 ]];then
la=${va#*\.}
la=${#la}
else
la=0
fi
if [[ $(expr index $vb '.') > 0 ]];then
lb=${vb#*\.}
lb=${#lb}
else
lb=0
fi
va=${va/\./}
vb=${vb/\./}
if [[ $la -gt $lb ]];then
vb=$vb$(seq $(($la-$lb)) |tr "\n" "a" |tr -d "0-9" |tr "a" "0")
elif [[ $lb -gt $la ]];then
va=$va$(seq $(($lb-$la)) |tr "\n" "a" |tr -d "0-9" |tr "a" "0")
fi
if [[ $va -gt $vb ]];then
echo " 绝对值最大数: $v_a"
elif [[ $va -lt $vb ]];then
echo " 绝对值最大数: $v_b"
else
echo " 绝对值最大数: $v_a 和 $v_b"
fi
echo
echo -n "总"
f_show_time
echo "共处理了$v_count 行。"
exit 0
}
f_show_time()
{
v_time2=$(date +%s)
v_time=$(($v_time2 - $v_time1))
v_h=$(($v_time/60/60))
v_h=${v_h%\.*}
v_m=$(($v_time/60))
v_m=$((${v_m%\.*}-($v_h*60)))
v_s=$(($v_time - ($v_h*60*60) - ($v_m*60)))
echo "用时$v_h小时$v_m分$v_s秒"
}
f_read_lines()
{
while read v_line;do
((v_count++))
v_numbers=$v_numbers" "$v_line
if [[ ${#v_numbers} -gt 2000 ]];then
f_max
echo -n "已处理了$v_count行。 "
f_show_time
fi
done < $v_file
if (echo $v_numbers|grep -q '[0-9] [0-9]');then
f_max
f_show_max
else
echo " 不到两个数字!"
fi
exit 1
}
#MAIN()
#{
f_read_lines
#}
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
-
- 帖子: 919
- 注册时间: 2009-07-01 22:04
Re: 请教如何查找最大值?
现在可以一行命令搞定无限精度:
kose1@kose1-desktop:~$ cat n.t
1.23456781234567812345679 -1.23456781234567812345679 -45.4555
5764.6756578584 12345678.123456789123456789123456789123456789 -12345678.1234567891234567891234567891234567891
34456 -4545556 45.5 -435.5656566466565656
kose1@kose1-desktop:~$ sed 's/-\([0-9][0-9.]*\)/\1_/g' n.t|xargs -n1|sort -n|tail -2|awk 'BEGIN{FS="\n";RS="m"} {split($0,a);gsub("_","");if ($1"" == $2"") print a[1],a[2];else print a[2]}'|sed 's/\([0-9.]*\)_/ -\1/g'
-12345678.1234567891234567891234567891234567891
kose1@kose1-desktop:~$
kose1@kose1-desktop:~$ cat n.t
1.23456781234567812345679 -1.23456781234567812345679 -45.4555
5764.6756578584 12345678.123456789123456789123456789123456789 -12345678.1234567891234567891234567891234567891
34456 -4545556 45.5 -435.5656566466565656
kose1@kose1-desktop:~$ sed 's/-\([0-9][0-9.]*\)/\1_/g' n.t|xargs -n1|sort -n|tail -2|awk 'BEGIN{FS="\n";RS="m"} {split($0,a);gsub("_","");if ($1"" == $2"") print a[1],a[2];else print a[2]}'|sed 's/\([0-9.]*\)_/ -\1/g'
-12345678.1234567891234567891234567891234567891
kose1@kose1-desktop:~$
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
-
- 帖子: 61
- 注册时间: 2010-04-29 22:00
- 系统: Gentoo Linux ~amd64
- 联系: