sorting array in heap memory - arrays

I have to write a function to sort an array in the heap. This function should make a copy of the array, sort the copy, and return a pointer to the sorted copy. I tried qsort() but I get strange output. I'm sure it has something to do with the pointer but still can't figure it out.
This is my code so far:
int cmpfunc(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b);
}
int sorted_copy(int* list[], size_t s)
{
int aList[s];
memcpy(aList,list,s);
printf("Array was copied successfuly to aList[] array\n\n");
printf("Before sorting the list is: \n");
for(int i = 0; i < s; i++)
printf("%d\n", aList[i]);
qsort(aList, s, sizeof(int), cmpfunc);
printf("After sorting the list is: \n");
for(int i = 0; i < s; i++)
{
printf("%d\n", aList[i]);
}
return *aList;
}
int main()
{
int list[10] = {4, 1, 2, 7, 3, 5, 6, 0, 8, 9};
sorted_copy(list,sizeof(list));
return 0;
}
An this the output I'm getting
Array was copied successfuly to aList[] array
Before sorting the list is:
4
1
2
7
3
5
6
0
8
9
0
0
0
0
3
0
0
0
268501009
32762
4199840
0
-1407817721
32762
12846904
0
1324151619
0
8
0
176
0
6487584
0
4199972
0
4200528
0
-1434081178
32762
After sorting the list is:
-1434081178
-1407817721
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
2
3
3
4
5
6
7
8
8
9
176
32762
32762
32762
4199840
4199972
4200528
6487584
12846904
268501009
1324151619
Process returned 0 (0x0) execution time : 0.281 s
Press any key to continue.

Well, the second parameter of sorted_copy() must be the number of elements of array passed as first parameter, and not its sizeof (the size of the object in memory bytes) I'm supposing you are using a 32 bit architecture, where an int is four bytes wide, and you are passing 40 as the array number of elements, not 10 which is the actual number of cells in the array.
Change
int main()
{
/* you don't need to specify the number of elements to declare
* the array if you are using an initializer that fully populates
* the array elements */
int list[10] = {4, 1, 2, 7, 3, 5, 6, 0, 8, 9};
sorted_copy(list,sizeof(list)); /* sizeof gives you the array
* size in bytes, not in number
* of elements */
return 0;
}
into
int main()
{
int list[] = {4, 1, 2, 7, 3, 5, 6, 0, 8, 9};
sorted_copy(list, sizeof list / sizeof list[0]);
return 0;
}
and you'll get the correct result.

Related

print evens number and odds number from an array

