Problem with changing numbers in an array in C - arrays

First I generate some random numbers and then i need to exchange them like I discribte in the following lines.
I tryed it iut with the for loobs.
I have to exchange the numbers of the array
Change number 1 and 2, 3 and 4,.....29 and 30
Change number 1 and 3, 4 and 7,.....27 and 30
Thank you for your Help
srand(time(NULL));
for ( i = 0; i < SIZE; i++ )
{
mainArray[i] = rand() % ( UPPERBOUND - LOWERBOUND + 1 ) + LOWERBOUND;
}
for ( i = 0; i < SIZE; i++)
{
if ( countDigitChange == 2 )
{
digitChanger1 = workArray2[i];
i++;
digitChanger2 = workArray2[i];
workArray2[i] = digitChanger1;
i--;
workArray2[i] = digitChanger2;
countDigitChange = 0;
}
countDigitChange++;
}
for ( i = 0; i < SIZE; i++)
{
if ( countDigitChange % 3 == 0 )
{
digitChanger1 = workArray3[i];
i += 2;
digitChanger2 = workArray3[i];
workArray3[i] = digitChanger1;
i += 2;
workArray3[i] = digitChanger2;
countDigitChange = 0;
}
countDigitChange++;
}

This seems much simpler:
Declare a helper function:
void swap_int(int* x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
Then in your code that needs to shuffle the array:
int i, j; // declare this up top with all your other variable declarations
// for each pair of elements swap them
for (i=0, j=1; j < SIZE; i+=2, j+=2)
{
swap_int(&mainArray[i], &mainArray[j]);
}
// swap array[0] with array[2], then swap array[3] with array[5], etc...
for (i=0, j=2; j < SIZE; i+=3, j+=3)
{
swap_int(&mainArray[i], &mainArray[j]);
}

Related

How can I create a generic function to sort an array of structures?

I'm working on this program for my University exam. I need to sort passenger array with a sorting algorithm (I choose bubblesort due to it's simplicity).
I need to create a generic function and pass as formal parameters:
-a list of objects i want to sort;
-a sort criterion.
So I think that I'll have to create only 1 Increasing sorting function and 1 decreasing sorting function and pass them the parameters to sort by.
I already tried to pass char *file_name to function, but I think that I'm wrong.
int passengersIncreasingBubbleSort_Birthyear(passengers test[], int x) {
int i = 0, j = 0, min_idx, flag = 0;
passengers temp;
for (i = 0; i < x; i++) {
min_idx = i;
for (j = i + 1; j < x; j++) {
if (test[j].birth_date.year < test[min_idx].birth_date.year) {
min_idx = j;
}
}
temp = test[min_idx];
test[min_idx] = test[i];
test[i] = temp;
flag = 1;
}
return flag;
}
I tried this:
int passengersIncreasingBubbleSort_Birthyear(passengers test[], int x, char *value1, char *value2) {
int i = 0, j = 0, min_idx, flag = 0;
passengers temp;
for (i = 0; i < x; i++) {
min_idx = i;
for (j = i + 1; j < x; j++) {
if (value1 < value2) {
min_idx = j;
}
}
temp = test[min_idx];
test[min_idx] = test[i];
test[i] = temp;
flag = 1;
}
return flag;
}
But it doesn't work as expected.
Ok, I achieved it.
int cmpfunction_Increasing_Birthdate (const void * a, const void * b)
{
passengers *passengerA = (passengers *)a;
passengers *passengerB = (passengers *)b;
return ( passengerA->signup_date.year - passengerB->signup_date.year );
}
and this is my call:
qsort(array, x, sizeof(passengers), cmpfunction_Increasing_Birthdate);
Now the question is, how can I also compare both year, month and day? Could I do it in the same compare function?

Majority element in an array.It

