2016-09-21 2 views
1

Есть ли способ сделать код быстрее? я все пробовал!Bash - Как сделать bash более эффективным и быстрее работать

В основном, что я пытаюсь сделать, это: , чтобы рассчитать все комбинации из 52 переменных, но показывать только комбинации, где все числа перечислены только один раз! так что не может быть FX: два 1-й или три 49-х

#!/bin/bash 

#Enter here how many cards you use 
howmanycards=52; 

let run=$howmanycards+1; 
i=1; 
u=52; 
totalrun=0; 
SECONDS=0; 

while [ $i -lt $run ]; do 
    let card$i=$u; 
    let i++; 
    let u--; 
done 

while [ -lt ]; do 

    let i=1; 

    if [ "$card1" -gt "52" ]; then let card2++;let card1=1; fi 
    if [ "$card2" -gt "52" ]; then let card3++;let card2=1; fi 
    if [ "$card3" -gt "52" ]; then let card4++;let card3=1; fi 
    if [ "$card4" -gt "52" ]; then let card5++;let card4=1; fi 
    if [ "$card5" -gt "52" ]; then let card6++;let card5=1; fi 
    if [ "$card6" -gt "52" ]; then let card7++;let card6=1; fi 
    if [ "$card7" -gt "52" ]; then let card8++;let card7=1; fi 
    if [ "$card8" -gt "52" ]; then let card9++;let card8=1; fi 
    if [ "$card9" -gt "52" ]; then let card10++;let card9=1; fi 
    if [ "$card10" -gt "52" ]; then let card11++;let card10=1; fi 
    if [ "$card11" -gt "52" ]; then let card12++;let card11=1; fi 
    if [ "$card12" -gt "52" ]; then let card13++;let card12=1; fi 
    if [ "$card13" -gt "52" ]; then let card14++;let card13=1; fi 
    if [ "$card14" -gt "52" ]; then let card15++;let card14=1; fi 
    if [ "$card15" -gt "52" ]; then let card16++;let card15=1; fi 
    if [ "$card16" -gt "52" ]; then let card17++;let card16=1; fi 
    if [ "$card17" -gt "52" ]; then let card18++;let card17=1; fi 
    if [ "$card18" -gt "52" ]; then let card19++;let card18=1; fi 
    if [ "$card19" -gt "52" ]; then let card20++;let card19=1; fi 
    if [ "$card20" -gt "52" ]; then let card21++;let card20=1; fi 
    if [ "$card21" -gt "52" ]; then let card22++;let card21=1; fi 
    if [ "$card22" -gt "52" ]; then let card23++;let card22=1; fi 
    if [ "$card23" -gt "52" ]; then let card24++;let card23=1; fi 
    if [ "$card24" -gt "52" ]; then let card25++;let card24=1; fi 
    if [ "$card25" -gt "52" ]; then let card26++;let card25=1; fi 
    if [ "$card26" -gt "52" ]; then let card27++;let card26=1; fi 
    if [ "$card27" -gt "52" ]; then let card28++;let card27=1; fi 
    if [ "$card28" -gt "52" ]; then let card29++;let card28=1; fi 
    if [ "$card30" -gt "52" ]; then let card31++;let card30=1; fi 
    if [ "$card31" -gt "52" ]; then let card32++;let card31=1; fi 
    if [ "$card32" -gt "52" ]; then let card33++;let card32=1; fi 
    if [ "$card33" -gt "52" ]; then let card34++;let card33=1; fi 
    if [ "$card34" -gt "52" ]; then let card35++;let card34=1; fi 
    if [ "$card35" -gt "52" ]; then let card36++;let card35=1; fi 
    if [ "$card36" -gt "52" ]; then let card37++;let card36=1; fi 
    if [ "$card37" -gt "52" ]; then let card38++;let card37=1; fi 
    if [ "$card38" -gt "52" ]; then let card39++;let card38=1; fi 
    if [ "$card39" -gt "52" ]; then let card40++;let card39=1; fi 
    if [ "$card40" -gt "52" ]; then let card41++;let card40=1; fi 
    if [ "$card41" -gt "52" ]; then let card42++;let card41=1; fi 
    if [ "$card42" -gt "52" ]; then let card43++;let card42=1; fi 
    if [ "$card43" -gt "52" ]; then let card44++;let card43=1; fi 
    if [ "$card44" -gt "52" ]; then let card45++;let card44=1; fi 
    if [ "$card45" -gt "52" ]; then let card46++;let card45=1; fi 
    if [ "$card46" -gt "52" ]; then let card47++;let card46=1; fi 
    if [ "$card47" -gt "52" ]; then let card48++;let card47=1; fi 
    if [ "$card48" -gt "52" ]; then let card49++;let card48=1; fi 
    if [ "$card49" -gt "52" ]; then let card50++;let card49=1; fi 
    if [ "$card50" -gt "52" ]; then let card51++;let card50=1; fi 
    if [ "$card51" -gt "52" ]; then let card52++;let card51=1; fi 

    while [ $i -lt $run ]; do 
     temp=${card}${i}; 
     if [ "$temp" = "$card1" ] || [ "$temp" = "$card2" ] || 
      [ "$temp" = "$card3" ] || [ "$temp" = "$card4" ] || 
      [ "$temp" = "$card5" ] || [ "$temp" = "$card6" ] || 
      [ "$temp" = "$card7" ] || [ "$temp" = "$card8" ] || 
      [ "$temp" = "$card9" ] || [ "$temp" = "$card10" ] || 
      [ "$temp" = "$card11" ] || [ "$temp" = "$card12" ] || 
      [ "$temp" = "$card13" ] || [ "$temp" = "$card14" ] || 
      [ "$temp" = "$card15" ] || [ "$temp" = "$card16" ] || 
      [ "$temp" = "$card17" ] || [ "$temp" = "$card18" ] || 
      [ "$temp" = "$card19" ] || [ "$temp" = "$card20" ] || 
      [ "$temp" = "$card21" ] || [ "$temp" = "$card22" ] || 
      [ "$temp" = "$card23" ] || [ "$temp" = "$card24" ] || 
      [ "$temp" = "$card25" ] || [ "$temp" = "$card26" ] || 
      [ "$temp" = "$card27" ] || [ "$temp" = "$card28" ] || 
      [ "$temp" = "$card29" ] || [ "$temp" = "$card30" ] || 
      [ "$temp" = "$card31" ] || [ "$temp" = "$card32" ] || 
      [ "$temp" = "$card33" ] || [ "$temp" = "$card34" ] || 
      [ "$temp" = "$card35" ] || [ "$temp" = "$card36" ] || 
      [ "$temp" = "$card37" ] || [ "$temp" = "$card38" ] || 
      [ "$temp" = "$card39" ] || [ "$temp" = "$card40" ] || 
      [ "$temp" = "$card41" ] || [ "$temp" = "$card42" ] || 
      [ "$temp" = "$card43" ] || [ "$temp" = "$card44" ] || 
      [ "$temp" = "$card45" ] || [ "$temp" = "$card46" ] || 
      [ "$temp" = "$card47" ] || [ "$temp" = "$card48" ] || 
      [ "$temp" = "$card49" ] || [ "$temp" = "$card50" ] || 
      [ "$temp" = "$card51" ] || [ "$temp" = "$card52" ]; then 
      let usefull++; 
     fi 
     let i++; 
    done 

