Remove negative numbers and sort an array - c

Good day everyone,
my task is to remove all negative numbers from an array, and shorten it (return the new length as the amount of positive numbers). I tried doing that by BubbleSort all negative number to the right, and new length would be (old length - number of swap). My code simply freezes up the system.
I would be grateful if you guys could help.
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a;
int n = length;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array < 0) {
swap(a, array);
a--;
array++;
length--;
}
}
}
printialn(array, n);
return length;
};
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
printiln(remove_negatives(a, l));
return 0;
}

The while loop never stops, that's probably the reason your code freezes.
Your code only changes the address when the if statement is true. Which the array in your main() will stuck on the second (a[1]) element. So if we change change the address when the if statement is false...
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a, *head;
int n = length;
head = array;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array >= 0) {
array++;
continue;
}
swap(a, array);
a--;
array++;
length--;
}
}
for (int i=0; i<length; i++) {
printf("%d ", *head);
head++;
}
puts("");
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
remove_negatives(a, l);
return 0;
}
Now the while loop works, buts as #wovano said, the answer is still wrong. Your code isn't exactly a "bubble sort". you swap all the negative number to the end of the array and didn't actually sort the array.
So, let's start from the beginning.
To simplify the process, let bubble sort first, and then find the new array length.
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int bubble_sort(int *array, int length) {
int i, j;
// Bubble sort
for (i=0; i<length-1; i++) {
for (j=i+1; j<length; j++) {
if (array[i]<array[j]) swap(&array[i], &array[j]);
}
}
// Find new array length
for (i=length-1; i>=0; i--) {
if (array[i]>=0) break;
length--;
}
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
l = bubble_sort(a, l);
for (int i=0; i<l; i++) printf("%d ", a[i]);
puts("");
return 0;
}

Related

Returning every s-th component of a vector abort problem in c

The task was to create a program in which you input a vector and it returnes every s-th component of the vector. For example, if x = (1, 2, 3, 4, 5, 6) and s = 2, the output is (1, 3, 5). But I get a zsh abort warning.
#include <stdio.h>
void sampleVector(double arr[], int n, int s){
int j = 0;
for (j=0; j<n; j++) {
arr[j] = 0;
printf("%d: ",j);
scanf("%lf",&arr[j]);
}
int i=1;
printf("%f,", arr[i]);
for (i=1; i<n; i++){
s=s*i;
printf("%f", arr[s]);
}
}
int main() {
int n;
scanf("%d", &n);
double arr[3]={0,0,0};
int s;
scanf("%d", &s);
sampleVector(arr, n, s);
}
This is my program so far!
void printfEveryNth(const int *array, size_t size, size_t n)
{
if(array && n)
{
for(size_t index = 0; index < size; index += n)
{
printf("%d ", array[index]);
}
printf("\n");
}
}
int main(void)
{
int array[] = {1, 2, 3, 4, 5, 6};
printfEveryNth(array, 6 , 2);
}
https://godbolt.org/z/e3Tsa8GKj

Permutations without repetition C

I have this code for permutation WITH repetition. Would anyone help to modify it to be WITHOUT repetition. I can't figure it out.
int array1[] = {1, 2, 3}; //array can be {1,1,2,3} for example also
int array2[3];
void permWithRep (int array1[], int array2[], int last, int index){
int i, len = last+1;
enter code here
for ( i=0; i<len; i++ )
{
array2[index] = array1[i] ;
if (index == last){
for(int i = 0; i < 3; i++) {
printf("%d ", array2[i]);
}
printf("\n");
}
else // Recur for higher indexes
permWithRep (array1, array2, last, index+1);
}
}
int main()
{
int len = sizeof(array1)/sizeof(int);
permWithRep (array1, array2, len-1, 0);
return 0;
}
I tested this on few inputs and it works.
There is certainly a better way to do it, but that's what i did:
#include <stdio.h>
int array1[] = {1, 2, 3}; //array can be {1,1,2,3} for example also
int array2[3];
int fixed[3];
void permWithRep(int array1[], int array2[],int fixed_index[], int size , int level){
if(level == size) return print_array(array2,size);
for(int k = 0; k< size; k++){
if(!is_present_in_fixed(fixed_index,level,k)){
fixed_index[level] = k;
array2[level] = array1[k];
permWithRep(array1,array2,fixed_index,size,level+1);
}
}
}
void print_array(int array[], int size){
for(int k = 0; k < size; k++)printf("%d ",array[k]);
printf("\n");
}
int is_present_in_fixed(int array[], int size, int element ){
for(int k =0; k<size;k++)
if(element == array[k]) return 1;
return 0;
}
int main()
{
int len = sizeof(array1)/sizeof(int);
permWithRep (array1, array2, fixed, len, 0);
return 0;
}
What I did:
Add an array (fixed_index[]) that keep track of the already visited indexes for one permutation.
In the loop, check if the index of current element belongs to the index already visited in that permutation (is_present_in_fixed(fixed_index,level,k)).
If so, it just skip that element (it does not enter the if statement).
Otherwise adds that element to the visited for that permutation and go on with recursive call.
When all array has been iterated on (level == size), just print the results contained in array2.