#include <stdio.h>
void main()
{
int maj, count, n = 6;
int arr[] = {1, 2, 2, 2, 2, 3, 4};
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 0;
for (int j = 9; j < n; j++) {
if (arr[j] == maj) count++;
}
if (count > n / 2) {
break; /* I think some problem is here ,if majority element not found then it takes last element as the majority element */
}
}
printf("%d", maj);
}
It is giving correct output if majority ellement is there but incorrect output if no majority element is there for example if array is {1,2,3,4} it is giving output as 4. please help!!
#include <stdio.h>
int main() {
int maj, count, n = 7; //n is size of arr
int arr[] = {1, 2, 2, 2, 2, 3, 4};
int isFound = 0; //0 -> false, 1 -> true
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 1; //first elements is itself
isFound = 0; //by default we assume that no major elements is found
for (int j = i+1; j < n; j++) { //iterate from next elements onwards to right in array
if (arr[j] == maj) count++;
}
if (count > n / 2) {
isFound = 1;
break; //major elements found; no need to iterator further; just break the loop now
}
}
if(isFound) printf("%d ", maj);
else printf("no major element");
return 0;
}
For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Try not to use magic numbers. Usually as in your program they are a reason for program bugs. For example you declared the array arr as having 7 elements however the variable n that should keep the number of elements in the array is initialized with the value 6. Another magic number 9 is used in the loop
for (int j = 9; j < n; j++) {
^^^
There is no need to write the outer loop that travers the whole array. Also the program does not report the case when the majority number does not exist in the array.
Using your approach with two loops the program can look the following way
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 2, 2, 2, 3, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t i = 0;
for ( ; i < ( N + 1 ) / 2; i++ )
{
size_t count = 1;
for ( size_t j = i + 1; count < N / 2 + 1 && j < N; j++ )
{
if ( a[i] == a[j] ) ++count;
}
if ( !( count < N / 2 + 1) ) break;
}
if ( i != ( N + 1 ) / 2 )
{
printf( "The majority is %d\n", a[i] );
}
else
{
puts( "There is no majority element" );
}
return 0;
}
Its output is
The majority is 2

Add the digits of each element in an multidimensional array

I have a 2 dimensional array. I'm trying to add the digits of each element in the array and find the sum.
For example :
consider my array is: a[2][2] = { {15,11}, {13,21} }.
Now for the element 15 i need to add 1+5 and the result 6 placed in the same position.
and for element 11 1+1 and place the result 2 in the same position. And the same for all other elements.
Following is my code.
int main ()
{
int a[3][2] = { {19,11}, {13,21}, {12,14}};
int i, j;
int digit1,digit2,sum1=0,sum2=0,rem1,rem2;
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 2; j++ )
{
digit1 = a[i];
rem1 = digit1%10;
sum1 = sum1 + rem1;
digit1 = digit1/10;
digit2 = a[j];
rem2 = digit2%10;
sum2 = sum2 + rem2;
digit2 = digit2/10;
printf("\nthe sum of i: ", sum1);
printf("\nthe sum of j: ", sum2);
}
}
return 0;
}
But from above code I'm not getting the sum.
I am kinda new to this and got stuck here. Here's the code in EDITOR.
Define a function to compute the sum of the digits of an integer.
int getSumOfDigits(int n)
{
int ret = 0;
while ( n > 0 )
{
ret += (n%10);
n /= 10;
}
return ret;
}
Use the function in the for loop.
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 2; j++ )
{
a[i][j] = getSumOfDigits(a[i][j]);
}
}
Its simple. Do the following -
//Assuming the array is a[3][2]
for(int i=0;i<3;i++)
for(int j=0;j<2;j++)
{
int sum = 0;
while(a[i][j])
{
sum+=a[i][j]%10;
a[i][j]/=10;
}
a[i][j]=sum;
}
Inside for loop put this code instead of your code it will work
for ( j = 0; j < 2; j++ )
{
sum1=0;
while(a[i][j]){
sum1=sum1+(a[i][j]%10);
a[i][j]=a[i][j]/10;
}
a[i][j]=sum1;
printf("\nthe sum of [%d][%d]: %d", i,j,sum1);
}

How to "combine" two int arrays?