Declare an array containing these number and print the evens numbers and odd numbers
Now I initialized an array that containing 11 integers.
Here is my code
#include <stdio.h>
int main(void) {
int nums[11] = {11,3,9,7,6,10,13,17,2,8,3}; // create an variables that store integers
int evens[11] = {0}; // initialized an array to store even numbers
int odds[11] = {0}; // initialized an array to store even numbers
int length = sizeof(nums) / sizeof(nums[0]); // get the length of nums
int nums_index = 0;
int evens_index = 0;
int odds_index = 0;
for (nums_index; nums_index < length;nums_index++) {
if (nums[nums_index] % 2 == 0) {
evens[evens_index] = nums[nums_index];
evens_index++;
}
else if(nums[nums_index] % 2 != 0) {
odds[odds_index] = nums[nums_index];
odds_index++;
}
printf("%d\n",evens[evens_index]);
printf("%d\n",odds[odds_index]);
}
return 0;
}
The major question is whether the output has problems when I compile my code.
The output is :0 11 0 3 0 9 0 7 6 0 10 0 0 13 0 17 2 0 8 0 0 3
Why it could happened?
Thank you all.
You need separate indexing for each array, advancing the index for evens and odds only when nums[i] value is one of the two.
Otherwise you would get sort of a copy of nums with zeroes in place of those numbers of the opposite type (odd/even).
For instance:
int j = 0;
int k = 0;
for (int i = 0; i < length; i++) {
if (nums[i] % 2 == 0) {
evens[j] = nums[i];
j++;
}
else if(nums[i] % 2 != 0) {
odds[k] = nums[i];
k++;
}
printf("%d\n",evens[i]);
printf("%d\n",odds[i]);
}
This will compose the arrays like:
11 3 9 7 13 17 3 0 0 0 0 --- for odds
6 10 2 8 0 0 0 0 0 0 0 0 --- for evens
The second problem is that you are printing inside the loop, firstly a value from evens and immediately after a value for odds.
So if you want to display them nice and separate, you can move both printf outside the first loop, then looping again on each result array for displaying it completely, before proceding to the other.
#include <stdio.h>
void PrintNumbers(int*, int);
int main(void) {
int nums[11] = {11,3,9,7,6,10,13,17,2,8,3}; // create an variables that store integers
int evens[11] = {0}; // initialized an array to store even numbers
int odds[11] = {0}; // initialized an array to store even numbers
int length = sizeof(nums) / sizeof(nums[0]); // get the length of nums
int nums_index = 0;
int evens_index = 0;
int odds_index = 0;
for (nums_index; nums_index < length; nums_index++)
{
if (nums[nums_index] % 2 == 0)
{
evens[evens_index] = nums[nums_index];
evens_index++;
}
else if(nums[nums_index] % 2 != 0)
{
odds[odds_index] = nums[nums_index];
odds_index++;
}
}
printf("Original List: ");
PrintNumbers(nums, length);
printf("Even numbers: ");
PrintNumbers(evens, length);
printf("Odd numbers: ");
PrintNumbers(odds, length);
return 0;
}
void PrintNumbers(int* numbers, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d, ", numbers[i]);
}
printf("\n");
}
Output:
Original List: 11, 3, 9, 7, 6, 10, 13, 17, 2, 8, 3,
Even numbers: 6, 10, 2, 8, 0, 0, 0, 0, 0, 0, 0,
Odd numbers: 11, 3, 9, 7, 13, 17, 3, 0, 0, 0, 0,

Generate combinations of k numbers in an array with ordering constraints

