Bill Gary
Bill Gary

Reputation: 3005

Random accessing array, how to skip duplicates?

I have an XML array that I access to pull a random question from. How would I go about making sure there is no duplicates pulled? My current code follows.

    private void getQuestion() {
    // TODO Auto-generated method stub

    res = getResources();
    qString = res.getStringArray(R.array.questions);

    rQuestion = qString[rgenerator.nextInt(qString.length)];

    tokens = new StringTokenizer(rQuestion, ":");
    wordCount = tokens.countTokens();
    sep = new String[wordCount];
    wArray = 0;
    while (tokens.hasMoreTokens()) {
        sep[wArray] = tokens.nextToken();
        wArray++;
    }

}

Any help would be appreciated.

Upvotes: 1

Views: 508

Answers (4)

Maarten Bodewes
Maarten Bodewes

Reputation: 93968

You are better off putting that array of questions in a list and use Collections.shuffle(). After that, simply iterate through the list. More information can be found at this related answer.

This solution will cost some memory for duplicating the list, but remember that the strings themselves won't be copied, only the references to the questions are. For maximum performance, use a list with random access (ArrayList), or use that as a replacement for the array. If you don't theshuffle method will create one internally.

Upvotes: 0

Bill Gary
Bill Gary

Reputation: 3005

I figured it out. I switched it to

private void getQuestion() {
    res = getResources();
    qString = res.getStringArray(R.array.questions);
    arrayLength = qString.length;
    qTotal = arrayLength;

}

private void getRandom() {
    rnd = rgenerator.nextInt(arrayLength);
    rQuestion = qString[rnd];
    qString[rnd] = "used";
    seperate();

}

private void seperate() {
    if (rQuestion != "used") {
        tokens = new StringTokenizer(rQuestion, ":");
        wordCount = tokens.countTokens();
        sep = new String[wordCount];
        wArray = 0;
        while (tokens.hasMoreTokens()) {
            sep[wArray] = tokens.nextToken();
            wArray++;
        }
        qNumber++;
    } else {
        if (qNumber < qTotal) {
            getRandom();
        } else {
            startActivity(new Intent("com.example.END"));
        }
    }

}

It gets the array from resources, then pulls a random question from the array. It then sets that one to "used" and splits it. It also checks to see if the pulled question is "used, and if it is, it pulls another question. It also goes to the end game activity if all questions are "used"

Upvotes: -1

Graham Smith
Graham Smith

Reputation: 25757

If you want a fast way of getting only unique values from an array this link has a very fast method. Below uses an ArrayList, but it will not be hard for you to convert from string array to an ArrayList - or just use ArrayLists instead.

e.g. new ArrayList(Arrays.asList(myArray));

In short you use a hashset to only get unique values using this method

public static ArrayList GetUniqueValues(Collection values)
{
    return new ArrayList(new HashSet(values));
}

Then use it like so

ArrayList x = new ArrayList();
x.add("abc");
x.add("abc");
x.add("abc");
x.add("def");
x.add("def");
x.add("ghi");

for (Object y : GetUniqueValues(x))
    Log.d("something", y); //ok lets print the value

To yield the result of "abc, def, and ghi"

To be clear I agree with Travis to ask why you have duplicates. The above is to answer the question.

Upvotes: -1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272497

The Fisher-Yates shuffle is an algorithm that is more or less designed for this purpose.

Upvotes: 5

Related Questions