Hello i have a little problem trying to "mix" two string arrays, i have searched about it but i have only found how to merge them or concatenate them, but thats not what i need.
i have two int arrays like this:
int no_items = 5;
int parent1[no_items], parent2[no_items];
if the arrays contains for example:
parent1[0] = 1;
parent1[1] = 2;
parent1[2] = 3;
parent1[3] = 4;
parent1[4] = 5;
and:
parent2[0] = 5;
parent2[1] = 1;
parent2[2] = 2;
parent2[3] = 3;
parent2[4] = 4;
given a "cross" point, for example 2:
parent1 should have his 2 first elements and the rest of parent2, and parent2 should have his first 2 elements and the rest of parent1. So the result should be:
parent1: 1,2 | 5,3,4
parent2: 5,1 | 2,3,4
where "|" is the break point index and the rest of elements should not be repeated.
How can i get this kind of mixing two int arrays? Thanks you!
at the moment i have this:
for(i = 0; i < cross_point; i++)
{
sprintf(buffer, "%d,", parent1[i]);
strcat(line1, buffer);
}
for(i = 0; i < cross_point; i++)
{
sprintf(buffer, "%d,", parent2[i]);
strcat(line2, buffer);
}
but i donĀ“t know how to go further than the cross point.
int *find(int *begin, int *end, int value)
{
int *p = begin;
for ( ; p != end; ++p)
if (*p == value) break;
return p;
}
int i, j;
int output1[no_items] = {0};
int output2[no_items] = {0};
int crosspoint = 3;
memcpy(output1, parent1, crosspoint * sizeof(int));
for (i = crosspoint, j = 0; i < no_items; ++i)
{
while (find(output1, output1+i, parent2[j]) != output1+i) ++j;
output1[i] = parent2[j];
}
memcpy(output2, parent2, crosspoint * sizeof(int));
for (i = crosspoint, j = 0; i < no_items; ++i)
{
while (find(output2, output2+i, parent1[j]) != output2+i) ++j;
output2[i] = parent1[j];
}
memcpy(parent1, output1, sizeof(parent1));
memcpy(parent2, output2, sizeof(parent2));
Demo: http://ideone.com/xUt6nQ
something like this should do it if you aren't concerned about creating temporaries:
int no_items = 5;
int output1[no_items];
int output2[no_items];
for (int i = 0; i < no_items; i++){
if(i < crosspoint){
output1[i] = parent1[i];
output2[i] = parent2[i];
}else{
output1[i] = parent2[i];
output2[i] = parent1[i];
}
}
If you are concerned about temporaries you need to swap the values, the logic should be fairly similar to above.
int no_items = 5;
int temp = 0;
for (int i = 0; i < no_items; i++){
if(i < crosspoint){
/* don't need to do anything here */
}else{
temp = parent1[i];
parent1[i] = parent2[i];
parent2[i] = temp;
}
}

Enumerating Permutations of a set of subsets