breadth-first search in C language

I have two integer lists say list_a and list_b.
I have a function say func(), and func(list_a) would produce n lists say:
list_a_1 list_a_2 list_a_3 list_a_4 ........... list_a_n
I have to run func() on all lists as produced above until I find one of those lists = list_b.
So below could be the possible representation of how the list grows:
list_a
============================================================================
list_a_1 list_a_2 list_a_3 list_a_4 ........... list_a_n LEVEL 1
============================================================================
list_a_1_1.... list_a_1_n list_a_2_1... list_a_2_n..... LEVEL 2
============================================================================
Suppose say we find list_a_1_n == list_b, then stop the function and return the LEVEL, which in our case is 2 (Level2).
I am not being able to do it :(
How to do it in C?
Please note, this is not a homework question.
I am trying to find Cyclic Kendal Tau distance between two inputs as I think I found a solution in terms of algorithm for this question. I want to check whether my algorithm is correct.
below is the code in Python:
import collections
def Transpose(alist):
leveloutput = []
n = len(alist)
for i in range(n):
x=alist[:]
x[i],x[(i+1)%n] = x[(i+1)%n],x[i]
leveloutput.append(x)
return leveloutput
def Cyc_Ken_Tau(start, goal):
queue = collections.deque([(start, 0)])
while True:
element, level = queue.popleft()
if element == goal:
return level
for new_list in Transpose(element):
queue.append((new_list, level + 1))
if __name__ == '__main__':
print "***********************************************************"
u = [2, 3, 4, 1]
v = [1, 2, 4, 3]
print "***********************************************************"
m = Cyc_Ken_Tau(u,v)
print "Cyclic Kendal Tau:",m
Also the partial code in C is as follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print_array(int **a, int num_elements);
int **transpose(int n, int arr[n]);
int main(){
int a[] = {2, 3, 4, 1};
int **c;
int n = sizeof(a)/sizeof(*a);
int i;
printf("original\n");
print_array2(a,4);
printf("\n*****************************\n");
c= transpose(n, a);
print_array(c, n);
//deallocate
for(i=0;i<n;++i)
free(c[i]);
free(c);
return 0;
}
int **transpose(int n, int arr[n]){
int l = n;
int **b = malloc(l * sizeof(*b));//sizeof(*b) : sizeof(int *)
int i, j, k;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
int *copy = malloc(l * sizeof(*copy));//sizeof(int)
for (k = 0; k < l; k++)
copy[k] = arr[k];
int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
//printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
b[i] = copy;
}
return b;
}
void print_array(int **a, int num_elements){
int i, j;
for(i=0; i<num_elements; i++){
for(j=0; j<num_elements; j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
void print_array2(int a[], int num_elements)
{
int i;
for(i=0; i<num_elements; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
But I am struggling with the Cyc_Ken_Tau function in C. Any help will be much much appreciated.

Find the union of two sets of 10 digit numbers

I'm trying to find the union of two sets of 10 digit numbers, I'm passing along three int arrays: first, second, and comp (this will hold the union set).
So far, I've added first and second into one array. I was thinking about finding the matching indices in comp[] then filter through deleting them. I figure there's a much easier way. Can anyone give me a hint?
Basically I'm taking
first[] = [1,2,3,4,5,6,7,8,9,10];
second[] = [1,2,3,4,11,12,13,14,15,16];
and I want to return
comp[] = [5,6,7,8,9,10,11,12,13,14,15,16];
The numbers won't necessarily be in order.
int compound(int first[],int second[],int comp[]){
int i=0;
int indicies[20];
for(int j = 0; j<SIZE; j++){
comp[i]=first[j];
i++;
}
for(int k = 0; k<SIZE; k++){
comp[i]=second[k];
i++;
}
int z=0;
for(int l = 0; l<SIZE*2; l++){
for(int m = 0; m<SIZE*2; m++){
if(comp[l]==comp[m]){
indicies[z]=m;
z++;
}}}
return 0;
}
A first good step is (nearly) always sorting.
Sort both input-sets (unless you know they are already sorted).
Then iterate over both at once (two indices) and only add those elements to the output which fulfill your criteria (seems to be union minus intersection, thus only in one).
Bonus: The output-set will be sorted.
I suggest you start by writing a contains(int[], int) method like
#include <stdio.h>
#include <stdbool.h>
bool contains(int arr[], int val) {
int offset;
for (offset = 0; arr[offset] != '\0'; offset++) {
if (arr[offset] == val) return true;
}
return false;
}
Then your compound method could be implemented using it with something like
int compound(int first[],int second[],int comp[]){
int i=0;
int j;
for(j = 0; first[j] != '\0'; j++){
int val = first[j];
if (contains(second, val) && !contains(comp, val))
comp[i++] = val;
}
return i;
}
Finally, you can test it like
int main(int argc, char *args[]) {
int a[] = {1,2,3,'\0'};
int b[] = {2,3,4,'\0'};
int c[3];
int count = compound(a,b,c);
int i;
for (i = 0; i < count; i++) {
printf("%i\n", c[i]);
}
}
Output is
2
3
If the numeric range is small you could do this:
#include <stdio.h>
#define MAX 20 // small numeric range
#define sz(a) (sizeof(a)/sizeof(*(a)))
int xunion(int *a, int sa, int *b, int sb, int *c) {
int n[MAX] = {0};
for (int i=0; i<sa; i++) n[a[i]] = 1;
for (int i=0; i<sb; i++) n[b[i]] = 1;
int j=0;
for (int i=0; i<MAX; i++) if (n[i]) c[j++] = i;
return j;
}
void prn(int *a, int s) {
while (s-- > 0) printf("%d ", *a++);
putchar('\n');
}
int main() {
int a[] = {6, 3, 4, 7, 5};
int b[] = {2, 4, 5, 7, 6, 3};
int c[MAX];
prn(a, sz(a));
prn(b, sz(b));
int n = xunion(a, sz(a), b, sz(b), c);
prn(c, n);
return 0;
}

trying to print largest value of the array..but printing garbage

Hey i am trying to print largest element in an array using function and pointers. Below is my code but its printing garbage value. Please help.
void findmax(int arr[],int,int*);
void findMax(int arr[], int n, int* pToMax)
{
if (n <= 0)
return; // no items, no maximum!
int max = arr[0];
pToMax = &arr[0];
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
max = arr[i];
pToMax = (arr+i);
}
}
}
int main()
{
int nums[4] = { 5, 3, 15, 6 };
int *ptr;
findMax(nums, 4, ptr);
printf("The maximum is at address %u\n", ptr);
printf("It's at index %d\n",ptr - nums);
printf("Its value is %d\n", *ptr);
}
With int *pToMax in findMax(int arr[], int n, int* pToMax) and
calling as findMax(nums, 4, ptr); you just pass ptr as a value.
The updated value won't be reflected after function exits.
You need to use **pToMax
to save address.
void findMax(int arr[], int n, int** pToMax)
{
if (n <= 0)
return; // no items, no maximum!
int max = arr[0];
*pToMax = &arr[0]; //Store base address
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
max = arr[i];
*pToMax = (arr+i); //Store max address
}
}
}
call using
findMax(nums, 4, &ptr);

Resources