Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: loshiat в Jun 17, 2010, 10:20



Титла: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: loshiat в Jun 17, 2010, 10:20
Код
GeSHi (Bash):
  1. #!/bin/bash
  2. aa=0
  3. while [ "$aa" != "x" ] ; do
  4. printf "input number or x for exit: " ; read aa
  5. ARRAY=( "${ARRAY[@]} "$aa" )
  6. done
  7.  
  8. echo ${ARRAY[@]}

Въпроса ми е че като натисна 'х' за да свършва попълването на масива и 'х' ми влиза в него. Не искам.
И другото как да покажа стойностите на масива - всяка на нов ред?

Така ми се вижда сложно

ELEMENTS=${#ARRAY
  • }
for (( i=0;i<$ELEMENTS;i++ )) ; do
echo ${ARRAY[${i}]}
done

И предизвикателството!!!...............трето най-трудно...... ако имам четири еднакви стойности (например четири пъти числото 345 на различни позиции, накрая да ми покаже RANDOM едно от тях и неговата позиция.


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: neter в Jun 17, 2010, 10:53
За да не влиза "x" в масива, просто сложи една такава проверка:
Код
GeSHi (Bash):
  1. if [ "$aa" != "x" ]; then
  2.      ARRAY=( "${ARRAY[@]}" "$aa" )
  3. fi

Щом "for" цикълът ти се вижда сложен, може да изведеш стойностите така:
Код
GeSHi (Bash):
  1. echo -e "${ARRAY[@]}" | tr -s ' ' '\n'
или така
Код
GeSHi (Bash):
  1. echo -n -e ${ARRAY[@]/%/"\n"}

Ще се наложи да обясниш по-подробно третия проблем. На базата на какво решаваме, че ни трябва числото 345. Предварително ли ще е дефинирано, или въпросното извеждане трябва да се случи за всички повтарящи се числа? И къде ще се извежда - в списъка с другите числа или под него? Ако ще е под него, повтарящите се числа ще влизат ли в списъка по-горе, или ще се извежда само отдолу с позицията му?


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: loshiat в Jun 17, 2010, 15:29
За да не влиза "x" в масива, просто сложи една такава проверка:
Код
GeSHi (Bash):
  1. if [ "$aa" != "x" ]; then
  2.      ARRAY=( "${ARRAY[@]}" "$aa" )
  3. fi

Щом "for" цикълът ти се вижда сложен, може да изведеш стойностите така:
Код
GeSHi (Bash):
  1. echo -e "${ARRAY[@]}" | tr -s ' ' '\n'
или така
Код
GeSHi (Bash):
  1. echo -n -e ${ARRAY[@]/%/"\n"}

Ще се наложи да обясниш по-подробно третия проблем. На базата на какво решаваме, че ни трябва числото 345. Предварително ли ще е дефинирано, или въпросното извеждане трябва да се случи за всички повтарящи се числа? И къде ще се извежда - в списъка с другите числа или под него? Ако ще е под него, повтарящите се числа ще влизат ли в списъка по-горе, или ще се извежда само отдолу с позицията му?


1. Ще са въведени предварително в базата.
2. Тези които се повтарят 3 пъти например. Да изведе едно рандъм от всички тях. Тези които се повтарят 2 пъти да изведе едно от всички тях........
(http://kachi-snimka.info/images/bwy1276777724u.JPG)


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: neter в Jun 17, 2010, 15:57
Т.е., съгласно схемата, от общо 6-те инстанции на числата 78 и 345 да се изведе само едната инстанция (някой път 78, друг път 345) и позицията на тази инстанция, и от общо 4-те инстанции на числата 123 и 22 да се изведе само едната инстанция (някой път 123, друг път 22) и позицията на тази инстанция? Питам, понеже въобще не ми идва на ум каква полза може да има от това действие, но ти надявам се си знаеш, аз доуточнявам :)


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: loshiat в Jun 17, 2010, 16:58
Т.е., съгласно схемата, от общо 6-те инстанции на числата 78 и 345 да се изведе само едната инстанция (някой път 78, друг път 345) и позицията на тази инстанция, и от общо 4-те инстанции на числата 123 и 22 да се изведе само едната инстанция (някой път 123, друг път 22) и позицията на тази инстанция? Питам, понеже въобще не ми идва на ум каква полза може да има от това действие, но ти надявам се си знаеш, аз доуточнявам :)

Точно така.... това е целта ми. Ще ти разкажа за какво иде реч като стане и ще ти  дам целия скрипт.


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: radoulov в Jun 17, 2010, 22:52
И аз не съм съвсем сигурен, дали това се иска,
но с GNU awk можеш да напишеш нещо такова:

Код
GeSHi ():
  1. awk -vstr="345 58 123 78 38 345 22 1 78 345 78 12 11 22 123" '
  2. BEGIN {
  3.  srand(); to_arry = str; n = split(to_arry, arry)
  4.  for (i = 0; ++ i <= n;) cnt[arry[i]]++
  5.  for (i = 0; ++ i <= n;)
  6.    g_cnt[cnt[arry[i]]] = ( \
  7.      g_cnt[cnt[arry[i]]] ? g_cnt[cnt[arry[i]]] FS arry[i] : arry[i] \
  8.        ) ":" i                
  9.  for (i = 0; ++ i <= n;) {
  10.    gn = split(g_cnt[cnt[arry[i]]], g_arry)
  11.     if (!(cnt[arry[i]] in prc) && cnt[arry[i]] > 1) {
  12.       rnd = int(gn * rand()) + 1; split(g_arry[rnd], r_elm, ":")
  13.       printf "random -> %s (tot %d, group count %d), position -> %d\n",
  14.       r_elm[1], cnt[arry[i]], gn, r_elm[2]
  15.       prc[cnt[arry[i]]]
  16.      }  
  17.    }
  18.  }'


Примерен резултат:

Код:
random -> 345 (tot 3, group count 6), position -> 10
random -> 22 (tot 2, group count 4), position -> 14


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: neter в Jun 18, 2010, 02:58
Ето моята интерпретация на bash, заедно с всички действия:
Код
GeSHi (Bash):
  1. #!/bin/bash
  2. aa=0
  3. while [ "$aa" != "x" ] ; do
  4.    printf "input number or x for exit: " ; read aa
  5.    if [ "$aa" != "x" ]; then
  6.        ARRAY=( "${ARRAY[@]}" "$aa" )
  7.    fi
  8. done
  9.  
  10. echo ${ARRAY[@]} | tr -s ' ' '\n'
  11.  
  12. for i in ${ARRAY[@]}; do
  13.    masiv[$i]=$((${masiv[$i]}+1))
  14. done
  15.  
  16. for i in ${!masiv[@]}; do
  17.    eval group`echo ${masiv[$i]}`=\( `echo \$\{group${masiv[$i]}[@]\}` "$i" \)
  18. done
  19.  
  20. echo ${masiv[@]} | tr -s ' ' '\n' | awk '!x[$0]++' | while read i; do
  21.    if [ "$i" -gt "1" ]; then
  22.        random=`eval echo \$\{group$i[\$\(\(RANDOM %= \$\{#group$i[@]\}\)\)]\}`
  23.        for y in ${!ARRAY[@]}; do
  24.            if [ "${ARRAY[$y]}" == "$random" ]; then
  25.                positions=( "${positions[@]}" "$y" )
  26.            fi
  27.        done
  28.        position=`echo ${positions[$((RANDOM %= ${#positions[@]}))]}`
  29.        echo "random -> $random ; position -> $position ; total -> $i"
  30.    fi
  31.    unset positions
  32. done


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: loshiat в Jun 18, 2010, 15:20
И двата скрипта не вървят... давам линк и за двата  да ги разгледате ако се съмнявате че грешно съм ги преписал.

http://www.2shared.com/file/IfMdCrdx/radulov.html   

http://www.2shared.com/file/rhhFSjkB/neter.html


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: radoulov в Jun 18, 2010, 15:37
Не си го преписал правилно. Виж прикачения file.


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: neter в Jun 18, 2010, 15:51
На ръка ли ги преписва тия скриптове, че успя да допуснеш такива грешки? В моя имаше добавена точка, липсващи скоби, сбъркани кавички (има няколко вида кавички, и всяка е важно да е такава, каквато съм я дал), сбъркано име на променлива даже и други. В този на radoulov имаше една сбъркана скоба (което е водело до грешката) и добавени интервали (макар че те не са проблем, но все пак). Просто копирай скриптовете и махни числата пред редовете. И двата скрипта си работят правилно ;)

редакция: Добавих ти прикачен файл и с моя скрипт.


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: loshiat в Jul 15, 2010, 11:32
на radulov нещо не ми тръгна но затова пък на neter работи.

Исказвам искрените си благодарности и на двама ВИ.... макар и със закъснение


Титла: Re: много малък и ОГРОМЕН проблем с Bash ARRAY
Публикувано от: niakoi в Jul 15, 2010, 12:19
Привет,
мисля, че задачата би била доста по-интересна ако числата са дадени във вид
3455812378383452217834578121122123, като се даде ограничение примерно за числа > 9 или > 99

поздрави
нас