I want to generate numbers from 1 to 10 in an array, then print them in descending order. The method I’ve used so far doesn’t work properly. Sometimes the number 10 is at the bottom, and all other numbers are correctly ordered.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int a[7], j, i;
srand(time(NULL));
a[0] = rand() % 10;
int length = 7;
for(int i = 0; i < 7; i++) {
int duplikat = 0;
a[i] = rand() % 10+1;
for (int j=0; j<i; j++) {
// descending order: Just change (a[j] > a[j+1])
if(a[i] == a[j]) duplikat = 1;
if (a[j] < a[j+1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
if (duplikat) i--;
}
}
for(int i = 0; i< length; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
printf("\n");
for(j=0;j<7;j++) printf("\n%d ", a[j]);
return 0;
}
Some observations:
The line if (duplikat) i--; should be outside the inner loop over j, so that you decrease i at most once when a dupicate is found.
Fiddling with the index of a for loop to implement some skipping logic is also very brittle. Instead, consider a while loop until your array a is full where you add items only if they are no duplicates.
If you want to "bubble down" the new number so that the part of the array is sorted, you must start from the right-hand side of the array. Otherwise, the only swap that may take place is of the new item with the last item in the array.
You could do something similar to insertion sort, where you keep the generated array sorted at all times:
Determine a new random number to add, the "pick".
Find the place i where the pick goes; if the number was already generated, pick again.
Otherwise, create an empty slot at the end of the array by incrementing the actual length, then move all elements right of the i one place to the right. There is now a gap at i, where you place your pick.
Repeat until your array has enough items.
In code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int a[7];
int length = 7; // desired length of array
int n = 0; // current length of array
srand(time(NULL));
while (n < length) {
int pick = rand() % 10 + 1;
int i = 0;
// skip greater elements
while (i < n && pick < a[i]) i++;
// shift smaller elements and add pick if it is unique
if (i == n || pick != a[i]) {
int j = n++;
while (i < j) {
a[j] = a[j - 1];
j--;
}
a[i] = pick;
}
}
// print array
for (int i = 0; i< length; i++) {
if (i) printf(", ");
printf("%d", a[i]);
}
printf("\n");
return 0;
}
Related
I want to give an array of a specific length a random number generated to each elements value where the values are varying.
srand(time(NULL));
int n = 8; //n is given for the sake of this example
int r[n];
for (int i = 0; i < n; i++)
{
r[i] = (rand() % n) + 1;
for (int j = 0; j < i; j++)
{
if (r[i] != r[j])
{
return 0;
}
else
{
while (r[i] == r[j])
{
r[i] = (rand() % n) + 1;
}
}
}
The problem is that the while loop doesn't go through every single element in the array "r" which most likely will give the array multiple elements with the same value since it only checks for one element and not the ones before.
In conclusion I need help to check for all elements and somehow eliminate the ones already chosen.
Your description of your requirement is ambiguous, but your code appears to be an attempt at a randomly ordered sequence of values from 1 to n inclusive.
That being the case, a simpler and more deterministic method than picking a random number than checking if it has already been used is simply to generate the values sequentially, then shuffle the array.
// Create an array of n elements
int* r = malloc( n * sizeof(*r) ) ;
// Fill the array with values 1 to n
for( size_t i = 0; i < n; i++ )
{
r[i] = i + 1 ;
}
// Shuffle the array
for( size_t i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
int t = r[j];
r[j] = r[i];
r[i] = t;
}
You logic is sound albeit not very efficient.
But you're missing an array and your loops don't work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main ()
{
srand(time(NULL));
int r[8]; // this is an array
int n = 8; //n is given for the sake of this example
for (int i=0; i<n; i++)
{
r[i] = (rand() % n) + 1;
for (int j = 0; j < i; j++)
{
if (r[i] == r[j]) // if duplicate
{
i--; // go back
break; // and try again
}
}
}
for (int i=0; i<n; i++) printf ("%d,",r[i]);
printf ("\n");
}
I want to put random numbers from 1 to 16 in a two-dimensional array without duplication.
I made a code that eliminates duplicates and puts new random numbers back into the array, but it keeps printing duplicate numbers.
Which part is wrong and why?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int A[4][4];
int i, j, k, l;
int num;
srand(time(NULL));
int count;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
//Re:
num = rand() % 16 + 1;
A[i][j] = num;
for(k = 0; k <= i; k++)
{
count = 0;
for(l = 0; l <= j; l++)
{
if(A[k][l] == num)
{
if(k != i && l != j)
{
j--;
count = 1;
break;
// goto Re;
}
}
}
if(count == 1)
break;
}
}
}
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
printf("%3d", A[i][j]);
}
printf("\n");
}
}
I want to put random numbers from 1 to 16 in a two-dimensional array without duplication. I made a code that eliminates duplicates and puts new random numbers back into the array, but it keeps printing duplicate numbers.
Put the numbers 1,…,16 into an array tmp.
Perform a Fisher-Yates shuffle on tmp.
Iterate through tmp to copy its elements to A using the mapping A[i/4][i%4] = tmp[i].
If you’re not convinced, try a few values of i by hand to assure yourself this works.
Can someone please help me i am facing runtime error while solving this problem.
I have first defined the integers and then used scanf to take the input.
Then i check whether the 2 consecutive elements of array are equal are not.
if they are equal i equate j variable to i+1 and so that it can traverse and find if same duplicate elements are side by side (eg- 15 15 15).
I increment the j element till a[j] is equal to a[i].
Then using i try to print the number with the number of occurences of it which is j-i and then assign i with vakue of j-1.
#include <stdio.h>
int main()
{
int n,j=0,i;
scanf("%d",&n);
int a[n];
for (i = 0; i < n; ++i) {
scanf("%d",&a[i]);
}
for (i = 0; i < n - 1; ++i)
{
if(a[i]==a[i+1])
{
j=i+1;
while(j<n && a[i]==a[j])
{
j++;
}
printf("%d is appearing %d times\n",a[i],j-i);
}
i=j-1;
}
return 0;
}
The input array needs to be sorted first to count duplicated, the loop logic needs to be fixed to reassign the index i.
A fixed code might like this:
#include <stdio.h>
#include <stdlib.h>
static int cmp_intp(const void *p1, const void *p2) {
return *(const int *)p1 > *(const int *)p2;
}
int main() {
int n, j = 0, i;
scanf("%d", &n);
int a[n];
for (i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
qsort(a, n, sizeof(a[0]), cmp_intp);
for (i = 0; i < n;) {
if (i < n - 1 && a[i] == a[i + 1]) {
j = i + 1;
while (j < n && a[i] == a[j]) {
j++;
}
printf("%d is appearing %d times\n", a[i], j - i);
i = j;
} else {
++i;
}
}
return 0;
}
The problem is created by the line,
i=j-1;
in the case when two consecutive elements are not equal.
move it within the if condition.
Looking for help describing this Algorithm for sorting an array. Is it a bubble or selection sort? Why do the elements switch?
#include <stdio.h> //including stdio.h for printf and other functions
#include <conio.h> //including conio.h for _getch() and other functions
int main() //default function for call
{
int a[10] = { 2,4,6,8 }; //Array declaration size-10
int n = 4; //Temporary number for array size
printf("\n\nArray Data : ");
flushall(); //Printing message
for (int i = 0; i < n; i++) //Loop for displaying the data of array
{
printf(" %d ", a[i]); //Printing data
}
for (int i = 0; i < n; i++) //Loop for ascending ordering
{
for (int j = 0; j < n; j++) //Loop for comparing other values
{
if (a[j] > a[i]) //Comparing other array elements
{
int tmp = a[i]; //Using temporary variable for storing last value
a[i] = a[j]; //replacing value
a[j] = tmp; //storing last value
}
}
}
}
This is a less efficient way of bubble sort.
You can find explanations here :
https://en.wikipedia.org/wiki/Bubble_sort#Step-by-step_example
A better code will be
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
// swap temp and arr[i]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
It reduces number of comparisons and looping by optimizing the upper limit of loops.
You can see a video on this here.
I have a task to sort negative and positive numbers while using dynamic memory, therefore in this case I used calloc and bubble sort to arrange negative numbers first while not changing their order. The problem is when I enter an even number of integers, in the middle of the result some random negative number of 10 digits appears. The same doesn't happen with odd number of integers. What seems to be the problem?
#include <stdio.h>
#include <stdlib.h>
#define SIZE 1000
void swap(int *arr, int n) {
int i, j, temp;
for (i = 0; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (arr[j] < 0) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
printf("sorted integers to negative and positive: \n");
for (i = 0; i < n; i++) {
printf("%i ", arr[i]);
}
}
int main() {
int n;
int i, *sk;
printf("Enter integer: \n");
scanf("%d", &n);
printf("Enter %i integers: \n", n);
sk = (int*)calloc(sizeof(int), n);
for (i = 0; i < n; i++) {
scanf("%d", sk + i);
}
swap(sk, n);
return 0;
}
This is undefined behavior that happens to manifest itself to you only when you happen to enter an even number of integers, but in reality the problem is always there: you read a value from one-past-the-end of the array, and it makes its way to the middle of your array.
You can fix this behavior by changing i <= n and j <= n with i < n and j < n. However, this is not going to fix your broken sorting algorithm, because the swapping condition is incorrect as well. Instead of
if(arr[j]<0)
it should be
if(arr[j]<arr[j-1])
You have 2 classic bugs in your for loops:
for (i = 0; i <= n; i++) is almost always wrong because the loop is run n + 1 times, where it should only enumerate index values from 0 to n - 1.
You have the same off by one error in the second loop: the test j <= n makes you go one step too far and read beyond the end of the array. Some random value gets shuffled into the array, but this undefined behavior could have worse consequences.
Furthermore, your comparison test is incorrect, it should be if (arr[j] < arr[j-1]).
As a rule of thumb, whenever you see the <= operator in a loop test, look again, it is probably a bug.
Here is a corrected version:
void swap(int *arr, int n) {
int i, j, temp;
for (i = 0; i < n; i++) {
for (j = 1; j < n; j++) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
printf("sorted integers to negative and positive: \n");
for (i = 0; i < n; i++) {
printf("%i ", arr[i]);
}
printf("\n");
}