Ordering numbers in an array - c

# include <stdio.h>
# include <stdlib.h>
# include <time.h>
int main(){
int i, n, A[10] = {0}, B[10] = {0};
srand((unsigned)time(NULL));
printf("Shift how many elements? ");
scanf("%d", &n);
for (i = 0; i < 10; i++){
A[i] = rand()%10;
printf("%d ", A[i]);
}
printf("\n\n\n");
for (i = 0; i < 10; i++){
B[i + n] = A[i]; *******
}
for (i = 0; i < 10; i++){
printf("%d ", B[i]);
}
return 0;
}
I'm trying to write a code that shifts the numbers in the array by a value entered by the user but I really don't know how to deal with the indexing, if the number is at the end and you add number to it it might go outside the array so how do i prevent that. Pay attention
to the line with asterisks. If you can, please give me a brief explanation of array indexing while coding, or hints about what I can do to fix this. I know my mistake however, I just don't know how to fix it.
This language is C and I'm using code::blocks. Thank you!

You can use modulo (%) operator to get the correct indexing:
for (i = 0; i < 10; i++){
B[ (i + n) % 10 ] = A[i];
}
I have used 10 directly. In general, you should use sizeof(B) or actual number of elements in the array if it's less than size of the array.

You can use a wraparound condition for this.
for (i = 0; i < 10; i++){
B[i] = A[(i+n) % 10]; // to shift elements to the left by n
//B[(i+n) % 10 ] = A[i]; // to shift right
}

Related

Is it the efficeint program to rotate array in left direction?

#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j,l,m,n;
j=0;
printf("\nenter 5 element single dimension array\n");
printf("enter shift rate\n");
scanf("%d",&n);
/* Here we take input from user that by what times user wants to rotate the array in left. */
int arr[5],arrb[n];
for(i=0;i<=4;i++){
scanf("%d",&arr[i]);
}
/* Here we have taken another array. */
for(i=0;i<=4;i++){
printf("%d",arr[i]);
}
for(i=0;i<n;i++){
arrb[j]=arr[i];
j++;
// These loop will shift array element to left by position which's entered by user.
}
printf("\n");
for(i=0;i<=3;i++){
arr[i]=arr[i+n];
}
for(i=0;i<=4;i++){
if(n==1 && i==4)
break;
if(n==2 && i==3)
break;
if(n==3 && i==2)
break;
printf("%d",arr[i]);
}
//To combine these two arrays. Make it look like single array instead of two
for(i=0;i<n;i++){
printf("%d",arrb[i]);
}
// Final sorted array will get printed here
}
Is it the efficeint program to rotate array in left direction?
Actually, very complicated, and some problems contained:
for(i = 0; i < n; i++)
{
arrb[j] = arr[i];
j++;
}
Why not simply:
for(i = 0; i < n; i++)
{
arrb[i] = arr[i];
}
There is no need for a second variable. Still, if n is greater than five, you get into trouble, as you will access arr out of its bounts (undefined behaviour!). At least, you should check the user input!
for(i = 0; i <=3 ; i++)
{
arr[i] = arr[i + n];
}
Same problem: last accessible index is 4 (four), so n must not exceed 1, or you again access the array out of bounds...
Those many 'if's within the printing loop for the first array cannot be efficient...
You can have it much, much simpler:
int arr[5], arrb[5];
// ^
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5];
This does not cover negative values of n, though.
arrb[i] = arr[(((i + n) % 5) + 5) % 5];
would be safe even for negative values... All you need now for the output is:
for(int i = 0; i < 5; ++i)
printf("%d ", arrb[i]);
There would be one last point uncovered, though: if user enters for n a value greater than INT_MAX - 4, you get a signed integer overflow, which again is undefined behaviour!
We can again cover this by changing the index formula:
arrb[i] = arr[(5 + i + (n % 5)) % 5];
n % 5 is invariant, so we can move it out of the loop:
n %= 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(5 + i + n) % 5];
Finally, if we make n positive already outside, we can spare the addition in the for loop.
n = ((n % 5) + 5) % 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5]; // my original formula again...
Last step is especially worth considering for very long running loops.
I think you want to do something like this (you should check that 0 <= n <= 5, too):
int b[5];
int k = 0;
for(i=0; i<5; i++){
if (i < 5 - n)
b[i] = arr[i+n];
else
{
b[i] = arr[k];
k++;
}
}
Array b is used to save the rotated matrix.

Generate array of unique characters in C

I'm trying to generate an array of 10 random but unique characters. Sometimes when I run the code, characters are not unique.
I would appreciate any help. Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
char letters[10];
for (int i = 0; i < 10; i++) {
letters[i] = 97 + rand() % (122-97);
for (int j = 1; j < i; j++) {
if (letters[i]==letters[j]) {
letters[i] = 97 + rand() % (122-97); // continue
}
}
printf("%c\n", letters[i]);
}
}
The problem is that random can give the same number. It doesn't know you want a different number every time.
This is how to solve this, I am telling you the way, you will need to program it.
Decide what characters are participating, then create an array that holds these characters.
Then roll the dice to give a number within the array range. The number you get is an index to the array, you then take the character in that index.
Then you take the last characters in the array and put in that index, and the next time you roll the dice you limit the max number to one less the original size of the array.
You continue with this algorithm until you get all the required amount of characters.
This algorithm ensures that you get different characters.
Your code checks only if the character you just generated is different from its predecessor in your array ; you should try with a flag like that :
srand(time(NULL));
char letters[10];
int is_unique = 1, i=0,j ;
while (i<10){
is_unique = true;
letters[i] = 'a' + rand() % 26;
for(j=0;j<i;j++){
if (letters[i]==letters[j])
is_unique = false;
}
if (is_unique)
i++;
}
BTW, it's better to replace rand() % (122-97) by simply 26, it's more clear for anyone reading your code.
Another way would be :
srand(time(NULL));
char letters[10];
int j;
for (int i = 0; i < 10; i++)
{
letters[i] = 'a' + rand() % 26;
j=0;
while (j<i) {
if (letters[i]==letters[j]){
letters[i] = 'a' + rand() % 26;
j = 1;
} else
j++;
}
printf("%c\n", letters[i]);
}