I have sets S1 = {s11,s12,s13), S2 = {s21,s22,s23) and so on till SN.I need to generate all the permutations consisting elements of S1,S2..SN.. such that there is only 1 element from each of the sets.
For eg:
S1 = {a,b,c}
S2 = {d,e,f}
S3 = {g,h,i}
My permuations would be:
{a,d,g}, {a,d,h}, {a,d,i}, {a,e,g}, {a,e,h}....
How would I go about doing it? (I could randomly go about picking up 1 from each and merging them, but that is even in my knowledge a bad idea).
For the sake of generality assume that there are 'n' elements in each set. I am looking at implementing it in C. Please note that 'N' and 'n' is not fixed.
It's just a matter of recursion. Let's assume these definitions.
const int MAXE = 1000, MAXN = 1000;
int N; // number of sets.
int num[MAXN]; // number of elements of each set.
int set[MAXN][MAXE]; // elements of each set. i-th set has elements from
// set[i][0] until set[i][num[i]-1].
int result[MAXN]; // temporary array to hold each permutation.
The function is
void permute(int i)
{
if (i == N)
{
for (int j = 0; j < N; j++)
printf("%d%c", result[j], j==N-1 ? '\n' : ' ');
}
else
{
for (int j = 0; j < num[i]; j++)
{
result[i] = set[i][j];
permute(i+1);
}
}
}
To generate the permutations, simply call permute(0);
If you know exactly how many sets there are and it's a small number one might normally do this with nested loops. If the number of sets is greater than 2 or 3, or it is variable, then a recursive algorithm starts to make sense.
And if this is homework, it's likely that implementing a recursive algorithm is the object of the entire assignment. Think about it, for each set, you can call the enumeration function recursively and have it start enumerating the next set...
If they are in a container, just iterate through each:
#include <stdio.h>
int main(void)
{
int set1[] = {1, 2, 3};
int set2[] = {4, 5, 6};
int set3[] = {7, 8, 9};
for (unsigned i = 0; i < 3; ++i)
{
for (unsigned j = 0; j < 3; ++j)
{
for (unsigned k = 0; k < 3; ++k)
{
printf("(%d, %d, %d)", set1[i], set2[j], set3[k]);
}
}
}
return 0;
}
Generic solution:
typedef struct sett
{
int* nums;
int size;
} t_set;
inline void swap(t_set *set, int a, int b)
{
int tmp = set->nums[a];
set->nums[a] = set->nums[b];
set->nums[b] = tmp;
}
void permute_set(t_set *set, int from, void func(t_set *))
{
int i;
if (from == set->size - 1) {
func(set);
return;
}
for (i = from; i < set->size; i++) {
swap(set, from, i);
permute_set(set, from + 1, func);
swap(set, i, from);
}
}
t_set* create_set(int size)
{
t_set *set = (t_set*) calloc(1, sizeof(t_set));
int i;
set->size = size;
set->nums = (int*) calloc(set->size, sizeof(int));
for(i = 0; i < set->size; i++)
set->nums[i] = i + 1;
return set;
}
void print_set(t_set *set) {
int i;
if (set) {
for (i = 0; i < set->size; i++)
printf("%d ", set->nums[i]);
printf("\n");
}
}
int main(int argc, char **argv)
{
t_set *set = create_set(4);
permute_set(set, 0, print_set);
}
This is a fairly simple iterative implementation which you should be able to adapt as necessary:
#define SETSIZE 3
#define NSETS 4
void permute(void)
{
char setofsets[NSETS][SETSIZE] = {
{ 'a', 'b', 'c'},
{ 'd', 'e', 'f'},
{ 'g', 'h', 'i'},
{ 'j', 'k', 'l'}};
char result[NSETS + 1];
int i[NSETS]; /* loop indexes, one for each set */
int j;
/* intialise loop indexes */
for (j = 0; j < NSETS; j++)
i[j] = 0;
do {
/* Construct permutation as string */
for (j = 0; j < NSETS; j++)
result[j] = setofsets[j][i[j]];
result[NSETS] = '\0';
printf("%s\n", result);
/* Increment indexes, starting from last set */
j = NSETS;
do {
j--;
i[j] = (i[j] + 1) % SETSIZE;
} while (i[j] == 0 && j > 0);
} while (j > 0 || i[j] != 0);
}
You may think about the elements of a set as values of a cycle counter. 3 sets means 3 for cycles (as in GMan answare), N sets means N (emulated) cycles:
#include <stdlib.h>
#include <stdio.h>
int set[3][2] = { {1,2}, {3,4}, {5,6} };
void print_set( int *ndx, int num_rows ){
for( int i=0; i<num_rows; i++ ) printf("%i ", set[i][ndx[i]] );
puts("");
}
int main(){
int num_cols = sizeof(set[0])/sizeof(set[0][0]);
int num_rows = sizeof(set)/sizeof(set[0]);
int *ndx = malloc( num_rows * sizeof(*ndx) );
int i=0; ndx[i] = -1;
do{
ndx[i]++; while( ++i<num_rows ) ndx[i]=0;
print_set( ndx, num_rows );
while( --i>=0 && ndx[i]>=num_cols-1 );
}while( i>=0 );
}
The most efficient method I could come up with (in C#):
string[] sets = new string[] { "abc", "def", "gh" };
int count = 1;
foreach (string set in sets)
{
count *= set.Length;
}
for (int i = 0; i < count; ++i)
{
var prev = count;
foreach (string set in sets)
{
prev = prev / set.Length;
Console.Write(set[(i / prev) % set.Length]);
Console.Write(" ");
}
Console.WriteLine();
}

Resources