4

this is the part of my code I'm having trouble with. I can't understand why its doing it wrong. I have an array where it stores numbers 0 - 25 which are cases. The numbers are to be randomized and overwritten into the array. Only condition is is that no number can be doulbes, there can only be one of that number. I'm not asking you to do my code but do hint me or point me in the write directions. I am trying to learn :)

The problem lies within the second do loop. I can get the numbers to be randomized, but I get doubles. I have created a loop to check and fix this, but it's not working. The code does run, and doubles do still happen and I can't see why. It looks correct to me. Please look, thank you (:

This is what I have done originally (at the very end is where I am at now):

int check_double = 0;
int i = 0;
int counter = 0;
int array_adder = 0;
int random_number = 0;

int cases[] = {
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
    };

float money[] = {
    0.01,1,5,10,25,50,75,100,200,300,400,500,750,1000,5000,10000,25000,50000,750000,100000,200000,300000,400000,500000,750000,1000000
    };

//Randomize all case number and realine them in the array
srand ( time(NULL) );
do
{
    cases[counter]= rand() % 26;
    counter += 1;
    printf("%d\n", cases[counter]);
}
while (counter <= 25);

//make sure there are no doubles in the array, just 0 - 25 and not a single number repeated twice
do
{
    check_double = 0;

    for (i = 0; i < counter; i++)
    {
        if (cases[counter] == cases[i])
        {
            cases[counter] = rand()% 26;
            check_double == 1;
        }
    }
}

while (check_double != 0);

Currently, what I had achived after that was combing both loops and check for doubles as the array goes. This is what I made, it still has doubles and im not sure why, I only posted the cose with both loops combined:

do
{

cases[counter]= rand() % 26;

if (cases[counter]>=1);

    for(i=0;i<=counter;i++)

    if (cases[counter]==cases[i])
        {
            cases[counter]=rand()% 26;
        }

printf("%d\n",cases[counter]);
counter+=1;
}
2
  • This answer to a different question may be helpful to you. Commented Sep 21, 2011 at 5:23
  • The normal way to handle that is to load the array with the values 0..25 (or other range) and then shuffle it. There are more and less correct ways of shuffling the array, but you end up with a pure permutation of the guaranteed unique values. Commented Sep 21, 2011 at 7:20

5 Answers 5

2

Robsta, you could try the following piece of code, I have run this in Dev-C++, any changes that you require can be made from your side. But, I assure you that this code generates what you intend.

int check_double = 0;
int i = 0;
int counter = 0;

int cases[] = {
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
    };
//Randomize all case number and realine them in the array
srand ( time(NULL) );
do
{

cases[counter]= rand() % 26;

   for(i=0;i<counter;i++)
    if (cases[counter]==cases[i]){
      while (cases[counter]==cases[i])
        {
            cases[counter]=rand()% 26;
        }
      i=0;
    }

printf("%d\t%d\n",counter,cases[counter]);
counter+=1;
}while (counter <= 25);

If you have any clarifications required, I would love to discuss with you.

-Sandip

Sign up to request clarification or add additional context in comments.

7 Comments

So making i=0 again after the inital while loop, that does it? I've been playing with this all night. I'm 100% new to C and new to array, and this random. So this has been quite hard for me. Thank you.
MY friend. This is EXACLY what I need. Alot of people on this website helped me with it and hinted me, and all gave me diffrent ways. Your way is the way that I wanted and I believe is what user "LaceySnr" wanted or hinted me towards but I couldn't catch it. Thank you.
It turns out this way didnt work prefectly. it still gave a double. But, only one double. and it was the very first number.
Hi, Robsta. I actually put i=0 again to recheck if the new random number generated isn't the same as some other number way below in the array. And this way I reached a solution. If you still are getting a double (even once), its something to be thought of seriously. Could you please provide the set of output that you obtained in that double case (I hope you had written it into a file) if possible. And please take care that you need not put the statement if (cases[counter]>=1) as it was in your revised code as it would be a huge source of bug. I would love to discuss further on this.
Hi, Robsta. The bug was from my side. I am really sorry I didn't take care of that.... You only have to replace i=0 with i=-1. Rest its the same and you get the correct results. This time I crossed checked it. I did that because after i=0 is executed it gets incremented to i=1 because of the loop's increment. So, I made it to i=-1 so that it finally comes to i=0 even after the loop's increment.
|
1

You're only ever writing over the last value in the array:

for(i=0;i<counter;i++)
    if (cases[counter]==cases[i])

You need to loop through as you are, then have an inner loop, where you compare all the other entries to the current one.

Even easier would be to do the loop where you set each random number, so when you set cases[3] for example, loop from 0 to 2 and check to see if your new value for 3 clashes, if so, wash - rinse - repeat!

9 Comments

Set each random number? You mean up in my first do loop? and I understand what you mean about that, that makes sense.
Yeah that's it, pick a number, test to see if it's valid, if not then pick another. That way should also be more efficient than the way you have it now as you won't have to look at the array entries after the one you're examining.
ahhhhhh. I get what your saying. Okay. I'll give it a go and post back my sucesss (:
Good luck :) Didn't want to be too precise so that you could work it out for yourself!
Of course. I updated my comment. Take a look at the very end, I tried to do what you said/hinted but it didn't work out. Any more clues as to what I'm doing wrong? It's still doing doubles :/
|
1

