This question already has answers here:
How to create a random permutation of an array?
(3 answers)
Closed 6 years ago.
i am doing a homework. i put rand function in a loop.
int counter = 1;
while ( counter <= 10 ){
variable1 = rand() % 5 + 1;
printf("%d", variable);
counter = counter + 1;
In this code, rand function assigns different value to variable called variable1 but sometimes it assigns same value because range of rand function is narrow. how can i perform that rand function assign different number to variable at the time when loop returns every time.
While rand() is not the greatest random function it should do the trick for many jobs and certainly for most homework. It is perfectly valid to have the same number returned twice in a row from a random function -- as the function should not have any memory of what values were previously returned.
The best way to understand this, is with an example of a coin-toss. Every coin toss is random, and the coin has no memory of the previous toss, so it is possible to flip a coin 32 times in a row and they all comes up head -- if every coin toss is a bit in a 32 bit integer you have created the binary value of integer zero.
However human tend to think (intuition) that having the same value returned more than once is "wrong" for a random function -- but our intuition is wrong on this account.
If you for some reason do want to not repeat the number from one loop to the next, then you will need to program that regardless of which random functions you use -- since any random function would be capable of returning the same values twice.
So something like this would do it;
int counter = 1;
int prevValue = -1;
while ( counter <= 10 ){
do {
variable1 = rand();
} while (variable1 == prevValue);
prevValue = variable1;
variable1 = variable1 % 5 + 1;
printf("%d", variable);
counter = counter + 1;
}
Note that this is still capable of printing the same value twice, since 10 and 15 would be different values before the %5 but would be the same after. If you want the %5 to be taken into account, so the printf never print the same value twice in a row, you would need to move the %5 inside the loop.
In your code snippet i can't find which instruction is the last one inside while. If you want to get different numbers every program run you should use srand() function before while.
But as you mentioned before. Your range (1 - 5) is to narrow to get 10 unique values every time.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int counter = 1;
int variable1 = 0;
srand(time(NULL));
while ( counter <= 10 ) {
variable1 = rand() % 5 + 1;
printf("%d ", variable1);
counter = counter + 1;
}
putchar('\n');
return 0;
}
how can i perform that rand function assign different number to variable at the time when loop returns every time?
I take this to mean OP does not want to generate the same number twice in a row.
On subsequent iterations, use %(n-1)
int main(void) {
int counter;
int variable;
for (counter = 1; counter <= 10; counter++) {
// First time in loop
if (counter <= 1) {
variable = rand() % 5 + 1;
} else {
int previous = variable;
variable = rand() % (5 - 1) + 1;
if (variable >= previous) variable++;
}
printf("%d\n", variable);
}
return 0;
}
In order to generate a unique list of random numbers, you must check each number generated against the list of numbers previously generated to insure there is no duplicate. The easiest way is to store your previously generated numbers in an array to check against. Then you simply iterate over the values in the array, and if your most recent number is already there, create a new one.
For example, you can use a simple flag to check if your are done. e.g.
while (counter < MAXI){
int done = 0;
while (!done) { /* while done remains 0 (not done) */
done = 1;
tmp = rand() % MAXI + 1; /* generate radom number */
for (i = 0; i < counter; i++) /* check again previous */
if (tmp == array[i]) /* if num already exists */
done = 0; /* set as (not done) */
}
array[counter++] = tmp; /* assign random value */
}
Or you can use the old faithful goto to do the same thing:
while (counter < MAXI) {
gennum:
tmp = rand() % MAXI + 1;
for (i = 0; i < counter; i++)
if (tmp == array[i])
goto gennum;
array[counter++] = tmp;
}
Whichever makes more sense to you. Putting together a full example, you could do:
#include <stdio.h>
#include <stdlib.h> /* for rand */
#include <time.h> /* for time */
enum { MAXI = 10 };
int main (void) {
int array[MAXI] = {0}, counter = 0, i, tmp;
srand (time (NULL)); /* initialize the semi-random number generator */
while (counter < MAXI){
int done = 0;
while (!done) { /* while done remains 0 (not done) */
done = 1;
tmp = rand() % MAXI + 1; /* generate radom number */
for (i = 0; i < counter; i++) /* check again previous */
if (tmp == array[i]) /* if num already exists */
done = 0; /* set as (not done) */
}
array[counter++] = tmp; /* assign random value */
}
for (i = 0; i < MAXI; i++)
printf (" array[%2d] = %d\n", i, array[i]);
return 0;
}
(note: the number your mod (%) the generated number by must be equal to or greater than the number of values you intend to collect -- otherwise, you cannot generate a unique list.)
Example Use/Output
$ ./bin/randarray
array[ 0] = 8
array[ 1] = 2
array[ 2] = 7
array[ 3] = 9
array[ 4] = 1
array[ 5] = 4
array[ 6] = 3
array[ 7] = 10
array[ 8] = 6
array[ 9] = 5
A Shuffled Sequence
Given the discussion in the comments, a good point was raised concerning whether your goal was to create unique set of random numbers (above) or a random set from a sequence of numbers (e.g. any sequence, say 1-50 in shuffled order). In the event you are looking for the latter, then an efficient method to create the shuffled-sequence is using a modified Fisher-Yates shuffle knows as The "inside-out" algorithm.
The algorithm allows populating an uninitialized array with a shuffled sequence from any source of numbers (whether the source can be any manner of generating numbers). Essentially, the function will swap the values within an array at the current index with the value held at a randomly generated index. An implementation would look like:
/** fill an uninitialized array using inside-out fill */
void insideout_fill (int *a, int n)
{
int i, val;
for (i = 0; i < n; i++) {
val = i ? randhq (i) : 0;
if (val != i)
a[i] = a[val];
a[val] = i; /* i here can be any source, function, etc.. */
}
}
(where randhq is any function that generates a random value (0 <= val < n))
A short example program that uses the function above to generate a shuffled array of value from 0 - (n-1) is shown below. The example generates a shuffled sequence of values in array using the inside-out algorithm, and then confirms the sequence generation by sorting the array:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void insideout_fill (int *a, int n);
int randhq (int max);
void prnarray (int *a, size_t n, size_t strd, int wdth);
int intcmp (const void *a, const void *b);
int main (int argc, char **argv) {
srand (time (NULL));
int arrsz = argc > 1 ? (int)strtol (argv[1], NULL, 10) : 50;
int array[arrsz];
insideout_fill (array, arrsz);
printf ("\n array initialized with inside-out fill:\n\n");
prnarray (array, arrsz, 10, 4);
qsort (array, arrsz, sizeof *array, intcmp);
printf ("\n value confirmation for inside-out fill:\n\n");
prnarray (array, arrsz, 10, 4);
return 0;
}
/** fill an uninitialized array using inside-out fill */
void insideout_fill (int *a, int n)
{
int i, val;
for (i = 0; i < n; i++) {
val = i ? randhq (i) : 0;
if (val != i)
a[i] = a[val];
a[val] = i; /* i here can be any source, function, etc.. */
}
}
/** high-quality random value in (0 <= val <= max) */
int randhq (int max)
{
unsigned int
/* max <= RAND_MAX < UINT_MAX, so this is okay. */
num_bins = (unsigned int) max + 1,
num_rand = (unsigned int) RAND_MAX + 1,
bin_size = num_rand / num_bins,
defect = num_rand % num_bins;
int x;
/* carefully written not to overflow */
while (num_rand - defect <= (unsigned int)(x = rand()));
/* truncated division is intentional */
return x/bin_size;
}
/** print array of size 'n' with stride 'strd' and field-width 'wdth' */
void prnarray (int *a, size_t n, size_t strd, int wdth)
{
if (!a) return;
register size_t i;
for (i = 0; i < n; i++) {
printf (" %*d", wdth, a[i]);
if (!((i + 1) % strd)) putchar ('\n');
}
}
/** qsort integer compare */
int intcmp (const void *a, const void *b)
{
return *((int *)a) - *((int *)b);
}
Example Use/Output
$ ./bin/array_io_fill
array initialized with inside-out fill:
40 15 35 17 27 28 20 14 32 39
31 25 29 45 4 16 13 9 49 7
11 23 8 33 48 37 41 34 19 38
24 26 47 44 5 0 6 21 43 10
2 1 18 22 46 30 12 42 3 36
value confirmation for inside-out fill:
0 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
Look it over and let me know if you have any questions.
Related
I'm making a program in C that factors any number using primes and saves these primes, multiplying them you find all the divisors of a number.
But I can't make an array that multiplies the previous columns and saves the results. follow the example
60 / 2
30 / 2
15 / 3
5 / 5
divisors = 2, 2, 3, 5
now i need`add 1 to array array {1, 2, 2, 3, 5}
i need this now start colune 2 {1, 2} 2 * 1 = 2 save.
next colune 3 {1, 2, 2} 2 * 1 = 2 but we already have 2 so don't save it.
continue 2 * 2 = 4 save.
colune 4 {1, 2, 2, 3} 3 * 1 = 3 save, 3 * 2 = 6 save, 3 * 4 = 12 save.
colune 5 {1, 2, 2, 3, 5} 5 * 1 = 5 save, 5* 2 = 10, 5 * 4 = 20 save, 5 * 3= 15 save, 5 * 6 = 30 save, 5 * 12 = 60 save.
now we found all divisors of 60 = 1, 2, 3, 4, 5, 6, 10 ,12 , 15,20, 30, 60.
It is important to mention that I need the program to be like this, I know there are other ways... but I only need this one, I have been unable to complete it for 1 week
video to help https://www.youtube.com/watch?v=p0v5FpONddU&t=1s&ab_channel=MATEM%C3%81TICAFORALLLUISCARLOS
my program so far
#include <stdlib.h>
#include <stdio.h>
int N = 1;
int verificarPrimo(int numero);
int main()
{
int num = 60, i, primo = 1, resultados[N], j = 1;
for (i = 0; i < 60; i++)
{
if (primo == 1)
{
resultados[N - 1] = primo;
i = 2;
primo = i;
}
if (verificarPrimo(i))
{
while (num % i == 0)
{
num = num / i;
resultados[N] = i;
N++;
}
}
}
for (i = 1; i < N; i++)
{
printf("%d \n", resultados[i]);
}
}
int verificarPrimo(int primo)
{
int i;
if (primo <= 1)
return 0;
for (i = 2; i <= primo / 2; i++)
{
if (primo % i == 0)
return 0;
}
return 1;
}
I tried out your code and ran into some issues with how the results were being stored. First off, the results array is being initially defined as an array with a size of "1", and that it not what you probably want.
int num = 60, i, primo = 1, resultados[N], j = 1;
With that in mind and determining the spirit of this project, following is tweaked version of the code to test for one or more values and their factors.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int verificarPrimo(int primo)
{
int sq = sqrt(primo) + 1; /* Usual checking for a prime number is from '2' to the square root of the number being evaluated */
if (primo <= 1)
return 0;
for (int i = 2; i < sq; i++)
{
if (primo % i == 0)
return 0;
}
return 1;
}
int main()
{
int N = 0;
int num = 0, entry = 0, resultados[100]; /* The results array needs to be defined with some value large enough to contain the assorted factors a number might have */
printf("Enter a number to evaluate for factors: "); /* Using a prompt to allow various values to be tested */
scanf("%d", &entry);
num = entry;
if (verificarPrimo(num)) /* Catchall in case the entered number is a prime number */
{
printf("This number is a prime number and has no factors other than one and itself\n");
return 0;
}
resultados[0] = 1; /* Normally the value '1' is implied in a list of factors, so these lines could be omitted */
N = 1;
for (int i = 2; i < entry; i++)
{
if (verificarPrimo(i))
{
while (num % i == 0)
{
num = num / i;
resultados[N] = i;
N++;
}
}
}
printf("Factors for %d\n", entry);
for (int i = 0; i < N; i++)
{
printf("%d ", resultados[i]);
}
printf("\n");
return 0;
}
Some items to point out in this tweaked code.
In the prime number verification function, it is usually customary to set up a for loop in testing for prime numbers to go from the value of "2" to the square root of the number being tested. There usually is no need travel to one half of the number being tested. For that, the #include <math.h> statement was added (FYI, "-lm" would need to be added to link in the math library).
Instead of defining the results array with a value of one element, an arbitrary value of "60" was chosen for the holding the possible number of results when evaluating factors for a given value. Your original code had the potential of storing data past the end of the array and causing a "smashing" error.
The value of "1" is usually left out of the list of factors for a number, but was left in as the initial result value. This might be left out of the completed code.
An additional entry field was added to allow for user entry to be tested to give the code some flexibility in testing numbers.
A test was also added to see if the entered number is itself a prime number, which would only have factors of "1" and itself.
Following is some sample terminal output testing out your original value of "60" along with some other values.
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 60
Factors for 60
1 2 2 3 5
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 63
Factors for 63
1 3 3 7
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 29
This number is a prime number and has no factors other than one and itself
Give that a try to see if it meets the spirit of your project.
I have generated an array that has 10 integers. I have to find how many times an element has been repeated, but I always get 0 as an output. Here in this code, countcolor variables is my count values. For example countcolor1 is my count value for the integer 1. Here is what I have so far:
#include <stdio.h>
#include <time.h>
int i;
double entropy_calculator(int bucket[10]);
int main() {
srand(time(NULL));
int countings;
int bucket[10];
for (i = 0; i < 10; ++i) {
bucket[i] = 1 + rand() % 10;
printf("%d \n", bucket[i]);
}
countings = entropy_calculator(bucket);
return 0;
}
double entropy_calculator(int bucket[10]) {
int x;
int countcolor1 = 0, countcolor2 = 0, countcolor3 = 0,
countcolor4 = 0, countcolor5 = 0, countcolor6 = 0;
for (x = 0; x <= 10; ++x) {
if (bucket[10] == 1)
countcolor1++;
if (bucket[10] == 2)
countcolor2++;
if (bucket[10] == 3)
countcolor3++;
if (bucket[10] == 4)
countcolor4++;
if (bucket[10] == 5)
countcolor5++;
if (bucket[10] == 6)
countcolor6++;
}
printf("%d,%d,%d,%d,%d,%d",
countcolor1, countcolor2, countcolor3,
countcolor4, countcolor5, countcolor6);
}
Notes on your code
The return type of entropy_calculator is double but you do not return anything. If you do not wish to return anything, set the return type to void.
In main, you attempt to assign the return value of entropy_calculator to an int called countings. If you are going to return some double value, countings should be a double.
Undefined behavior. According to the C Standard, behavior of a program is undefined in the event that an array subscript is out of range. bucket is an array of 10 integers. The valid indices of an array with N elements is in general 0, 1, 2, ..., N - 1; in other words, the first element is assigned the index 0, the second element is assigned the index 1, ..., the Nth element is assigned the index N - 1. Thus, the valid indices into the bucket array is any integer in the closed interval [0, 10 - 1] = [0, 9]. In your entropy_calculator function, you are attempting to access the element of bucket with index 10; the only valid indices are one of 0, 1, ..., 9.
In entropy_calculator, suppose we change all the 10s to a 9 so that the loop runs from x = 0, x = 1, .. . , x = 9 and checks of the form ([bucket[10] == j) for some j in [1, 6] are replaced with ([bucket[9] == j). All of these six checks are simply checking if the 10th element of bucket is one of 1, 2, ..., or 6. You have disregarded the other 9 randomly-generated numbers in bucket so you are never involving them in the count. You are also disregarding the other possible randomly-generated values, namely, 7, 8, 9, and 10 as you are currently only comparing the 10th element of bucket against 1, 2, ..., and 6.
Solution
I assume your task is to
generate 10 random integers in [1, 10] and store them in an array of ints, say, bucket.
create a function that accepts as an argument an array of 10 ints (i.e. a pointer to an int) and prints the number of occurrences of 1s, 2s, ..., 10s in the array.
To make the program slightly more general, we define the macro MAX_LEN and make it represent the number 10.
In main, first, we initialize the random number generator by setting the seed to the current time. Second, we define an array of MAX_LEN ints called bucket. Third, we fill each element of bucket with a pseudo-random integer in [1, MAX_LEN]. Lastly, we call the functionentropy_calculator, passing bucket as the sole argument, and then return 0.
In the function, entropy_calculator, we define an array of MAX_LEN ints called counts, with each element initialized to zero. We create our own internal mapping such that the nth element of counts represents the number of ns found in bucket, for each n in {1, 2, ..., MAX_LEN}. Equivalently, for each n in {1, 2, ..., MAX_LEN}, the number of ns found in bucket is represented by the element of counts with index n - 1. We then loop over the elements of the bucket array and, using our mapping, increment the corresponding element in the counts array. We then print out all the elements of counts.
For example, for some i in the set of valid indices of the arrays in our program, i.e. {0, 1, ..., MAX_LEN - 1}, if we find that bucket[i] is 5, then we want to increment the 5th element of counts (since the nth element of counts counts the number of ns generated) which is counts[5 - 1] or, more generally, counts[bucket[i] - 1].
Program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_LEN 10
void entropy_calculator(int bucket[]);
int main(void) {
/* initialize random number generator */
srand((unsigned) time(NULL));
/* will contain MAX_LEN random ints in [1, MAX_LEN] */
int bucket[MAX_LEN];
/* generate pseudo-random ints in [1, MAX_LEN], storing them in bucket */
for (int i = 0; i < MAX_LEN; i++) {
bucket[i] = 1 + rand() % MAX_LEN;
printf("%d\n", bucket[i]);
}
entropy_calculator(bucket);
return 0;
}
/****************************************************************************
* entropy_calculator: given an array of MAX_LEN integers in [1, MAX_LEN], * *
* prints the number of occurrences of each integer in *
* [1, MAX_LEN] in the supplied array *
****************************************************************************/
void entropy_calculator(int bucket[]) {
int counts[MAX_LEN] = {0}; /* initialize counts to all 0s */
int i; /* loop variable */
for (i = 0; i < MAX_LEN; i++)
counts[bucket[i] - 1]++;
/* printing all elements of counts */
for (i = 0; i < MAX_LEN; i++) {
if (i % 4 == 0) printf("\n");
printf(" %2d*: %d", i + 1, counts[i]);
}
printf("\n");
}
Example Session
3
9
2
6
10
9
3
8
3
1
1*: 1 2*: 1 3*: 3 4*: 0
5*: 0 6*: 1 7*: 0 8*: 1
9*: 2 10*: 1
Simplified version
If the task is to simply generate MAX_LEN (macro representing the value 10) random integers in [1, MAX_LEN] and to count how many 1s, 2s, ..., (MAX_LEN - 1), MAX_LENs are generated, then it can simply be done as follows.
We create an array of MAX_LEN integers, called counts. The valid indices associated with counts is 0, 1, ..., MAX_LEN - 1. We form our own internal mapping such that the element of counts with index n - 1 represents the number of randomly-generated ns for n in {1, 2, ..., MAX_LEN}.
As we generate a random integer in [1, MAX_LEN], we assign it to cur, and we increment the element of counts with index cur - 1 as this element represents the number of occurrences of the number cur.
Program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_LEN 10
int main(void) {
srand((unsigned) time(NULL)); /* initialize random number generator */
int counts[MAX_LEN] = {0}; /* initialize counts to all 0s */
int i, cur;
for (i = 0; i < MAX_LEN; i++) {
cur = 1 + rand() % MAX_LEN; /* pseudo-random int in [1, MAX_LEN] */
printf("%d\n", cur);
counts[cur - 1]++;
}
/* printing all elements of counts */
for (i = 0; i < MAX_LEN; i++) {
if (i % 4 == 0) printf("\n");
printf(" %2d*: %d", i + 1, counts[i]);
}
printf("\n");
return 0;
}
Example Session
8
4
6
2
4
1
10
9
2
10
1*: 1 2*: 2 3*: 0 4*: 2
5*: 0 6*: 1 7*: 0 8*: 1
9*: 1 10*: 2
#include<stdio.h>
#include<time.h>
int i;
double entropy_calculator(int bucket[10]);
int main()
{
srand(time(NULL));
int countings;
int bucket[10];
for(i=0; i<10; ++i)
{
bucket[i] = 1 + rand() % 10;
printf("%d ", bucket[i]);
}
printf("\n");
countings = entropy_calculator(bucket);
return 0;
}
double entropy_calculator(int bucket[10])
{
int x;
int countcolor1=0, countcolor2=0, countcolor3=0, countcolor4=0, countcolor5=0, countcolor6=0;
for(x=0; x<10; ++x)
{
if (bucket[9]==1)
countcolor1++;
if (bucket[9]==2)
countcolor2++;
if (bucket[9]==3)
countcolor3++;
if (bucket[9]==4)
countcolor4++;
if (bucket[9]==5)
countcolor5++;
if (bucket[9]==6)
countcolor6++;
}
printf("%d,%d,%d,%d,%d,%d",countcolor1,countcolor2,countcolor3,countcolor4,countcolor5,countcolor6);
}
Random numbers are printed in "numbers.txt". "numbers.txt" exists as a single line. The values here will be taken as two digits and assigned to the queue. I'm having trouble with the while part.
When the numbers in the Numbers.txt file are separated by two digits, I want to make the 0 in the tens digit a 1.
Example
numbers.txt :
839186660286459132876040232609
Output:
two-digit
83 91 86 66 2 86 45 91 32 87 60 40 23 26 9.
As you can see 02 and 09 written as 2 and 9. i want to 12 and 19.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 30
typedef struct stack
{
int value;
} Stack;
int *first, *last, *queue;
void kuyrukList()
{
printf("\nKuyruktaki Elemeanlar\n");
int *temp = first;
while (temp < last)
{
printf("%d ", *temp);
temp++;
}
}
void insert(int value)
{
*last = value;
last++;
}
int main()
{
//Random number.
srand(time(NULL));
int text[30] = {0};
FILE *dosyaYaz = fopen("numbers.txt", "w");
printf("\nOlusturulan number degeri:\n");
for (int i = 0; i < SIZE; i++)
{
text[i] = (rand() % 10);
printf("%d", text[i]);
fprintf(dosyaYaz, "%d", text[i]);
}
fclose(dosyaYaz);
printf("\n ");
//***********************************
char ch;
int number = 0;
int counter = 1;
queue = (int *)malloc(sizeof(int) * SIZE);
first = queue;
last = queue;
FILE *dosyaAc = fopen("numbers.txt", "r");
if (dosyaAc == NULL)
{
printf("\nDosya bulunamadi.\n");
exit(0);
}
while ((ch = fgetc(dosyaAc)) != -1)
{
if (counter % 2 == 1)
{
number += (ch - '0') * 10;
}
if (counter % 2 == 0)
{
number += (ch - '0');
insert(number);
number = 0;
}
counter++;
}
fclose(dosyaAc);
kuyrukList();
return 0;
}
So you are creating random numbers, but afterwards you modify them when they are smaller than 10? The easiest solution is to create random numbers who only vary from 10 to 99. This can be done as follows:
Imagine that double rand() generates a random number from 0 to 1 (both never being generated).
Then, 90 * rand() generates a random number from 0 to 90 (both never being generated).
Then, 10 + 90 * rand() generates a random number from 10 to 100 (both never being generated).
Then, (int)(10 + 90 * rand()) generates a random natural number, from 10 to 99 (both might be generated because of the rounding mechanism).
It appears from your stated goals that an array of 15 numbers ranging from 10 - 99 is the need. If that is true, skip writing to a file, and reading them back as a intermediate step and just create an array of 15, two digit numbers directly.
To do this, consider using a function to accept range and offset parameters (upper and lower values) and an array sized for each of the values to use with configuring rand(),.
The following can serve as the core of what you are doing by generating an array of pseudo randoms in the range you specify:
//generate an array of pseudo random values between lower and upper values
void gen_rand(int lower, int upper, int count, int *arr)
{
int i;
for (i = 0; i < count; i++)
{
arr[i] = (rand() % (upper - lower + 1)) + lower;
}
}
int main(void)
{
int arr[15];
srand(time(NULL));
gen_rand(10, 99, 15, arr);
return 0;
}
I create a program that get the input of array element size of 10. Everything getting will with the sum of even and odd number. but when it comes to the inverse it didn't work.
i created two arrays where the first getting the value from the user and second copying the element starting from end of the first array..
#include <stdio.h>
int main (){
int array[10] , i , odd =0 , even =0;
int array1[10],b;
for (i=0 ; i < 10 ; i ++){
printf("Insert number %d: ",i);
scanf("%d",&array[i]);
}
for (i=0; i < 10 ; i++){
if ( array[i] % 2 == 0){
even = even + array[i];
}
else
odd = odd + array[i];
}
printf("\n The Sum of Even Numbers in this Array = %d ", even);
printf("\n The Sum of Odd Numbers in this Array = %d ", odd);
for ( i = 10 , b =0; i>0; i-- , b++)
{
array1[b] = array[i];
}
printf("\nReverse Order:\n");
for ( b = 0 ; b< 10;b++ )
{
printf(" %d",array[b]);
}
return 0;
}
The input will be: 2 3 5 4 6 12 3 7 4 9
What I expect the out put for the reverse is: 9 4 7 3 12 6 4 5 3 2
But it gave me same value as : 2 3 5 4 6 12 3 7 4 9 .
Any Idea for how doing this reverse.?
In addition to the answer by #Yunnosch that identifies the problems in your current implementation, you can refactor (rearrange) your code to sum even and odd and reverse array into array1 in a single loop. The only other loop you need is the loop to iterate over array1 outputting the reversed array.
With a bit of re-arranging, you could do something similar to:
#include <stdio.h>
int main (void) {
int array[] = { 2, 3, 5, 4, 6, 12, 3, 7, 4, 9 }, /* array */
array1[sizeof array/sizeof *array], /* array1 */
even = 0, odd = 0; /* even/odd */
size_t n = sizeof array/sizeof *array; /* no. elem in array */
for (size_t i = 0; i < n; i++) { /* loop over each element in array */
array1[i] = array[n - i - 1]; /* reverse into array1 */
if (array[i] & 1) /* check if odd (bit-0 == 1) */
odd += array[i]; /* add value to odd */
else /* even */
even += array[i]; /* add value to even */
}
/* output results */
printf ("even sum: %d\nodd sum : %d\n\nreversed: ", even, odd);
for (size_t i = 0; i < n; i++)
printf (" %d", array1[i]);
putchar ('\n');
}
(note: you can either use if (array[i] % 2) or if (array[i] & 1) to test whether the element is odd or even. Anding with 1 simply checks whether bit-0 is 1, if it is, it's an odd number. Modern compilers will optimize to remove the division inherent to modulo, so whichever you prefer should pose no penalty)
Example Use/Output
$ ./bin/revarr
even sum: 28
odd sum : 27
reversed: 9 4 7 3 12 6 4 5 3 2
Look things over and let me know if you have questions.
You are outputting the array which you never tried to inverse.
printf(" %d",array[b]);
should be
printf(" %d",array1[b]);
Aside, the input by David C. Rankin:
Also for ( i = 10 ... and array1[b] = array[i]; assigns from beyond the end of array. It should e.g. better be
for ( i = 10 , b =0; i>0; i-- , b++)
{
array1[b] = array[i-1];
}
So I have this code that randomly generates an integer array based on user input, and puts the elements in ascending and descending order. However, currently, the code only prints the descending order twice. So I would like to know how to make a copy of the array ascd and use the copy in the piece of code that organizes the descending order. I am just a beginner, so I apologize if this is a silly question, and appreciate all the guidance I can get. Here is my code:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
int main (){
int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
for(c = 0; c<x; c++){//Randomly generating elements
srand(time(0));
ascd[kk] = (rand() %100) + 1;
}
for(c = 0; c<x; c++){ //Ascending order
for(d = 0; d<(x-c-1); d++){
if(ascd[d] > ascd[d+1]){
temp = ascd[d];
ascd[d] = ascd[d+1];
ascd[d+1] = temp;
}
}
}
for(turtle = 0; turtle<x; turtle++){//Descending order
for(e = 0; e<(x-turtle-1); e++){
if(ascd[e] < ascd[e+1]){
tempother = ascd[e];
ascd[e] = ascd[e+1];
ascd[e+1] = tempother;
}
}
}
printf("The ascending order is\n\n");
for(c = 0; c<x; c++){
printf("%d\n", ascd[c]);
}
printf("\n\nThe descending order is\n\n");
for(turtle = 0; turtle<x; turtle++){
printf("%d\n", ascd[turtle]);
}
}
There are a number of additional issues you need to consider. First always, always, validate user input. If nothing else, with the scanf family of functions, make sure the expected number of conversions were successfully performed. e.g.
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
Next, you only need to seed the random number generator once. Move srand (time (NULL)); out of the loop.
While not a requirement, it is good practice to initialize your VLA's to all zero (or some number, since you cannot provide an initializer) to eliminate the chance of an inadvertent read from an uninitialized value when iterating over the array (you can consider your filling in this case an initialization, making the memset optional here, but you won't immediately loop and fill in all cases. Something as simple as the following is sufficient if you are not immediately filling the array, e.g.
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
After filling your array, a simple memcpy will duplicate the array if you wish to preserve both ascending and descending sorts, e.g.
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
The remainder is just a bit of cleanup. Resist the urge to create a (variable next) for every value in your code. That quickly becomes unreadable. While I prefer the C89 declarations, the C99/C11 declarations inside the for block are convenient, e.g.:
for (int i = 0; i < x; i++) /* ascending order */
for (int j = 0; j < (x - i - 1); j++)
if (ascd[j] > ascd[j + 1]) {
int temp = ascd[j];
ascd[j] = ascd[j + 1];
ascd[j + 1] = temp;
}
Putting all the pieces together, and noting that main() is type int and therefore will return a value, you could tidy things up as follows. Your style is completely up to you, but the goal should be readability. e.g.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main (void) {
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
srand (time (NULL)); /* you only need do this once */
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
for (int i = 0; i < x; i++) /* ascending order */
for (int j = 0; j < (x - i - 1); j++)
if (ascd[j] > ascd[j + 1]) {
int temp = ascd[j];
ascd[j] = ascd[j + 1];
ascd[j + 1] = temp;
}
for (int i = 0; i < x; i++) /* descending order */
for (int j = 0; j < (x - i - 1); j++)
if (desc[j] < desc[j + 1]) {
int temp = desc[j];
desc[j] = desc[j + 1];
desc[j + 1] = temp;
}
printf ("\n the ascending order is\n\n");
for (int i = 0; i < x; i++) {
if (i && !(i % 10)) putchar ('\n');
printf (" %3d", ascd[i]);
}
printf ("\n\n the descending order is\n\n");
for (int i = 0; i < x; i++) {
if (i && !(i % 10)) putchar ('\n');
printf (" %3d", desc[i]);
}
putchar ('\n');
return 0;
}
Example Use/Output
$ ./bin/sort_copy
enter the number of elements for your array: 100
the ascending order is
1 1 4 4 5 5 7 8 8 9
10 13 16 16 17 20 22 22 22 23
24 24 25 27 29 29 33 35 35 35
37 38 40 41 41 41 41 42 44 45
46 48 48 48 49 50 53 54 56 57
58 59 61 61 63 64 65 65 66 66
67 68 68 70 71 73 74 74 74 75
76 80 80 80 80 82 84 84 85 85
85 85 86 88 88 89 89 90 91 91
91 92 92 93 93 93 96 99 100 100
the descending order is
100 100 99 96 93 93 93 92 92 91
91 91 90 89 89 88 88 86 85 85
85 85 84 84 82 80 80 80 80 76
75 74 74 74 73 71 70 68 68 67
66 66 65 65 64 63 61 61 59 58
57 56 54 53 50 49 48 48 48 46
45 44 42 41 41 41 41 40 38 37
35 35 35 33 29 29 27 25 24 24
23 22 22 22 20 17 16 16 13 10
9 8 8 7 5 5 4 4 1 1
Look things over and let me know if you have any questions.
Sorting with qsort
Continuing for the comment, qsort is an optimized sorting routine that is part of the C standard library (in stdlib.h) and is the go-to sort function regardless of the type of data you have to sort. The only requirement that generally catches new C programmers is the need to write a comparison function to pass to qsort so that qsort knows how you want the collection of objects sorted. qsort will compare two elements by passing a pointer to the values to the compare function you write. The declaration for the comparison is the same regardless of what you are sorting, e.g.
int compare (const void *a, const void *b);
You know you are sorting integer values, so all you need to do to sort ascending is to write a function that returns a positive value if a > b, returns zero if they are equal, and finally returns a negative value if b > a. The simple way, is to write
int compare (const void *a, const void *b) {
int x = *(int *)a;
int y = *(int *)b;
return x - y;
}
That satisfies the sort requirement for ascending order, and to sort in descending order return y - x; -- but there is a problem. If x and y happen to be large positive and large negative values, there is a potential that x - y will exceed the maximum (or minimum) value for an integer (e.g. overflow, because the result will not fit in an integer value).
The solution is simple. You can perform the same comparison, but using the results of an inequality, e.g. returning (a > b) - (a < b) for the ascending comparison, and (a < b) - (a > b) for the descending comparison. (this scheme will work for all numeric types, you just need to adjust the cast). Step though the inequality. In the ascending case, if a > b the return is 1 (e.g. return 1 - 0;). If they are equal, the inequality returns 0 (0 - 0 ), and finally if a < b, the value returned is -1 ( 0 - 1 ).
While you are free to continue to explicitly declare the x and y variables, you will generally see it written with the cast in the comparison, eliminating the need for the x and y variables altogether, e.g.
/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
/* (a > b) - (a < b) */
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}
Putting those pieces together, the same program can be written using qsort instead of the inefficient nested loops (and moving the print array routine to a function of its own) as follows,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ROW 10
int cmpascd (const void *a, const void *b);
int cmpdesc (const void *a, const void *b);
void prnarr (int *a, int n, int row);
int main (void) {
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
srand (time (NULL)); /* you only need do this once */
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
qsort (ascd, x, sizeof *ascd, cmpascd); /* qsort ascending */
qsort (desc, x, sizeof *desc, cmpdesc); /* qsort descending */
printf ("\n the ascending order is\n\n");
prnarr (ascd, x, ROW);
printf ("\n\n the descending order is\n\n");
prnarr (desc, x, ROW);
putchar ('\n');
return 0;
}
/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
/* (a > b) - (a < b) */
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}
/* integer comparison descending */
int cmpdesc (const void *a, const void *b)
{
/* (a < b) - (a > b) */
return (*(int *)a < *(int *)b) - (*(int *)a > *(int *)b);
}
void prnarr (int *a, int n, int row)
{
for (int i = 0; i < n; i++) {
printf (" %3d", a[i]);
if (i && !((i + 1) % row))
putchar ('\n');
}
}
As with the first answer, give it a try and let me know if you have any questions. (And remember to always compile with a minimum -Wall -Wextra to enable most compiler warnings -- and fix any warnings generated before you consider your code reliable -- you won't run into any circumstance where warnings can be understood and safely ignored anytime soon) Add -pedantic to see virtually all warnings that can be generated. (if you look up pedantic in Websters, you will see why that name is apt.) Just FYI, the gcc compiler string I used to compile the code was:
$ gcc -Wall -Wextra -pedantic -std=c11 -Ofast -o bin/sort_copy sort_copy.c
You print the final array twice, you can have your ascending array output by printing the values of the array right after you have done the ascending operation.
Create an another array to store descending items. You can reverse the ascending array to create the descending array. Try this code.
#include
#include
#include
#include
int main (){
int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int desc[x];
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
int z=0;
for(c = 0; c<x; c++){//Randomly generating elements
srand(time(0));
ascd[kk] = (rand() %100) + 1;
}
for(c = 0; c<x; c++){ //Ascending order
for(d = 0; d<(x-c-1); d++){
if(ascd[d] > ascd[d+1]){
temp = ascd[d];
ascd[d] = ascd[d+1];
ascd[d+1] = temp;
}
}
}
for(turtle = x-1; turtle>=0; turtle--){//Descending order
desc[z]=ascd[turtle];
z++;
}
printf("The ascending order is\n\n");
for(c = 0; c<x; c++){
printf("%d\n", ascd[c]);
}
printf("\n\nThe descending order is\n\n");
for(turtle = 0; turtle<x; turtle++){
printf("%d\n", desc[turtle]);
}
}