if [ $usefull -gt 51 ]; then 
    echo "[loops($totalrun)] $card52-$card51-$card50-$card49-$card48-$card47-$card46-$card45-$card44-$card43-$card42-$card41-$card40-$card39-$card38-$card37-$card36-$card35-$card34-$card33-$card32-$card31-$card30-$card29-$card28-$card27-$card26-$card25-$card24-$card23-$card22-$card21-$card20-$card19-$card18-$card17-$card16-$card15-$card14-$card13-$card12-$card11-$card10-$card9-$card8-$card7-$card6-$card5-$card4-$card3-$card2-$card1"; 
fi 

let usefull=0; 

if [ "$card52" -gt "52" ]; then 
    echo " "; 
    duration=$SECONDS 
    echo "$(($duration/60)) min and $(($duration % 60)) sec"; 
    exit; 
fi 

let card1++; 
let totalrun++; 
done 

Я попытался создать приоритеты кода, но dosen't, кажется, чтобы сделать разницу!

но я понял, что код, который делает чек, если в нем больше одного номера, использует большую производительность! И я не знаю, что с этим делать!

Благодарим за помощь.

+0

Возможный дубликат http://stackoverflow.com/questions/22358139/all-possible-combinations-of-card-poker-hands-for-a-set-of-players – tripleee

