到达数组的最后一个索引时如何解决“索引超出范围异常”

时间:2019-10-01 09:32:14

标签: c# unity3d

我有一个脚本,用于从具有加权机会的数组中选择随机项目,并且在大多数情况下,它可以很好地工作。当索引到达数组的最后一项时,就会出现问题。

这是我的代码:

string[] grades = { "D", "C", "B", "A", "S" };
int[] weights = { 80, 140, 170, 180, 181 };
// 80, 60, 30, 10, 1

int iterations = 100;

void Update() {
    if (iterations > 0) {
        string genGrade = grades[WeightedChance(weights)];
        print("Chance: " + chance + ", Grade: " + genGrade);
        iterations--;
    }
}

int WeightedChance(int[] weights) {
    float weightSum = weights[weights.Length - 1];

    float chance = Random.Range(0f, weightSum);

    for (int i = 0; i < weights.Length - 1; i++) {
        if (chance <= weights[i]) {
            return i;
        }
    }
    return -1;
}

据我了解,当i到达数组中的最后一项时,它似乎跳过了它,然后运行return -1,给了我“ IndexOutOfRangeException”。我似乎无法理解的是为什么会这样。 chance生成一个介于0fweightSum之间的数字(在本例中为181),它们在浮动时都包含在内。之后,我检查weights中的每个元素,并查看chance生成的数字是否小于或等于每个。如果所有这些都按照我的想法运行,那么它应该总是可以选择一个权重,但是当i达到4时出了点问题(至少这是我的猜测) 。我不熟悉所有这些内容,因此如果我错过了任何重要内容或代码格式不正确,我深表歉意。

4 个答案:

答案 0 :(得分:1)

此行不正确:

for (int i = 0; i < weights.Length - 1; i++) {

您应该使用“ weights.Length”而不是“ weights.Length-1”。

您没有到达最后一个项目。

答案 1 :(得分:1)

此部分出现错误:

val1="À È Ì Ò Ù Ỳ Ǹ Ẁ"
val2 = val1
print('val1 is: ',val2)

encoded_val1=val1.encode()
print('encoded_val1 is: ',encoded_val1)

decoded_encoded_val1=encoded_val1.decode()
print('decoded_encoded_val1 is: ',decoded_encoded_val1)

proc RunCSM { scen } { catch { $scen start } if { "[$scen status]" != "SUCCESS" } { puts "$scen FAILED. Error Info:" puts "[$scen errorInfo]" ... 返回-1时,您得到 string genGrade = grades[WeightedChance(weights)]; ,这当然不在范围内

答案 2 :(得分:0)

尝试这样

void Update() {
if (iterations > 0) {
  int x= WeightedChance(weights);
   if(x>=0){
    string genGrade = grades[x];
    print("Chance: " + chance + ", Grade: " + genGrade);
    iterations--;
   }
}
}

答案 3 :(得分:0)

我认为您在for循环中误解了<运算符,这意味着该值“严格小于”您要比较的值,这意味着相等不满足此条件。

在您的情况下,您要循环到weights.Length -1,即4,但是for循环中的条件表明它应该运行直到i“严格小于” 4,因此i将达到最大值3,而不检查最后一个元素181

要解决此问题,您有2种解决方案:

  • 将运算符更改为<=(小于或等于),以涵盖i=4的情况
  • 运行for循环直至Weight.Length,不减去(如其他答案中所建议的那样)