I want to shuffle an array of containing a list of cities to generate a result. The requirement for this shuffling is that same city can only appear again after at least six different cities have appeared. The same city must appear only twice.
I messed up using a different scenario before but I am new on here and getting used to how to post codes that I am struggling with. Any help would be appreciated. Array5 is the array to be shuffled.
Cities to be shuffled:
Boston, Durban, Melbourne, Paris, Denver, Algiers, Freetown, Sydney, Colorado, Oslo, Melbourne, Brussels
I have included my code below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i,j,count;
char array1[3][10]={"Denver","Boston","Colorado"};
char array2[3][10]={"Melbourne","Sydney","Canberra"};
char array3[3][10]={"Paris","Brussels","Oslo"};
char array4[3][10]={"Durban","Algiers","Freetown"};
char array5[12][10];
for (i=0;i<3;i++){
strcpy(array5[i],array1[i]);
}
for (i=0;i<3;i++){
strcpy(array5[i+3],array2[i]);
}
for (i=0;i<3;i++){
strcpy(array5[i+6],array3[i]);
}
for (i=0;i<3;i++){
strcpy(array5[i+9],array4[i]);
}
for (i=0;i<12;i++)
printf("%s\t\n",array5[i]);
}
The problem can be solved in two steps.
1) We shuffle the auxiliary array to obtain initial placement of the cities.
We can use FisherYates shuffle algorithm for shuffling the initial array.
2) We randomly decide which city we want to duplicate. We have to be mindful of the restrictions. City can be doubled only one time. If the city is doubled then there are at least 6 cities between them.
More explanations in the code:
// The requirement for this shuffling is that same city can only appear again after at least six different cities have appeared.
// A city can only appear twice.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define STR_LEN 16
#define NR_OF_ROWS 3
#define NR_OF_SMALL_ARRAYS 4
#define NR_OF_ROWS_IN_BIG_ARRAY NR_OF_ROWS*NR_OF_SMALL_ARRAYS
#define DOUBLE_COUNTER 12 // number of tries to double the city
void copy(char dest[][STR_LEN], char source[][STR_LEN], size_t displacement)
{
size_t i;
for (i=0; i<NR_OF_ROWS; i++){
strcpy(dest[i+displacement], source[i]);
}
}
void init_shuffle(size_t array[], size_t size)
{
size_t i;
for (i=0; i<size; i++){
array[i] = i;
}
}
void print_array(char array[][STR_LEN], size_t size)
{
size_t i;
for (i=0; i<size; i++){
printf("%s ",array[i]);
}
printf("\n");
}
void print_shuffle(size_t array[], size_t size)
{
size_t i;
for (i=0; i<size; i++){
printf("%zu ",array[i]);
}
printf("\n");
}
void print_corresponding_cities(char array[][STR_LEN], size_t *shuffle, size_t size)
{
size_t i;
size_t j;
for (i=0; i < size; i++){
j = shuffle[i];
printf("%s ", array[j] );
}
printf("\n");
}
int check_for_repeats(size_t *arr, size_t size, size_t value)
{
size_t i;
size_t counter = 0;
for (i=0; i<size; i++){
if(arr[i] == value){
counter++;
if(counter > 1)
return 1; // repeats found
}
}
return 0; // no repeats
}
int check_for_number_of_repeats(char array[][STR_LEN], size_t *arr, size_t size)
{
size_t i, j;
size_t counter = 0;
size_t value;
int repeats = 0;
for (j=0; j<size; j++){
value = j;
counter = 0;
for (i=0; i<size; i++){
if(arr[i] == value){
counter++;
if(counter > 1){
repeats++; // repeats found
printf("%s ", array[j]); // print the city
break;
}
}
}
}
return repeats;
}
void FisherYatesShuffle(size_t *arr, int n) {
size_t i, j; // indexes
size_t tmp; // create local variables to hold values for shuffle
for (i = n - 1; i > 0; i--) { // shuffle
j = rand() % (i + 1); // randomise j for shuffle
tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
}
int main()
{
size_t i;
int no_yes;
size_t double_index;
time_t t;
size_t shuffle[NR_OF_ROWS_IN_BIG_ARRAY]; // keep the results
char array1[NR_OF_ROWS][STR_LEN]={"Denver0","Boston1","Colorado2"};
char array2[NR_OF_ROWS][STR_LEN]={"Melbourne3","Sydney4","Canberra5"};
char array3[NR_OF_ROWS][STR_LEN]={"Paris6","Brussels7","Oslo8"};
char array4[NR_OF_ROWS][STR_LEN]={"Durban9","Algiers10","FreeTown11"};
char array5[NR_OF_ROWS_IN_BIG_ARRAY][STR_LEN];
init_shuffle(shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
// Initial arrangement:
copy(array5, array1, 0*NR_OF_ROWS);
copy(array5, array2, 1*NR_OF_ROWS);
copy(array5, array3, 2*NR_OF_ROWS);
copy(array5, array4, 3*NR_OF_ROWS);
printf("Initial arrangement:\n");
print_shuffle(shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
print_array(array5, NR_OF_ROWS_IN_BIG_ARRAY);
printf("\n");
// Algorithm:
// Note:
// The shuffling will be done on the auxilliary shuffle array
// Once the shuffling is done we can print the cities base on shuffle array values
// Steps.
// 1. We shuffle existing cities.
// 2. We randomly decide if we want to repeat the city.
// 3. If yes, we choose a random city
//
// 4. Now we have to repeat that city. The requirement is that if we repeat the city
// then we have have at least 6 cities between them.
// E.g. We want to repat city from index 0 then duplicated city can only be placed at index 7 to 11
// Index Next city placement:
//
// 0 7-11 range 5 [7,8,9,10,11]
// 1 8-11 range 4
// 2 9-11 range 3
// 3 10-11 range 2
// 4 11 fixed position
// 5 no placement
// x if (x > 4) no placement possible
// else placement possible in the range [x+7, 11]
// size of the range is 5-x
// 5. we can repeat that procees a few times (DOUBLE_COUNTER). Restriction: A given city can be repeated only 1 time.
/* Intializes random number generator */
srand((unsigned) time(&t));
// 1. Shuffle
printf("After the shuffle:\n");
FisherYatesShuffle(shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
print_shuffle(shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
print_corresponding_cities(array5, shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
printf("\n");
// 2. Add cities
for(int i=0; i < DOUBLE_COUNTER; i++)
{
no_yes = rand() % 2; // add? YES OR NO
if(no_yes == 0) // NO
continue;
double_index = rand() % NR_OF_ROWS_IN_BIG_ARRAY; // which city
if(double_index > 4)
continue; // NO placement possible
// check for repeats
int rep = check_for_repeats(shuffle, NR_OF_ROWS_IN_BIG_ARRAY, shuffle[double_index]);
if(rep)
continue; // city under this index has a double already
//-------------------------------------------------------
// OK we need to repeat the city
if(double_index == 4)
{
shuffle[11] = shuffle[double_index];
continue;
}
// now we have a choice:
int choice = rand() % (5 - double_index);
// random placement within the range:
shuffle[double_index +7 + choice] = shuffle[double_index];
//-------------------------------------------------------
}
// Results:
printf("Final arrangement after adding double city/cities:\n");
print_shuffle(shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
print_corresponding_cities(array5, shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
// Stats:
printf("\nThese cites occure two times:\n");
int nr_rep = check_for_number_of_repeats(array5, shuffle, NR_OF_ROWS_IN_BIG_ARRAY);
printf("\nNumber of repeated cities = %d\n", nr_rep);
return 0;
}
Output:
Initial arrangement:
0 1 2 3 4 5 6 7 8 9 10 11
Denver0 Boston1 Colorado2 Melbourne3 Sydney4 Canberra5 Paris6 Brussels7 Oslo8 Durban9 Algiers10 FreeTown11
After the shuffle:
5 9 3 11 6 8 4 0 7 2 1 10
Canberra5 Durban9 Melbourne3 FreeTown11 Paris6 Oslo8 Sydney4 Denver0 Brussels7 Colorado2 Boston1 Algiers10
Final arrangement after adding double city/cities:
5 9 3 11 6 8 4 0 5 2 1 6
Canberra5 Durban9 Melbourne3 FreeTown11 Paris6 Oslo8 Sydney4 Denver0 Canberra5 Colorado2 Boston1 Paris6
These cites occure two times:
Canberra5 Paris6
Number of repeated cities = 2
Related
I wanna create all possible 5 digit numbers that can be created from the numbers (0-7).
The code below achieves this, but is there any way to make this depend on user input?
The number of loops equals the number of digits I want and each individual loop must be:
for(1st number;condition<=last number;1st number++)
So, for five digits, I have:
for(i=0;i<8;i++){
for(j=0;j<8;j++){
for(k=0;k<8;k++){
for(m=0;m<8;m++){
for(n=0;n<8;n++){
printf("%d %d %d %d %d\n",i,j,k,m,n);
}
}
}
}
}
Keep iterators in an array and increment them manually.
#include <assert.h>
#include <stdio.h>
#include <string.h>
void callback(unsigned n, int i[n]) {
assert(n == 5);
printf("%d %d %d %d %d\n", i[0], i[1], i[2], i[3], i[4]);
}
void iterate(unsigned n, unsigned max, void (*callback)(unsigned n, int i[n])) {
// VLA, use *alloc in real code
int i[n];
memset(i, 0, sizeof(i));
while (1) {
for (int j = 0; j < n; ++j) {
// increment first number, from the back
++i[n - j - 1];
// if it didn't reach max, we end incrementing
if (i[n - j - 1] < max) {
break;
}
// if i[0] reached max, return
if (j == n - 1) {
return;
}
// if the number reaches max, it has to be zeroed
i[n - j - 1] = 0;
}
// call the callback
callback(n, i);
}
}
int main() {
// iterate with 5 numbers to max 8
iterate(5, 8, callback);
}
The beginning and ending of what the code prints:
0 0 0 0 0
0 0 0 0 1
...
...
7 7 7 7 6
7 7 7 7 7
If you want variable numbers of loops, you generally need to use recursion.
Say if you want n digits, with the ith digit be in the range of a[i],b[i], then you will do the following:
/* whatever */
int n;
int *a,*b,*number;
void recursion(int whichdigit){
if (whichdigit==n){
/* Say you managed to output number */
return;
}
for (int i=a[whichdigit];i<=b[whichdigit];i++){
number[whichdigit]=i;
recursion(whichdigit+1);
}
return;
}
int main(){
/* Say somehow you managed to obtain n */
a=malloc(n*sizeof(int));
b=malloc(n*sizeof(int));
number=malloc(n*sizeof(int))
if (!a||!b||!number){
/* unable to allocate memory */
}
/* Say somehow you managed to read a[i],b[i] for all i in 0..n-1 */
recursion(0);
return 0;
}
Warning: if you tries to have too many digits, you will likely get a segmentation fault or stack overflow error.
I am still new to C, and I need to figure a way to print the same number of stars as the number of frequencies.
Here's my code:
int arrayHistogram(int array[]){
int i;
int j;
int count=0;
int freq[SIZE];
char stars[SIZE];
for(i = 0; i < SIZE; i++){
count =1;
for(j = i+1; j < SIZE; j++){
if(array[i]==array[j]){
count++;
freq[j]=0;
}
}
if(freq[i] != 0){
freq[i] = count;
}
}
//for ( i = 0; i < SIZE; i++){
//int num = freq[i];
//stars[i]= '*'*num;
}
printf("Value ");
printf("Frequency ");
printf("Histogram\n");
for(i = 0; i < SIZE; i++){
if(freq[i] != 0){
printf("%5d%10d%10d\n", array[i], freq[i], stars[i]);
}
}
}
I know that I can't multiply char by int here to print the stars, but I put here just to show where I need to print those stars (i.e. the histogram).
My Output:
Value Frequency Histogram
7 4 -46
8 3 126
4 6 84
Expected output:
Value Frequency Histogram
7 4 ****
8 3 ***
4 6 ******
Well, you already know everything to do that i.e. loop.
Simply, loop up to a frequency and print that many stars.
Something like this (pseudo code):
loop until freq[i]
print '*'
end loop
It's just an idea. You know how a loop works. Just put a nested loop (i.e. for loop) where you need to print the stars. Mind the newline. You need a newline at the end of each line after printing the stars.
UPDATE:
As observed, you've frequencies up to 10 i.e. a fixed size that you already know. You can simply use a string of stars and then print it using printf() with %.*s format specifier with field width and string length.
Here's an example (live code):
#include <stdio.h>
#define SIZE 10
int main(void)
{
const char* stars = "**********";
const int freqs[ SIZE ] = { 3, 5, 6, 2, 0, 7, 10, 9, 4, 8 };
for ( int i = 0; i < SIZE; i++ )
{
printf("%5d \t %10.*s\n", freqs[i], freqs[i], stars);
}
return 0;
}
OUTPUT:
3 ***
5 *****
6 ******
2 **
0
7 *******
10 **********
9 *********
4 ****
8 ********
how about building char stars[SIZE] with a loop?
int nStars = freq; // in you situation.
for(int i=0; i < nStars;++i)
{
stars[i] = '*'; // set char i to be '*'
}
stars[nStars] = '\0'; // don't forget to terminate your string
you can make a simple utility function void fillChar(char* buff, char ch, int count); of it.
Take Caution not to exceed the size of the allocated string or bad things gona happen.
Cheers.
I am successfully storing the calculated subsets in a 2-D array matrix in C language.Now I want to print the subsets in an order desired.
For eg.
2-D array matrix is
10 7 3 2 1
10 7 5 1
7 6 5 3 2
10 6 5 2
10 7 6
Desired Output
10 7 6
10 7 5 1
10 7 3 2 1
10 6 5 2
7 6 5 3 2
How quick sort can be applied to sort/order these rows?
As #chqrlie noted, this can be easily solved with qsort.
Depending on the way the matrix is declared (is it an array of pointers to arrays of ints? do all arrays have the same length? is it a global array of fixed size?) the code will have to do slightly different things.
So, assuming the array is a global variable and all rows have same length (padded with 0s):
MWE:
#include <stdio.h>
#include <stdlib.h>
/*
Compare 2 integers
returns:
-1 if *i1 < *i2
+1 if *i1 > *i2
0 if *i1 == *i2
*/
int intcmp(const int *i1, const int *i2)
{
return (*i2 < *i1) - (*i1 < *i2);
}
#define ROWS 5
#define COLS 5
/*
Assumes rows already sorted in descending order
NOTE: qsort calls the comparison function with pointers to elements
so this function has to be tweaked in case the matrix is an array of
pointers. In that case the function's declaration would be:
int rowcmp(int **pr1, int **pr2)
{
const int *r1 = *pr1;
const int *r2 = *pr2;
// the rest is the same
}
*/
int rowcmp(const int *r1, const int *r2)
{
int i = 0, cmp;
do {
cmp = intcmp(&r1[i], &r2[i]);
i++;
} while (i < COLS && cmp == 0);
return -cmp; /* return -cmp to sort in descending order */
}
int data[5][5] = {
{10,7,3,2,1},
{10,7,5,1,0},
{ 7,6,5,3,2},
{10,6,5,2,0},
{10,7,6,0,0}
};
void printmatrix()
{
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", data[i][j]); /* leaves a trailing space in each row */
}
printf("\n");
}
}
int main()
{
printmatrix();
qsort(data, 5, sizeof(data[0]), (int (*)(const void *, const void *))rowcmp);
printf("\n");
printmatrix();
return 0;
}
For the most flexible solution, I would define
struct row {
size_t len;
int *elems;
};
struct matrix {
struct row *rows;
size_t nrows;
};
and change the code accordingly.
NOTE: code not thoroughly tested, use with caution ;)
First of all, are you sure that the 1 on row 3,col 5 should be there and not on the last line?
Anyway, an efficient way to achieve what you want is:
compute the frequency array
declare a new matrix
go from the highest element (10 in your case) from frequency array and put in your matrix using your desired format.
It is time-efficient because you don't use any sorting algorithm, thus you don't waste time there.
It is NOT space-efficient because you use 2 matrices and 1 array, instead of only 1 matrix as suggested in other posts, but this should not be a problem, unless you use matrices of millions of rows and columns
C code for frequency array:
int freq[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(MATRIX[i][j]!=null && MATRIX[i][j]>0 && MATRIX[i][j]<11) {
freq[MATRIX[i][j]]++;
}
}
}
C code for computing the new matrix dimensions
(assuming you want to keep the number of rows)
OUTPUT_MATRIX[100][100] /*I declared it statically, but I would advise to make it dinamically */
/* first, compute the number columns.
To do so, we need the number of elements
(we get them by simply summing up frequency array's elements) */
int s=0;
for(int i=0; i<11; i++) {
s+=frequency[i];
}
int addOne = 0 /* boolean value to check if we will have to add one extra column for safety */
if(s % NO_ROWS) {
addOne = 1; /* division is not even, so we will have to add extra column */
}
NO_COLS = s/NO_ROWS + addOne;
Now, final part, assigning the values from frequency array to the OUTPUT_MATRIX
int k=0;
int currentNumber = 10; /* assigning starts from 10 */
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(currentNumber>0) {
if(frequency[currentNumber]==0 || k>=frequency[currentNumber]) {
currentNumber--;
k=0;
}
OUTPUT_MATRIX[i][j] = frequency[currentNumber];
k++;
} else {/*here, you can assign the rest of the value with whatever you want
I will just put 0's */
OUTPUTMATRIX[i][j] = 0;
}
}
}
Hope this helps!
This is what I do in C++ to reorder a matrix:
// b is the matrix and p is an array of integer containing the desired order of rows
for(i=0; i<n; i++){
if( p[i]==i )
continue;
b[i].swap(b[p[i]]);
j = p[i]; // New row i position
// Update row i position to new one
for(int k=i+1; k<n; k++){
if( p[k] == i )
p[k] = j;
}
printRow( b[i] );
}
You need to define an array of pointers of the data type you use and then you can reorder your matrix.
for example your matrix is: arr[5][10], and you want to print line 4 before line 3:
int *[5] arr2;
arr2[0] = &arr[0][0];
arr2[1] = &arr[1][0];
arr2[2] = &arr[2][0];
arr2[3] = &arr[4][0];
arr2[4] = &arr[3][0];
in regard to how will the ordering algorithm work, i would suggest placing a header in the start of each array in the matrix which will tell you how many elements it has(basically the first element of each array can be a counter of the total elements) afterwards you can order the strings by comparing the header, and if it is equal comparing the first element and so on. this can be done in a loop that iterates as many times as there are elements in the array, when the elements are not equal, break out of the loop.
hope this helps.
I've been at this problem for like 3 days and I've combed my entire code to try to figure out why I'm getting incorrect output. The purpose of this program is to do a merge sort using threads. The first part is simply sorting the elements in parallel into however many segments a user inputs. The only inputs tested will be 2, 5, and 10. And the array to be sorted will always be 50 int array of randomly generated numbers.My code works fine when the segments entered (denoted by the variable 'segments' at the top of main) is 2. However, when I change segments to 5 or 10, I don't get a sorted array at the end. I've tried debugging by using print statements (which I've commented out but you can still see) and there seems to be a problem during the first two merge iterations. For some reason the resulting of those merge iterations are not in order, and they contain duplicate numbers that don't exist in duplicate in the original array passed to it. My sorting method and merging methods work fine when I just pass arrays to them, and don't use threads but when I do use threads I get behavior that I can't explain. Below is my program in its entirety, to merge an array of 50 it should do the following:
split the array into 10 segments of 5, and sort each segment.
pass the segments in pairs, in rounds. So round one should pas segment 0-5 in one segment and 5-10 in another, 10-15 and 15-20, 20-25 and 25-30, and so on until it reaches 40-45 and 45-50.
then it will go into round two which does same thing as round one but it passes the segments in pairs of 10. So 0-10 and 10-20, 20-30 and 30-40, then it leaves the last part of 10 untouched
round three passes the segments to merge in pairs of 20: 0-20 and 20-40, then stops.
Finally it should merge the segments 0-40 with 40-50.
My program: (you should mainly focus on my main function, sort is fine, and merge seems fine too, but i've included them anyways just in case)
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
/**
* Struct to contain an array partition as well as the size of the partition.
* Use struct to pass multiple parameters to pthread_create
*/
struct array_struct{
int *partition;
int size;
};
/**
* Struct that contains two arrays (should be sorted) to merge
* Use struct to pass multiple parameters to pthread_create
*/
struct arrays_to_merge{
int *array1;
int *array2;
int size1;
int size2;
};
//comparison function to use with qsort, sorts in ascending order
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
/**
* Method that takes a struct containing a pointer to the first int in an array
* partition, as well as the partition size. Object must be type void, used with pthread_create
* #param pointer to the partition object. Type void
*/
void *sort(void *object){
struct array_struct *structure;
structure = (struct array_struct *) object;
int *array = structure->partition;
int size = structure->size;
int *i, j = 0;
qsort(array, size, sizeof(int), cmpfunc);
printf("Sorted %d elements.\n", size);
}
void *merge(void * object){
struct arrays_to_merge *arrays_struct;
arrays_struct = (struct arrays_to_merge *) object;
int *array1 = arrays_struct->array1;
int *array2 = arrays_struct->array2;
int size1 = arrays_struct->size1;
int size2 = arrays_struct->size2;
int tempArray[size1 + size2];
int i = 0, j = 0, k = 0, duplicates = 0;
while (i < size1 && j < size2) {
// printf("Merge number : %d Comparing %d and %d\n", mergenumber, array1[i], array2[j]);
if (array1[i] <= array2[j]) {
// printf("Picking %d\n", array1[i]);
tempArray[k] = array1[i];
if (array1[i] == array2[j])
{
duplicates++;
}
i++;
k++;
}else {
// printf("Merge number : %d Picking %d\n", mergenumber, array2[j]);
tempArray[k] = array2[j];
k++;
j++;
}
}
while (i < size1) {
// printf("Merge number : %d left over Picking %d\n", mergenumber, array1[i]);
tempArray[k] = array1[i];
i++;
k++;
}
while (j < size2) {
// printf("Merge number : %d left over Picking %d\n", mergenumber, array2[j]);
tempArray[k] = array2[j];
k++;
j++;
}
array1 = arrays_struct->array1;
for(i = 0; i < size1 + size2; i++){
array1[i] = tempArray[i];
}
printf("Merged %d and %d elements with %d duplicates\n", size1, size2, duplicates);
}
//return an array of size 50 with randomly generated integers
int *randomArray(){
srand(time(NULL));
static int array[50];
int i;
for (i = 0; i < 50; ++i){
array[i] = rand() % 51;
}
return array;
}
int main(int argc, char const *argv[])
{
int segments = 10;//make equal to argv input after testing
pthread_t threads[segments];
int i, *numbers; //iterator i, and pointer to int array 'numbers'
numbers = randomArray(); //return an array of random ints and store in 'numbers'
struct array_struct array[segments];
for(i = 0; i < segments; i++){
int *partition = numbers + (i * (50/segments));//obtain the first index of partition
array[i].partition = partition;
array[i].size = 50/segments;
pthread_create(&threads[i], NULL, sort, (void *) &array[i]);
}
for(i = 0; i < segments; i++){
pthread_join(threads[i], NULL);
}
int count = segments;
struct arrays_to_merge arrays[segments];
int j;
int size = 50/ segments;
while(count > 1){
for(i = 0, j = 0; i < count-1; j++, i += 2){
int *partition = numbers + (i * (size));
int *partition2 = numbers + (i+1 * (size));
arrays[j].array1 = partition;
arrays[j].array2 = partition2;
arrays[j].size1 = size;
arrays[j].size2 = size;
pthread_create(&threads[j], NULL, merge, (void *) &arrays[j]);
}
for(i = 0; i < j; i++){
pthread_join(threads[i], NULL);
}
size = size * 2;
count = count/2;
}
if(segments != 2){//for segments = 2, no need for his
int *partition = numbers;
int *partition2 = numbers + (size);
arrays[0].array1 = partition;
arrays[0].array2 = partition2;
arrays[0].size1 = size;
arrays[0].size2 = 50 - size;
pthread_create(&threads[0], NULL, merge, (void *) &arrays[0]);
pthread_join(threads[0], NULL);
}
for(i = 0; i < 50; i++){
printf("%d\n", numbers[i]);
}
pthread_exit(NULL);
return 0;
}
this is my output:
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 10 and 10 elements with 3 duplicates
Merged 10 and 10 elements with 1 duplicates
Merged 20 and 20 elements with 7 duplicates
Merged 40 and 10 elements with 17 duplicates
0
6
9
11
12
13
13
14
15
17
19
23
25
25
25
26
26
28
28
28
28
30
32
32
32
34
39
41
41
44
44
44
44
44
50
50
9
15
50
9
15
19
26
50
50
9
15
11
14
50
Sorry for the long wall of text, I've tried resolving this on my own and after countless hairs pulled I can't figure it out. Please help me figure out what I'm doing wrong. I think my problem lies in either the way I'm joining threads, or my merge function but since I cant be sure, i just included the whole thing.
It took a while but finally I got there :)
The problem is with this line:
int *partition2 = numbers + (i+1 * (size));
which is equivalent to (due to operator precedence).
int *partition2 = numbers + (i + size);
and is not what you want.
It should be:
int *partition2 = numbers + ((i+1) * (size));
Notice the additional brackets. Without which, the partition2 index is calculated incorrectly. Hence, merging with different parts of the array.
This question has been asked here on SO before with below code
find3missing(int* array)
{
int newarray[100] = {0};
For i = 0 to 99
++newarray[array[i]] ;
For i = 0 to 99
If newarray[i] != 1
Cout << “the missing number is ” << i+1 << endl ;
}
But when I checked this code, it doesn't seem to work. Suppose I have an array of {1,2,6}. The output should be 3,4,5 but with the code above I get 1,4,5,6 instead. Below is my implementation of pseudo code with array size 6.
main()
{
int a[6]={1,2,6};
int tmp[6]={0},i;
for(i=0;i<6;i++)
{
++tmp[a[i]];
}
for(i=0;i<6;i++)
{
if(tmp[i]!=1)
{
printf("%d",i+1);
}
}
}
Is this the right code?
This ++newarray[array[i]] should be ++newarray[array[i] - 1]. This because you are interested in a sequence of 1-100 numbers, so no 0, but C arrays are 0 based. If you then look at the cout: the missing number is ” << i+1 here you "unshift" the number by adding 1.
There is another problem: you should pass the number of elements of the array, something like:
find3missing(int* array, int length) {
int newarray[100] = {0};
for (int i = 0; i < length; i++) {
++newarray[array[i] - 1] ;
}
C/C++ arrays are zero based, as A[i] is equivalent to *(A+i). So change ++newarray[array[i]] to ++newarray[array[i]-1]. Also use malloc, free and memset to use an array of dynamic size.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void find3missing(int* pArray, size_t size, int min, int max){
int* newarray;
int i;
unsigned int j;
int range = max - min;
if(range < 0)
return;
newarray = (int*) malloc(range*sizeof(int)); // allocate enough memory
memset(newarray,0,range*sizeof(int)); // set that block to zero
for(j = 0; j < size; ++j){
++newarray[pArray[j]-min];
}
for(i = 0; i < range; ++i){
if(!newarray[i])
printf("%d is missing!\n",min+i);
}
free(newarray);
}
int main(){
int test[] = {1,3,6};
find3missing(test,sizeof(test)/sizeof(int),1,6);
return 0;
}
Please note that this solution is very inefficient if your array is sorted. In this case have a look at Jimmy Gustafsson's answer.
This algoritm will be quite simple, since you're using a sorted array. Simply check if the current value +1 equals the nextvalue like below:
find3missing(){
int array[arraySize]; // the array with integers
for(i=0;i<arraySize;i++)
if(array[i]+1 != array[i+1]) // if value array[i]+1 is not equal the next index
// value, then it's a missing number
printf("A missing number: %i", i+1);
}