This is one of the questions from my midterm exam.
Please trace the following program. Modify this program to write a recursive program int combinations(A, n, k) that you can print out all the
combinations of k numbers out of n different numbers stored in an array A with additional rules of:
(1) the order of A[0], A[1], ..., A[n-1] must remain and
(2) the sequence of these k numbers must be in an increasing order.
For example, assume there are four numbers 4, 1, 2, 3 stored in array int A[4]. Calling this recursive function combinations(A, 4, 2) will return a count 3 and print out (1, 2), (1, 3) and (2, 3), or calling combinations(A, 4, 3) will return a count 1 and print out (1, 2, 3).
Your recursive program must consider to avoid the unnecessary recursive function calls.
Teacher gave the following code as the hint:
#include <stdio.h>
#define N 4
int boolfunc(int *var, int m);
int recursivebool(int *var, int n);
int main(){
int varbool[20];
recursivebool(varbool, N);
}
int boolfunc(int *var, int m){
int result=var[0], i;
for (i=1; i<m; i++) result = (result && var[i]);
return result;
}
int recursivebool(int *var, int n){
int localvar[20], i, j;
if (n == 0){
for(i=0; i<N; i++) printf("%d ", var[i]);
printf("%d\n", boolfunc(var, N));
return;
}
for (j=0; j<=1; j++) {
var[n-1] = j;
recursivebool(var, n - 1);
}
}
If we run this program we can get output like this:
0 0 0 0 0
1 0 0 0 0
0 1 0 0 0
1 1 0 0 0
0 0 1 0 0
1 0 1 0 0
0 1 1 0 0
1 1 1 0 0
0 0 0 1 0
1 0 0 1 0
0 1 0 1 0
1 1 0 1 0
0 0 1 1 0
1 0 1 1 0
0 1 1 1 0
1 1 1 1 1
I can understand the hint program. And I need to use this concept to write int combination(int *A, int n, int k) like the question asked. As what I know, if k is 2, I can use this concept to find the scenario that have two 1 with two 0 like this:
1 1 0 0
1 0 1 0
1 0 0 1
0 1 1 0
0 1 0 1
0 0 1 1
Then, we can find the numbers from corresponding index of 1 and exam the numbers to see if they are in the increasing order.
I tried so hard to solve this question. But it's too difficult.
You can approach this as a simple constraint satisfaction problem and use recursive backtracking to solve the constraints.
As you mention, we can naively generate all the possible combinations, then retroactively pick the ones we want, but then we've done a lot of useless work which the assignment correctly prohibits.
A solution is to break off the recursive search as soon as a violation of a constraint is detected and try a different possibility. If we ever reach a point where we've satisfied all the constraints for the sequence, we print the result. Ideally, we'd return an array of results, but not having to do so makes it easier to focus on the algorithm.
In terms of satisfying the constraints, we can do so by using a start index to fulfill the i < j requirement. If we add a number to an in-progress result, the result array must be empty or the existing element at the tail of the array is less than the element we're trying to add. Beyond that, we have our base case of k.
#include <stdio.h>
void print_arr(int len, int *a);
int combinations_recurse(int *a, int n, int k, int *selected,
int selected_len, int start) {
if (selected_len == k) {
print_arr(selected_len, selected);
return 1;
}
int selected_count = 0;
for (int i = start; i < n; i++) {
if (!selected_len || selected[selected_len-1] < a[i]) {
selected[selected_len] = a[i];
selected_count += combinations_recurse(a, n, k,
selected, selected_len + 1, start + 1);
}
}
return selected_count;
}
int combinations(int *a, int n, int k) {
int selected[n];
return combinations_recurse(a, n, k, selected, 0, 0);
}
int main() {
int a[] = {4, 1, 2, 3};
printf("count: %d\n\n", combinations(a, 4, 2));
printf("count: %d\n", combinations(a, 4, 3));
return 0;
}
void print_arr(int len, int *a) {
printf("[");
for (int i = 0; i < len - 1; printf("%d, ", a[i++]));
if (len) printf("%d]\n", a[len-1]);
else puts("]");
}
Output:
[1, 2]
[1, 3]
[2, 3]
count: 3
[1, 2, 3]
count: 1

Looping through and comparing subsets of arrays