Optimise a code of random number with no repetition in C

I do a code that will display to the screen 10 random numbers with no repetitions. I want to know if we can optimize the code or if you have a better and simple way in order to do this request.
Thanks !!
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
for (i = 0; i < 10; i++)
{
do
{
nbr = rand() % 10 + 1;
flag = 1;
for (j = 0; j < i; j ++)
{
if (nbr == arr[j])
{
flag = 0;
break;
}
}
} while (!flag);
arr[i] = nbr;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
system("PAUSE");
return 0;
}
So if i get what you're trying to do here it is:
generate an array of numbers between 1 and 10, in a random order (given rand() % 10 + 1)
instead of trial and error I'd suggest the following algorithm:
fill arr with 1...10
shuffle arr
this will run a lot faster
While I agree with the solution provided by Work of Artiz, this will result in the hard question to answer of when to stop shuffling.
To solve this you can use the following solution (which will use more memory, but less clock time):
1 Create an array temp having values 1..10 (ordered, not random)
2 Keep track of the length length of the array (10)
3 Generate a random index rand_i between 0 and length - 1
4 Copy temp[rand_i] to next position in your final array
5 Overwrite temp[rand_i] by temp[length-1]
6 Decrement length
7 Iterate Steps 3 - 6 until your array is filled (10 times)
This will both eliminate your excessive looping, and the problem of when to stop shuffling your array
EDIT: including code
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
int temp[10] = {1,2,3,4,5,6,7,8,9,10};
int length = 10;
for (i = 0; i < 10; i++)
{
nbr = rand() % length; // Generate random index between 0 and length - 1
arr[i] = temp[nbr]; // Copy value from random index in temp to next index in arr
// Now since temp[nbr] is already taken (copied to arr) we should replace it by last available value in temp (temp[lenght])
// and in the next iteration we will create a value between 0 and length -1. This will keep values not yet taken from temp in
// contiguous order
temp[nbr] = temp[length-1];
length--;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
return 0;
}

Scramble numbers from array with numbers - C

I have been figuring out how to scramble numbers from array after user enters 10 different numbers by using rand(). It crushes when it arrives to adjust() function so feel free to point out my stupid mistake. Cheers. The top part is function, the bottom part is in main().
void adjust(int z[], int size)
{
int i, n, t;
for(i = 0; i < size; i++)
{
size = rand();
t = z[size];
z[size] = z[i];
z[i] = t;
}
printf("\nYour numbers have been scrambled and here they are: \n", t);
}
.....................
int z[10];
int i;
int num = 0;
printf("Please enter 10 different numbers: \n");
for(i = 0; i < 10; i++)
{
z[i] = num;
scanf("%d", &num);
}
printf("\nThe numbers you entered were: ");
for (i = num; i <= 10; i++)
{
printf("%d ", z[i]);
}
printf("\n");
addNum(z, 10);
adjust(z, 10);
return 0;
The rand() function returns a number between 0 and RAND_MAX.
Hence, the array index can go well beyond its range.
To get a random index within a range from 0 to N -1 , use rand() % N.
Another issue is that in your for loop, in adjust function, you are destroying the original value of 'size'. That contains the length of your array and is used to check the terminating condition of your for loop. Hence, do not modify 'size'. Use another variable to store your random index.
for(i = 0; i < size; i++)
{
n = rand() % size; // n is between 0 and size-1
t = z[n];
z[n] = z[i];
z[i] = t;
}
// For a better design move the following lines to a separate function
// that way adjust function just does the scrambling while another
// printing function prints out the array. Each function does only one thing.
printf("\nYour numbers have been scrambled and here they are: \n");
for( i = 0; i < size; i++)
{
printf("%d ", z[i]);
}

Is the statement *a[i]++ /= K valid?

Array initialization Code:
int m = 100;
int n = 50;
int i = 0, j = 0;
float **a = (float**)malloc(m*sizeof(float*));
for (i = 0; i < m; i++)
{
a[i] = (float*)malloc(n*sizeof(float));
for (j = 0; j < n; j++)
a[i][j] = i + j;
}
a is a 2D array and I want to traverse and update the elements of the 1D array a[0]
Say I want to divide all elements of a[0] by 2:
for (i = 0; i < n; i++)
*a[0]++ /= 2; // instead of a[0][i] /= 2;
This doesn't seem to work..
I guess a is a 2 dimensional array like int a[10][20], then the given statement a[i]++ is "invalid".
The reason is that since a[i] being an array a[i] is a non-modifiable 'lvalue'.
In the above case *a[i] is valid but not the a[i]++
Yes, although it look like a homework. If you want more interesting code, you could write this without spaces, as *a[i]++/=K, and finally you could attach this to the containing loop, as for example while(p=a[i]++)*p/=K; to make things more compressed. ;-)

Resources