변수를 배열의 임의 항목으로 설정할 때 확률을 어떻게 지정합니까?

변수를 배열의 임의 항목으로 설정할 때 확률을 어떻게 지정합니까?

현재 저는 배열의 임의 항목에 변수를 설정하기 위해 다음과 같은 작업을 수행합니다.

array=("foo" "bar" "baz")

var=${array[$RANDOM % ${#array[@]} ]}

이러한 값 중 하나로 설정하고 싶지만 변수가 각 항목의 값으로 개별적으로 설정될 가능성을 지정하면 $var어떻게 되나요 ? 73.3%의 확률 foo, 26.6%의 확률 bar, 0.1%의 확률을 원한다고 가정해 보겠습니다 baz.

답변1

한 가지 방법은 병렬 배열을 구축하고 아래에서 해당 백분율 확률을 설정하고 이를 1000으로 조정하는 것입니다. 그런 다음 1에서 1000 사이의 임의의 숫자를 선택하고 기회가 없어질 때까지 배열을 반복합니다.

#!/bin/bash

array=( "foo"  "bar" "baz")
chances=(733    266     1)

choice=$((1 + (RANDOM % 1000)))
value=

for((index=0; index < ${#array[@]}; index++))
do
  choice=$((choice - ${chances[index]}))
  if [[ choice -le 0 ]]
  then
    value=${array[index]}
    break
  fi
done

[[ index -eq ${#array[@]} ]] && value=${array[index]}
printf '%s\n' "$value"

답변2

쉘은 부동 소수점 연산을 수행할 수 없지만 소수점만 이동하면 $RANDOM정수 연산을 사용할 수 있습니다.

#!/usr/local/bin/bash
array=("foo" "bar" "baz")
dieroll=$(($RANDOM % 1000))

if [[ "$dieroll" -lt 1 ]]; then
  printf "%s\n" "${array[2]}"
elif [[ "$dieroll" -lt 266 ]]; then
  printf "%s\n" "${array[1]}"
else
  printf "%s\n" "${array[0]}"
fi

이것의 장점은 배열을 1000개 항목으로 늘리거나 루프를 요구할 필요가 없다는 것입니다 for.

관련 정보