I have two arrays:
int group_id[] = {1, 1, 2, 2, 2, 3, 3, 3};
int value[] = {1, 0, 3, 5, 0, 2, 1, 6};
From the second array, I need to return the largest value within the group_id index (not including the current index position), the result (in a new array) would be:
{0, 1, 5, 3, 5, 6, 6, 2}
The arrays are a lot longer (~10 millions), so looking for an efficient solution.
Clarification:
The first two elements of value belong to group_id = 1, the first element will return 0 as the highest value as it can't return its self. The second element will will return 1 as it's the largest value in group_id 1.
the third, fourth and fifth elements (3, 5, 0) belong to group_id 2, the first will return 5, the second 3 (as it can't return its own index and the third will return 5).
It isn't clear that all the elements in group_id with the same number are adjacent (but that is crucial for efficiency).
Good point, you can assume they are all adjacent.
It isn't clear what should happen if there was only one entry in group_id with a given value — there isn't an alternative entry to use, so what should happen (or should the code abandon ship if the input is invalid).
Assume invalid.
The problem can be solved in O(N) time; it does not need O(N•log N) and sorting. This code shows how:
/* SO 5723-6683 */
#include <assert.h>
#include <stdio.h>
static void dump_array(const char *tag, int size, int *data);
static void test_array(const char *tag, int size, int *groups, int *values);
int main(void)
{
int groups1[] = { 1, 1, 2, 2, 2, 3, 3, 3 };
int values1[] = { 1, 0, 3, 5, 0, 2, 1, 6 };
int groups2[] = { 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5 };
int values2[] = { 1, 1, 3, 5, 0, 2, 1, 6, 6, 3, 5, 5, 5, 3, 2, 3, 7, 3 };
enum { NUM_VALUES1 = sizeof(values1) / sizeof(values1[0]) };
enum { NUM_VALUES2 = sizeof(values2) / sizeof(values2[0]) };
test_array("Test 1", NUM_VALUES1, groups1, values1);
test_array("Test 2", NUM_VALUES2, groups2, values2);
return 0;
}
static void test_array(const char *tag, int size, int *groups, int *values)
{
printf("%s (%d):\n", tag, size);
dump_array("values", size, values);
dump_array("groups", size, groups);
int output[size];
int grp_size;
for (int lo = 0; lo < size - 1; lo += grp_size)
{
assert(groups[lo+0] == groups[lo+1]);
grp_size = 2;
int max_1 = (values[lo+0] < values[lo+1]) ? values[lo+1] : values[lo+0];
int max_2 = (values[lo+0] < values[lo+1]) ? values[lo+0] : values[lo+1];
for (int hi = lo + 2; hi < size && groups[hi] == groups[lo]; hi++)
{
grp_size++;
if (values[hi] >= max_1)
{
max_2 = max_1;
max_1 = values[hi];
}
else if (values[hi] >= max_2)
max_2 = values[hi];
}
for (int i = lo; i < lo + grp_size; i++)
output[i] = (values[i] == max_1) ? max_2 : max_1;
}
dump_array("output", size, output);
}
static void dump_array(const char *tag, int size, int *data)
{
printf("%s (%d):", tag, size);
for (int i = 0; i < size; i++)
printf(" %d", data[i]);
putchar('\n');
}
Output from this test program:
Test 1 (8):
values (8): 1 0 3 5 0 2 1 6
groups (8): 1 1 2 2 2 3 3 3
output (8): 0 1 5 3 5 6 6 2
Test 2 (18):
values (18): 1 1 3 5 0 2 1 6 6 3 5 5 5 3 2 3 7 3
groups (18): 1 1 2 2 2 3 3 3 3 3 4 4 4 5 5 5 5 5
output (18): 1 1 5 3 5 6 6 6 6 6 5 5 5 7 7 7 3 7
The following code will do it. Its efficiency is O(sum of all n_ilog(n_i)) in which n_i is the size of each subset i, unless we use MPI or OpenMP (in that case, it will be at best O(mlog(m)), in which m is the size of the greatest subset).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare (const void * e1, const void * e2)
{
int f = *((int*)e1);
int s = *((int*)e2);
return (f>s);
}
int main(int argc, char* argv[])
{
int group_id[] = {1, 1, 2, 2, 2, 3, 3, 3};
int value[] = {1, 0, 3, 5, 0, 2, 1, 6};
int i,j,k,count,*tmp;
for (i=0; i<8; i++)
{
/* find subsets */
count = 1;
for (j=i; j<7 && group_id[j]==group_id[j+1]; j++)
count++;
/* copy subset */
tmp = malloc(sizeof(int)*count);
memcpy(tmp, &value[i], sizeof(int)*count);
/* sort */
qsort (tmp, count, sizeof(*tmp), compare);
/* print */
for (k=i; k<=j; k++)
if (value[k] != tmp[count-1])
printf("%d ", tmp[count-1]);
else
printf("%d ", tmp[count-2]);
i = j;
free(tmp);
}
printf("\n");
return 0;
}
PS: You will probably have to do some modifications to it, but I hope its enough for what you want (or to get you started). Please, be aware, I am assuming each subset has size at least 2, and that the greatest value within a subset appears only once.

Given an array, print all possible contiguous subsequences whose sum is divisible by a given number x

Given an array, print all possible contiguous subsequences whose sum is divisible by a given number x.
I can see some related question :-
[Find numbers of subarray of an array whose sum is divided by given number
[how to find the length of the longest contiguous subarray whose sum is divisible by a given number
All ask to either print the largest array or length of largest array. I want to print all combinations of those contiguous array with are divisible by a given number.
I tried to9 solve this and came up with this solution
#include<iostream>
using namespace std;
void function(int arr[], int start, int end, int div, int sum)
{
if(start>end)
return;
if(!(sum%div))
{
if(start<end)
{
for(int i=start;i<=end;i++)
{
cout<<" "<<arr[i];
}
cout<<endl;
}
}
function(arr, start+1, end, div, sum-arr[start]);
function(arr, start, end-1, div, sum-arr[end]);
}
int main()
{
int arr[] = {2, 6, 3, 8, 5, 7, 4, 1};
int div;
int size = sizeof(arr)/sizeof(*arr);
cout<<" Enter divisor :- ";
cin>>div;
int sum = 0;
for(int i=0;i<size;i++)
sum+=arr[i];
function(arr, 0, size-1, div, sum);
cout<<endl;
system("PAUSE");
return 0;
}
This code has HORRIBLE complexity, i can think of one more solution using two loops with complexity O(n^2).
Can we do this in better that n^2 time complexity?
I assume you would have read the answer
Find numbers of subarray of an array whose sum is divided by given number .
If yes, then you can modify the aforementioned algorithm as below:
Input: 0 5 3 8 2 1
X = 3
Sum: 0 0 5 8 16 18 19
Mod 3: 0 0 2 2 1 0 1
All you need to do is to print the array whenever you see same value in "mod 3" output array. So in the above case you will print array from index [0], [2], [0, 4], [1, 4] and [4 ,5].
0 5 3 8 2 1
- 0 = 0 % 3 = 0
------------- 0 + 5 + 3 + 8 + 2 = 18 % 3 = 0
---------- 5 + 3 + 8 + 2 = 18 % 3 = 0
- 3 = 3 % 3 = 0
---- 2 + 1 = 3 % 3 = 0

C - Recursive, cumulative sum of an array

I've been tasked with making a recursive function that takes an array of numbers, and turns it into an array of the cumulative sum of all the numbers up to this point, thus:
1, 2, 3, 4, 5 becomes 1, 3, 6, 10, 15
This is what I came up with:
#include <stdio.h>
int cumul(int tab[], int length, int ind) {
if (ind > 0) {
tab[ind] += tab[ind-1];
}
if (ind < length) {
cumul(tab, length, ind+1);
}
return 0;
}
int main() {
int ind;
int tab[6] = {1, 2, 3, 4, 5, 6};
int length = sizeof(tab)/sizeof(tab[0]);
for (ind = 0; ind < length; ind++) {
printf("%d ", tab[ind]);
}
printf("\n");
cumul(tab, length, 0);
for (ind = 0; ind < length; ind++) {
printf("%d ", tab[ind]);
}
printf("\n");
return 0;
}
It works well in most cases but I've hit a snag for oddly specific arrays:
For example, it doesn't work for tab[6] = {1, 2, 3, 4, 5, 6}, here's the output:
1 2 3 4 5 6
1 3 6 10 15 21 27 7 4196016 0 -1076574208 32528 -1609083416 32767 -1609083416 32767 0 1 4195802 0 0 0 -1815242402 30550560 4195424 0 -1609083424
I have no idea why it goes bonkers. It works fine for just about any tab[5] and tab[7] arrays I tried, but fails for every tab[6] array I tried.
The problem occurs when ind reaches length-1. For example, if length is 6, and ind is 5, then the recursive call is
cumul(tab, 6, 6); // length=6 ind+1=6
At the next level of recursion, after the if ( ind > 0 ), the code will do this
tab[6] += tab[5]; // ind=6 ind-1=5
That results in undefined behavior because you're writing beyond the end of the array.
You could check the upper bound in the first if statement, e.g.
if ( ind > 0 && ind < length )
But it's better to just avoid the recursive call by changing the second if statement to
if ( ind < length - 1 )
Either change avoids the situation where you access tab[length].

Resources