+3

Вы понимаете, сколько есть комбинации? http://czep.net/weblog/52cards.html – tripleee

+1

Сказав это, генерация возможных перестановок будет намного более эффективной, чем создание списков переборки и исключение тех, которые не являются перестановками. – tripleee

ответ

0

Во-первых, я думаю, что вам нужна выполнимая реализация, чтобы получить комбинации в bash. Вот один из них, который работает с ассоциативными массивами. Я реализовал ее, чтобы имитировать this Java code:

#!/bin/bash 

function combine() { 
    local index="$1" 
    local -a prefix=("${!2}") 
    local -a postfix=("${!3}") 

    local i=$index 

    while [ $i -lt ${#prefix[@]} ]; do 
     postfix+=(${prefix[@]:$i:1}) 
     echo ${postfix[@]} 
     combine "$((i + 1))" prefix[@] postfix[@] 
     local postfix_last_char="$((${#postfix[@]} - 1))" 
     postfix=(${postfix[@]:0:$postfix_last_char}) 
     ((i++)) 
    done 
} 

function get_combinations() { 
    local -a prefix_table=("${!1}") 
    local -a postfix_table=() 
    local index=0 

    combine 0 prefix_table[@] postfix_table[@] 
} 

function example_use() { 
    # Get all combinations of the numbers 0 to 9. 
    foo=({0..9}) 
    get_combinations foo[@] 
} 

Теперь можно начать думать об изменении функции combine() ввести дополнительное условие, что мы будем печатать только из наборов (массивы, которые содержат только отдельные элементы.) Таким образом, мы можем заменить строку:

echo ${postfix[@]} 

к новому вызову:

echo_if_is_a_set postfix[@] 

который реализуется как:

function echo_if_is_a_set() { 
    local -a input=("${!1}") 
    local -a entry_count_lookup 

    # Tally up the occurrences of each item. 
    for item in ${input[@]}; do 
     local current_count=${entry_count_lookup[$item]:-0} 
     ((current_count++)) 
     entry_count_lookup[$item]=$current_count 
    done 

    for value in ${!entry_count_lookup[@]}; do 
     if [ ${entry_count_lookup[$value]} -ne 1 ]; then 
      return 
     fi 
    done 

    echo ${input[@]} 
} 

Хорошо, но не совсем сделано. Мы можем по-прежнему печатать одну и ту же комбинацию дважды, в случае, если она была передана в повторяющихся элементах. Например, если вы сделали:

foo=(1 1 1) 
get_combinations foo[@] 

Итак, давайте просто называть Uniq, изменение get_combinations к:

function get_combinations() { 
    local -a prefix_table=("${!1}") 
    local -a postfix_table=() 
    local index=0 

    combine 0 prefix_table[@] postfix_table[@] | sort | uniq 
} 

И мы сделали. Запуск этого с входом ({1..3}) напечатает:

1 
1 2 
1 2 3 
1 3 
2 
2 3 
3 

Но хорошая вещь об этой реализации является то, что, поскольку он использует ассоциативные массивы, мы можем быть на самом деле вообще, а вход что-то вроде (2 Racecar 34), который будет возвращать:

2 
2 34 
2 Racecar 
2 Racecar 34 
34 
Racecar 
Racecar 34 

В любом случае, в качестве последнего комментария, я бы сказал, начните с чего-то подобного, а затем вы сможете оптимизировать алгоритм эффективности.

Кроме того, Bash, вероятно, совсем не подходит для этого. :-D

Смежные вопросы