免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zhkun
打印 上一主题 下一主题

数字相加情况。  关闭 [复制链接]

论坛徽章:
0
51 [报告]
发表于 2004-10-04 03:56 |只看该作者

数字相加情况。

重新修改了程序以符合本坛的宗旨: 无论算法深浅,只求语句巧妙。
另外还加了 bash 的版本。

KSH:

  1. #!/bin/ksh

  2. typeset -r MAX=150
  3. typeset -r MIN=100
  4. set -A data $(cat $1 | sort -n)

  5. getall () {
  6. typeset i=$3
  7. while [ $i -ge 0 ]
  8. do
  9.        typeset sum=$2
  10.        typeset list=$1${1:+' + '}${data[$i]}
  11.        sum=$(( sum + data[$i] ))
  12.         if [ $sum -le $MAX ]; then
  13.                 if [ $sum -ge $MIN ]; then
  14.                         echo $list" = "$sum
  15.                 fi

  16.                    ( getall "$list" $sum $((i - 1)) )
  17.         fi

  18. (( i -- ))
  19. done
  20. }

  21. getall "" 0 $(( ${#data[*]} - 1 ))

复制代码



BASH:

  1. #!/bin/bash

  2. MAX=150
  3. MIN=100
  4. data=($(cat $1 | sort -n))

  5. getall () {
  6. local i=$3
  7. while [ $i -ge 0 ]
  8. do
  9.         local sum=$2
  10.         local list=$1${1:+' + '}${data[$i]}
  11.         sum=$(( sum + data[$i] ))
  12.         if [ $sum -le $MAX ]; then
  13.                 if [ $sum -ge $MIN ]; then
  14.                         echo $list" = "$sum
  15.                 fi

  16.                     getall "$list" $sum $((i - 1))
  17.         fi

  18. (( i -= 1 ))
  19. done
  20. }

  21. getall "" 0 $(( ${#data[*]} - 1 ))


复制代码
[/quote]

论坛徽章:
0
52 [报告]
发表于 2004-10-04 11:00 |只看该作者

数字相加情况。

我想若将条件修改一下,大家看看这样行不行。
设置最大值,每个数字只能相加一次,不设置最小值,求最少加式(可以把没有相加的数字放到最后一组中)。

论坛徽章:
0
53 [报告]
发表于 2004-10-05 13:24 |只看该作者

数字相加情况。

9494

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
54 [报告]
发表于 2004-10-05 15:41 |只看该作者

数字相加情况。

强!

论坛徽章:
0
55 [报告]
发表于 2004-10-05 20:42 |只看该作者

数字相加情况。

请各位高手显伸手!!!

论坛徽章:
0
56 [报告]
发表于 2004-10-06 04:04 |只看该作者

数字相加情况。

原帖由 "zhkun" 发表:
我想若将条件修改一下,大家看看这样行不行。
设置最大值,每个数字只能相加一次,不设置最小值,求最少加式(可以把没有相加的数字放到最后一组中)。


此题有点问题。 如我前面所讲, 无唯一解,所有我全列出了结果。
这次用 perl. 另外, 修改 $MINLEN, 可限制最少加项的数目。


  1. #!/bin/perl

  2. $MAX=150;
  3. $MINLEN=1;
  4. $min=9;

  5. open DATA, "<$ARGV[0]" or die "Can't open $ARGV[0]: $!";
  6. while (<DATA>) {
  7. chomp;
  8. @data=(@data, $_);
  9. }
  10. @data=sort { $a <=> $b } @data;

  11. sub getall {
  12. my $i=$_[2];
  13. for ( $i; $i >= 0; $i -- ) {
  14.         my $sum=$_[1];
  15.         my $list="$_[0]" . ($_[0] ? " + " : "") . "$data[$i]";
  16.         $sum += $data[$i];
  17.         if ( $sum <= $MAX ) {
  18.                 my $list1 = $list . " = " . $sum ;
  19.                 @str=split /\D+/, $list;
  20.                 $len=$#str + 1;
  21.                 if ( $len <= $min && $len >= $MINLEN ) {
  22.                  $min = $len;
  23.                     $store{$list1}=$len;
  24.                  @used=(@used, split /\s+/, $list);
  25.                 }
  26.         }
  27.                       &getall( $list, $sum, $i - 1);
  28. }
  29. }

  30. &getall( "", 0, $#data) ;

  31. foreach $key ( sort { $a <=> $b} keys %store ) {
  32.         print "$key\n";
  33. }

  34. print "\nUnused number\n\n";
  35. foreach (@used) {
  36. $u{$_}=$_;
  37. }
  38. for ( $i=0; $i <= $#data; $i++ ) {
  39.   print "$data[$i]\n" if ( ! exists $u{$data[$i]} );
  40. }

复制代码


  1. $MINLEN=1 时的结果:

  2. # ./1  data

  3. 1 = 1
  4. 2 = 2
  5. 3 = 3
  6. 4 = 4
  7. 12 = 12
  8. 24 = 24
  9. 32 = 32
  10. 45 = 45
  11. 53 = 53
  12. 97 = 97
  13. 100 = 100
  14. 145 = 145
  15. 150 = 150

  16. Unused number

  17. 170

复制代码


  1. $MINLEN=4 时的结果:

  2. # ./1  data

  3. 4 + 3 + 2 + 1 = 10
  4. 12 + 3 + 2 + 1 = 18
  5. 12 + 4 + 2 + 1 = 19
  6. 12 + 4 + 3 + 1 = 20
  7. 12 + 4 + 3 + 2 = 21
  8. 24 + 3 + 2 + 1 = 30
  9. 24 + 12 + 2 + 1 = 39
  10. 24 + 12 + 3 + 2 = 41
  11. 24 + 4 + 3 + 1 = 32
  12. 24 + 12 + 4 + 2 = 42
  13. 24 + 12 + 3 + 1 = 40
  14. 24 + 12 + 4 + 1 = 41
  15. 24 + 4 + 2 + 1 = 31
  16. 24 + 12 + 4 + 3 = 43
  17. 24 + 4 + 3 + 2 = 33
  18. 32 + 24 + 4 + 2 = 62
  19. 32 + 4 + 3 + 2 = 41
  20. 32 + 4 + 3 + 1 = 40
  21. 32 + 3 + 2 + 1 = 38
  22. 32 + 12 + 3 + 2 = 49
  23. 32 + 12 + 4 + 2 = 50
  24. 32 + 12 + 2 + 1 = 47
  25. 32 + 24 + 12 + 1 = 69
  26. 32 + 24 + 4 + 3 = 63
  27. 32 + 24 + 3 + 2 = 61
  28. 32 + 24 + 12 + 2 = 70
  29. 32 + 12 + 3 + 1 = 48
  30. 32 + 24 + 4 + 1 = 61
  31. 32 + 12 + 4 + 1 = 49
  32. 32 + 4 + 2 + 1 = 39
  33. 32 + 24 + 12 + 4 = 72
  34. 32 + 12 + 4 + 3 = 51
  35. 32 + 24 + 12 + 3 = 71
  36. 32 + 24 + 3 + 1 = 60
  37. 32 + 24 + 2 + 1 = 59
  38. 45 + 24 + 4 + 1 = 74
  39. 45 + 24 + 3 + 1 = 73
  40. 45 + 12 + 2 + 1 = 60
  41. 45 + 4 + 3 + 2 = 54
  42. 45 + 24 + 4 + 3 = 76
  43. 45 + 32 + 12 + 1 = 90
  44. 45 + 12 + 3 + 2 = 62
  45. 45 + 24 + 12 + 4 = 85
  46. 45 + 32 + 12 + 3 = 92
  47. 45 + 4 + 2 + 1 = 52
  48. 45 + 12 + 4 + 2 = 63
  49. 45 + 32 + 24 + 3 = 104
  50. 45 + 4 + 3 + 1 = 53
  51. 45 + 12 + 4 + 3 = 64
  52. 45 + 24 + 12 + 2 = 83
  53. 45 + 3 + 2 + 1 = 51
  54. 45 + 24 + 3 + 2 = 74
  55. 45 + 32 + 24 + 2 = 103
  56. 45 + 32 + 24 + 12 = 113
  57. 45 + 24 + 2 + 1 = 72
  58. 45 + 32 + 4 + 3 = 84
  59. 45 + 12 + 3 + 1 = 61
  60. 45 + 12 + 4 + 1 = 62
  61. 45 + 32 + 3 + 1 = 81
  62. 45 + 24 + 12 + 1 = 82
  63. 45 + 32 + 24 + 4 = 105
  64. 45 + 32 + 24 + 1 = 102
  65. 45 + 24 + 12 + 3 = 84
  66. 45 + 32 + 3 + 2 = 82
  67. 45 + 32 + 12 + 2 = 91
  68. 45 + 24 + 4 + 2 = 75
  69. 45 + 32 + 4 + 1 = 82
  70. 45 + 32 + 12 + 4 = 93
  71. 45 + 32 + 2 + 1 = 80
  72. 45 + 32 + 4 + 2 = 83
  73. 53 + 45 + 24 + 2 = 124
  74. 53 + 24 + 12 + 3 = 92
  75. 53 + 32 + 2 + 1 = 88
  76. 53 + 45 + 24 + 3 = 125
  77. 53 + 32 + 12 + 3 = 100
  78. 53 + 32 + 4 + 2 = 91
  79. 53 + 45 + 32 + 2 = 132
  80. 53 + 45 + 4 + 2 = 104
  81. 53 + 12 + 2 + 1 = 68
  82. 53 + 32 + 24 + 4 = 113
  83. 53 + 4 + 3 + 2 = 62
  84. 53 + 32 + 12 + 4 = 101
  85. 53 + 32 + 3 + 1 = 89
  86. 53 + 45 + 4 + 3 = 105
  87. 53 + 32 + 12 + 2 = 99
  88. 53 + 12 + 3 + 2 = 70
  89. 53 + 12 + 4 + 2 = 71
  90. 53 + 45 + 3 + 1 = 102
  91. 53 + 32 + 24 + 2 = 111
  92. 53 + 32 + 24 + 1 = 110
  93. 53 + 45 + 12 + 4 = 114
  94. 53 + 45 + 12 + 2 = 112
  95. 53 + 45 + 12 + 1 = 111
  96. 53 + 32 + 4 + 3 = 92
  97. 53 + 45 + 3 + 2 = 103
  98. 53 + 45 + 4 + 1 = 103
  99. 53 + 4 + 3 + 1 = 61
  100. 53 + 24 + 4 + 3 = 84
  101. 53 + 24 + 12 + 4 = 93
  102. 53 + 12 + 3 + 1 = 69
  103. 53 + 45 + 32 + 3 = 133
  104. 53 + 45 + 32 + 4 = 134
  105. 53 + 32 + 4 + 1 = 90
  106. 53 + 12 + 4 + 3 = 72
  107. 53 + 24 + 12 + 1 = 90
  108. 53 + 3 + 2 + 1 = 59
  109. 53 + 24 + 4 + 1 = 82
  110. 53 + 32 + 12 + 1 = 98
  111. 53 + 32 + 3 + 2 = 90
  112. 53 + 24 + 3 + 2 = 82
  113. 53 + 45 + 32 + 1 = 131
  114. 53 + 24 + 12 + 2 = 91
  115. 53 + 24 + 4 + 2 = 83
  116. 53 + 12 + 4 + 1 = 70
  117. 53 + 24 + 2 + 1 = 80
  118. 53 + 32 + 24 + 3 = 112
  119. 53 + 45 + 24 + 1 = 123
  120. 53 + 45 + 24 + 4 = 126
  121. 53 + 45 + 2 + 1 = 101
  122. 53 + 24 + 3 + 1 = 81
  123. 53 + 45 + 32 + 12 = 142
  124. 53 + 4 + 2 + 1 = 60
  125. 53 + 32 + 24 + 12 = 121
  126. 53 + 45 + 12 + 3 = 113
  127. 53 + 45 + 24 + 12 = 134
  128. 97 + 12 + 4 + 3 = 116
  129. 97 + 24 + 3 + 1 = 125
  130. 97 + 45 + 4 + 1 = 147
  131. 97 + 32 + 12 + 2 = 143
  132. 97 + 32 + 4 + 3 = 136
  133. 97 + 32 + 2 + 1 = 132
  134. 97 + 32 + 12 + 4 = 145
  135. 97 + 24 + 4 + 1 = 126
  136. 97 + 4 + 3 + 1 = 105
  137. 97 + 32 + 3 + 2 = 134
  138. 97 + 32 + 12 + 3 = 144
  139. 97 + 4 + 3 + 2 = 106
  140. 97 + 45 + 4 + 3 = 149
  141. 97 + 32 + 4 + 2 = 135
  142. 97 + 12 + 3 + 2 = 114
  143. 97 + 45 + 2 + 1 = 145
  144. 97 + 12 + 3 + 1 = 113
  145. 97 + 12 + 4 + 1 = 114
  146. 97 + 45 + 3 + 2 = 147
  147. 97 + 24 + 12 + 1 = 134
  148. 97 + 24 + 12 + 2 = 135
  149. 97 + 45 + 4 + 2 = 148
  150. 97 + 3 + 2 + 1 = 103
  151. 97 + 24 + 3 + 2 = 126
  152. 97 + 45 + 3 + 1 = 146
  153. 97 + 24 + 12 + 3 = 136
  154. 97 + 12 + 2 + 1 = 112
  155. 97 + 24 + 2 + 1 = 124
  156. 97 + 32 + 12 + 1 = 142
  157. 97 + 24 + 4 + 2 = 127
  158. 97 + 24 + 4 + 3 = 128
  159. 97 + 12 + 4 + 2 = 115
  160. 97 + 32 + 3 + 1 = 133
  161. 97 + 4 + 2 + 1 = 104
  162. 97 + 24 + 12 + 4 = 137
  163. 97 + 32 + 4 + 1 = 134
  164. 100 + 32 + 4 + 1 = 137
  165. 100 + 45 + 4 + 1 = 150
  166. 100 + 3 + 2 + 1 = 106
  167. 100 + 12 + 3 + 1 = 116
  168. 100 + 32 + 3 + 1 = 136
  169. 100 + 32 + 12 + 2 = 146
  170. 100 + 32 + 12 + 1 = 145
  171. 100 + 32 + 4 + 3 = 139
  172. 100 + 4 + 2 + 1 = 107
  173. 100 + 45 + 2 + 1 = 148
  174. 100 + 45 + 3 + 2 = 150
  175. 100 + 4 + 3 + 2 = 109
  176. 100 + 12 + 2 + 1 = 115
  177. 100 + 4 + 3 + 1 = 108
  178. 100 + 12 + 4 + 3 = 119
  179. 100 + 24 + 4 + 3 = 131
  180. 100 + 32 + 2 + 1 = 135
  181. 100 + 32 + 12 + 3 = 147
  182. 100 + 24 + 12 + 3 = 139
  183. 100 + 45 + 3 + 1 = 149
  184. 100 + 12 + 4 + 2 = 118
  185. 100 + 24 + 3 + 1 = 128
  186. 100 + 12 + 4 + 1 = 117
  187. 100 + 24 + 4 + 1 = 129
  188. 100 + 24 + 2 + 1 = 127
  189. 100 + 24 + 12 + 4 = 140
  190. 100 + 24 + 3 + 2 = 129
  191. 100 + 24 + 12 + 1 = 137
  192. 100 + 12 + 3 + 2 = 117
  193. 100 + 24 + 4 + 2 = 130
  194. 100 + 24 + 12 + 2 = 138
  195. 100 + 32 + 12 + 4 = 148
  196. 100 + 32 + 3 + 2 = 137
  197. 100 + 32 + 4 + 2 = 138

  198. Unused number

  199. 145
  200. 150
  201. 170


复制代码

论坛徽章:
0
57 [报告]
发表于 2004-10-06 10:43 |只看该作者

数字相加情况。

真的不错!!!,谢谢lightspeed

论坛徽章:
0
58 [报告]
发表于 2004-10-06 20:20 |只看该作者

数字相加情况。

俩字,高手!

论坛徽章:
0
59 [报告]
发表于 2004-10-09 11:28 |只看该作者

数字相加情况。

请大家继续!

论坛徽章:
0
60 [报告]
发表于 2004-10-10 13:22 |只看该作者

数字相加情况。

用一种算法最后解决了找出一组最少算式的问题。 由于楼主要求 ksh,  使工作
难于展开。ksh 中对数组的 size 限制,不得不用临时文件, 这样速度慢了,
但可处理大的数据文件。 有可能的话,还是用 perl 好。


  1. #!/bin/ksh

  2. typeset -r MAX=150
  3. TMP=.mytmp
  4. if [ -e $TMP ]; then
  5. rm -rf $TMP
  6. fi
  7. mkdir $TMP


  8. set -A data $(cat $1 | sort -n)

  9. getall () {
  10. typeset i=$1
  11. shift
  12. typeset sumsum=$1
  13. shift
  14. while [ $i -ge 0 ]
  15. do
  16.         typeset sum=$sumsum
  17.         typeset list
  18.         set -A list
  19.         list=($* "a${i}a")
  20.         sum=$(( sum + data[$i] ))
  21.         if [ $sum -le $MAX ]; then
  22.                 echo $sum" "${#list[*]}" "${list[*]} >> ${TMP}/a

  23.                     ( getall $((i - 1)) $sum  "${list[*]}" )
  24.         fi

  25. (( i -- ))
  26. done
  27. }

  28. i=0
  29. max_index=0
  30. while [ $i -le $(( ${#data[*]} - 1 )) ]
  31. do
  32.         if [ ${data[$i]} -le $MAX ]; then
  33.                 max_index=$i
  34.         else
  35.                 unused=$unused" "${data[$i]}
  36.         fi
  37. (( i ++ ))
  38. done

  39. echo
  40. echo Collect data ....

  41. getall  $max_index 0 ""

  42. sort -n -r -k 1 -k 2 ${TMP}/a |awk '{$1="";$2="";print}' > ${TMP}/b

  43. echo Process data ...
  44. echo
  45. set -A avail

  46. wfile=a
  47. rfile=b
  48. while true
  49. do
  50.         line=$(sed -n "1p" ${TMP}/$rfile)
  51.         current=$(echo $line|sed 's/a//g')

  52.         s=0
  53.         l=
  54.         for k in $current
  55.         do
  56.                 s=$(( s + data[k] ))
  57.                 l=$l" + "${data[k]}
  58.         done
  59.         l=$(echo $l|sed 's/+//')
  60.         echo $l" = "$s

  61.         avail=(${avail[*]} $current)
  62.         if [ ${#avail[*]} -gt $max_index ]; then
  63.                 break
  64.         fi
  65.         j=0
  66.         while [ $j -le $((${#avail[*]} - 1)) ]
  67.         do
  68.                 command=$command" | grep -v a${avail[$j]}a"        
  69.                 (( j++ ))
  70.         done
  71.                
  72.         command="cat ${TMP}/$rfile "$command" > ${TMP}/$wfile"
  73.         eval $command
  74.         command=
  75.         tfile=$wfile
  76.         wfile=$rfile
  77.         rfile=$tfile

  78. done

  79. echo "\nUnused number: $unused\n"
  80. echo Clear temp files ...

  81. rm -rf $TMP

  82. echo Done !


复制代码


运行:



  1. # ./1  data

  2. Collect data ....
  3. Process data ...

  4. 53 + 45 + 32 + 12 + 4 + 3 + 1 = 150
  5. 150 = 150
  6. 145 + 2 = 147
  7. 100 + 24 = 124
  8. 97 = 97

  9. Unused number:  170

  10. Clear temp files ...
  11. Done !   

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP