Array generation w/ specific parameters (a small problem)

Hi, I been trying to come up with a simple algorithm that will generate arrays of random values where;
- none of the values generated equal oneanother
- the values generated for each iteration of the loop arent equal to the 'loop value' itself (or the indice the loop is in, if you know what I mean?)

Heres what Ive done so far, I think its a bit noobish - Im sure theres an easier way of doing this though Im yet to find it;

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctime> 


using namespace std;

int main()
{

srand((unsigned)time(NULL));

int a = 7;           //input parameters linked to the main program
int ind = 4;         //number of random values to be generated
int S[ind]; 

for (int x=0;x<ind;x++)
{
    S[x] = rand()%(a-1);    //generates array
}
for (int i=0;i<ind;i++) 
{  
  int fr = 1;
      while (fr > 0)
      {
      for (int j=0;j<ind;j++)
          {
            {
             if (((j != i) & (S[i] == S[j])) | (S[i] == i))   
             {
             fr = 1;            //does this section test the values correctly for the conditions noted above?
             S[i] = rand()%(a-1);
             }
             else
             {
             fr = 0;
             break;
             }
          } 
      }    
}
}

for (int f=0;f<ind;f++)
    {
    printf("%d\n", S[f]);     //print array values
    }

cin.get();
}



So far the values Ive returned satisfy the 1st condition (that the 'array reference value isnt matched') however Im still getting values out that match eachother. Can anyone help me on this please? Im pretty sure theres an easier way but im yet to discover it...(you shouldnt underestimate the incapabilities of those at the pinnacle of relative noobdom haha). thanks alot guys, regards Ryan
In line 32
 
if (((j != i) & (S[i] == S[j])) | (S[i] == i))   


You want to use && and ||. The single operators indicate bitwise operation (they perform binary operations AND(&) and OR(|).

Way harder than it needs to be.

I would be using some algorithms to help you.

Namely, std::find().

1
2
3
4
5
6
7
int a[ 10 ]  = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int* pValue = std::find( a, a + 10, 5 ); // Find the value 5 in the array
if( pValue != a + 10 )
    std::cout << "Found the value" << std::endl;
else
    std::cout << "Didn't find the value" << std::endl;


Algorithm:


int array[ 4 ] = { 0, 0, 0, 0 };
for( elements 1 to 4 )
{
do {
Generate a random number between X and Y;
} while( number == element OR std::find( ... ) );
store number in array[ element ];
}


done.
cheers jsmith. yea that definitely seems a more concise way of doing it (heres how it looks now);

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
27
28
29
30
31
32
33
34
35
36

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>


using namespace std;

int main()
{

srand(time(NULL));

int a = 7;
int ind = 4;
int S[ind]; 
int* p;

for (int j=0;j<ind;j++)
{
    do { 
    S[j] = rand()%(a-1);
    p = (find(S, S + ind, S[j]));
    } while (S[j] == j || p != S + ind);
}

for (int f=0;f<ind;f++)
    {
    printf("%d\n", S[f]);    
    }
cin.get();
}



for some reason Im still getting an infinite loop out though, could you possibly suggest why? Im sure all it needs now is a small tweak and Im away! :) thanks
Your find() on line 25 is not right.

You are searching every element of the array every time.

But you've already filled out S[j] with the random number, and now you
are seeing if that number is in the entire array, anywhere. Obviously
it is since you just put it there.

You want to search only the elements prior to, but not including S[j].
ah ofcourse, silly mistake! Ive changed the limits of the find() function anyway, but am still managing to get infinite loops out;

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <algorithm>

using namespace std;

int main()
{

srand(time(NULL));

int a = 7;
int ind = 3;
int S[ind];
int* p; 

do {
S[0] = rand()%(a-1);
} while (S[0] == 0); 

for (int j=1;j<ind;j++)
{
    do { 
    S[j] = rand()%(a-1);
    p = find(S, S + j, S[j]);
    } while ((S[j] == j) || p != (S + ind));
}

for (int f=0;f<ind;f++)
    {
    printf("%d\n", S[f]);    
    }
cin.get();
}



I know its the 'find' thats causing the infinite loop because taking it out eradicates this problem, however...looking at it now it shouldnt be causing errors right (im probably missing something blatantly obvious)? cheers for the help and patience so far anyway mate, its most definitely appreciated :)
Last edited on
On line 30 ind should be j.

Why do you always use a - 1? Why not just make a one less if you always use it that way? Assuming you actually want random numbers from 0 to a - 1 inclusive, you should just use rand() % a.

Your first do-while loop can be replaced with S[0] = rand() % (a - 1) + 1. That will give a number between 1 and a-1 inclusive.
You don't need the loop on 21-23 at all; it can be done as part of the loop on 27-30.

The definition of std::find is (paraphrased):

template< typename Iter, typename T >
Iter find( Iter first, Iter last, T value );

where first points to the first element to compare;
last points to one past the last element to compare;
value is the value to search for.

This means that find( S, S, 4 ) will always return S (ie, last... ie, not found).

So:

int array[ 10 ] = { 0, 1, 2, 3, 4, 10, 6, 7, 8, 9 };

find( array, array + 5, 10 ) == array + 5 == not found,
since only elements array[0] through array[4] inclusive are searched.

On line 30 you are comparing P against S + ind, which is beyond what your find looks
at on line 29, since j is always less than ind.

Summary:
remove lines 21-23;
line 25 should iterate beginning at 0;
line 30 p comparison needs to compare against last. last in your case is S + j.
that's brilliant, cheers guys, yea I was misunderstanding what limit the find() function returns when not satisfied but its sorted now :) just a quick question - I was hoping to use the array elements that have been formed as references for another array in doing some calculations etc (this is for my research project) however have encountered an unforeseen issue. Is it possible to double reference arrays in this fashion? i.e.

1
2
3
4
5
6
7
8
9

for (int m=0; m < a; m++)              //a - user declared variable
   {
   for (int G = 0; G < ind; G++)
      {
       B[m] = B[m] + A[S[G]]                    //A - preformed array of values, B is formed using these.
      }               
   }


I've just tried doing this but the values within B Im getting out are grotesquely large and definitely incorrect (something to do with the rand() seed generator I suspect?). cheers
If A is an array containing N elements, and S is an array containing "ind" elements, then as long as for all G, S[G] is an integer between [0,N-1] inclusive then you are fine.
Topic archived. No new replies allowed.