Actionscript 3 цикла while с indexOf - PullRequest
       1

Actionscript 3 цикла while с indexOf

0 голосов
/ 21 апреля 2010

Есть ли причина, почему этот цикл застревает? Я не могу понять, как это происходит:

var i:Number = -1;
do
{
i = Math.round(Math.random() * _totalQuestions);
}
while(_usedQuestions.indexOf(i));

Где _usedQuestions - это массив чисел. Этот массив начинается пустым.

Спасибо!

Редактировать: я хочу, чтобы цикл завершился, если я НЕ найден в массиве ... таким образом, я знаю, что выбранный мной вопрос ранее не задавался.

Ответы [ 3 ]

1 голос
/ 22 апреля 2010

Здесь действительно два ответа.

  1. Цикл никогда не завершается, потому что Array.indexOf() возвращает -1, если аргумент не найден, а -1 имеет значение true в логическом контексте. Единственный выход из вашего цикла - это если i равно _usedQuestions[0].

  2. Это может быть неочевидно, но даже если вы исправите вышеуказанную проблему, ваш цикл все равно не сможет завершиться после того, как все вопросы будут использованы ... и это ваша настоящая проблема - вы используете запутанный алгоритм сделать что-то простое.

Было бы гораздо разумнее просто сохранить два массива - один из невидимых вопросов и один из увиденных вопросов. Каждый раз, когда вы выбираете новый вопрос, просто удалите его из unseen и добавьте его к seen. Как это:

if (unseen.length > 0) {
    var i:int = Math.floor( Math.random() * unseen.length );
    seen.push( unseen[i] );
    unseen.splice(i, 1);
} else // all questions seen...

Помните: написание программ, которые работают правильно, является лишь минимальным требованием программирования. хороший программист пишет программы, которые легко понимают и люди! И большая часть этого заключается в том, чтобы простые вещи делались простыми способами. (Если производительность не является неизбежным фактором - но в этом случае я абсолютно обещаю, что это не будет!)

0 голосов
/ 21 апреля 2010

indexOf вернет -1, если ничего не найдено, поэтому используйте это значение, а также для избежания проверки бесконечного цикла, что _useQuestions не содержит все ваши totalQuestions:

Редактировать : более полная версия для иллюстрации:

var checked:int = 0;
var seen:Dictionary = new Dictionary();
while (checked < _totalQuestions) {
    var i:int = int(Math.random() * _totalQuestions);
    if (_usedQuestions.indexOf(i) < 0) {
        break;
    } else if (seen[i] === undefined) {
        seen[i] = i;
        checked++;
    }
}
if (checked < _totalQuestions) {
    //ok you have found a non used questions
} else {
    // all questions have been used
}
0 голосов
/ 21 апреля 2010

Попробуйте это.

    var i:Number = -1;
    var found:Boolean;
    do
    {
        i = Math.round(Math.random() * _totalQuestions);

        found = false;
        for (var j:int = 0; j < _usedQuestions.length; j++)
        {
            // assume that _usedQuestions is an array which holds the question
            // number that has been selected before
            if (_usedQuestions[j] == i)
            {
                found = true;
                // get out of for loop if found, we'll need to get another
                // random number
                break;
            }
        }
    }
    while (found);  

Я не очень разбираюсь в AS3, так как только начал изучать его, чтобы у кого-то был более эффективный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...