You have this line of code:

check_double==1;

That doesn't change check_double because it's ==, not =. == compares; it doesn't assign. Change that line to this:

check_double=1;

A helpful compiler (clang in this example) will give you a warning about this:

test.c:5:14: warning: expression result unused [-Wunused-value]
        check_double==1;
        ~~~~~~~~~~~~^ ~

1 Comment

Thank you. That I didn't notice D: But I apreciate you telling me that, although. It still didn't fix my problem :/
1

You can't check for duplicates with a single loop. You need to at least compare every possible pair of elements to be able to see if there's a duplicate. I'm guessing you forgot to loop over counter somewhere inside the second do...while?

Note that your method is not guaranteed to terminate. (Very, very likely but not certain.) Why don't you simply shuffle the cases array? Shuffling is simple but tricky; see Fisher-Yates (or Knuth) Shuffle for a simple algorithm.

4 Comments

Hey, thanks. I'll take a look at that. I never knew of such a way. What do you mean add another loop?
Right now you're checking if any element is equal to cases[26] which doesn't even exist. I think you meant something along the lines of for i=0 to 26 .. for j=i+1 to 26 .. if cases[i] == cases[j] then duplicate; regenerate and recheck? If that's the case you missed a loop.
BTW, you can check for duplicates with a single loop (using O(N) memory along with the O(N) running time), but that's even more complicated. I'd simply shuffle the array once and be done with it.
The thing is, if I were to do a shuffle I'd have to explain how to do one or how I achived one/learned it. So I'm going to read more into that shuffle, and if it works, then perfect (:
1

If you are asking how to randomly sequence the number 1-25 then you could do something like this. This is a very brute-force way of generating the sequence, but it does work and might give you a starting point for something more optimized.

#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#include <conio.h>

const int LastNumber = 25;

bool HasEmpty(int available[LastNumber][2])
{
    bool result = false;
    for(int i = 0; i < LastNumber; i++)
    {
        if (available[i][1] == 0)
        {
            result = true;
            break;
        }
    }

    return result;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int available[LastNumber][2];
    int newSequence[LastNumber];

    srand((unsigned int)time(NULL));

    for(int i = 0; i < LastNumber; i++)
    {
        available[i][0]=i;
        available[i][1]=0;
    }

    int usedIndex = 0;

    while (HasEmpty(available))
    {
         int temp = rand() % (LastNumber + 1);
         if (available[temp][1] == 0)
         {
             newSequence[usedIndex++] = available[temp][0];
             available[temp][1] = 1;
         }
    }   

    for(int i = 0; i < LastNumber; i++)
    {
        printf("%d\n",newSequence[i]);
    }

    getch();

    return 0;
}

1 Comment

That is defeintly a new way to look at it and I never thought of it. I'm going to take a closer look into this. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.