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.
Related
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;
}
I have this C code that creates an array with 100 random numbers and I want to sort it using quick sort, but it always gives a Segmentation fault error.
Here is the code:
#define MAX 100
int a[MAX];
void quick_sort(double *x, int l, int r) {
int l1, r1;
if (l < r) {
l1 = l;
r1 = r;
do {
while (l1 < r && x[l1 - 1] <= x[l - 1]) {
l1++;
}
while (l < r1 && x[r1 - 1] >= x[l - 1]) {
r1--;
}
if (l1 < r1) {
swap(&x[l1 - l], &x[r1 - 1]);
}
} while (l1 < r1);
swap(&x[l - 1], &x[r1 - 1]);
quick_sort(x, l, r1 - 1);
quick_sort(x, r1 + 1, r);
}
}
void printArray(int a[], int size) {
int i;
for (i = 0; i < size; i++)
printf("%d ", a[i]);
printf("\n");
}
int main() {
int i = 1;
int a_size = sizeof(a) / sizeof(a[0]);
srand((unsigned int)time(NULL));
for (i = 0; i < MAX; i++) {
a[i] = rand() % 501;
}
quick_sort(a, 0, a_size);
printArray(a, a_size);
}
The error is that nothing prints when I run the program.
Can someone help me with the problem?
There are many problems in your code:
You do not include <stdio.h>, <stdlib.h>, nor <time.h>.
Your quick_sort function expects a pointer to an array of double, yet you pass an array of int.
The code for function swap() is not posted.
Your implementation of the Quick Sort algorithm in function quick_sort is flawed:
you should not scan slices of size 1, use (r - l > 1).
You cannot use x[l - 1] as pivot, it is not even part of the slice to be sorted. Furthermore, you should extract the pivot from the array before the swapping phase as it may move.
You should not name a variable l, it looks too close to 1 and you do make the mistake here: swap(&x[l1 - l], &x[r1 - 1]);
You should initialize l1 and r1 such that you do not need to subtract 1 in so many places, it leads to confusion and erroneous code.
Study the algorithms from the Wikipedia article and translate one to C.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 100
void swap(int *a, int *b) {
int x = *a;
*a = *b;
*b = x;
}
// Quick Sort using Hoare's original partition scheme
void quick_sort(int *x, int l, int r) {
if (l < r) {
int pivot = x[l];
int l1 = l - 1;
int r1 = r;
for (;;) {
while (x[++l1] < pivot)
continue;
while (x[--r1] > pivot)
continue;
if (l1 < r1) {
swap(&x[l1], &x[r1]);
} else {
break;
}
}
quick_sort(x, l, r1 + 1);
quick_sort(x, r1 + 1, r);
}
}
void printArray(int a[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main(void) {
int a[MAX];
int a_size = sizeof(a) / sizeof(a[0]);
srand((unsigned int)time(NULL));
for (int i = 0; i < MAX; i++) {
a[i] = rand() % 501;
}
quick_sort(a, 0, a_size);
printArray(a, a_size);
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
in visuals studio i try to make respectively sum of rows. but first sum multiplied by 4 . i didnt understand this situation
get_sum(int **q, int p, int n);
int main(void)
{
int num[3][5] = { 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 };
get_sum(&num[0][0], 3, 5);
}
get_sum(int **q, int p, int n)
{
/*for (int i = 0; i < ; i++)
printf("%d\n", *(q + i));*/
for (int k = 0; k < p; k++)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum =*(q + n*k + i)+sum;
printf("%d\n", sum);
}
}
}
If I understand you simply want to create a function that sums the elements of the array passed as a parameter, along with the dimensions of the array, then you have the right idea, but woefully wrong syntax.
Rather than verbally discussing each change, the simple example contains all the changes. Look over the changes and why they were made:
#include <stdio.h>
int get_sum (int (*q)[5], int p, int n);
int main (void)
{
int num[3][5] = {{ 10, 11, 12, 13, 14 },
{ 15, 16, 17, 18, 19 },
{ 20, 21, 22, 23, 24 }};
int sum = get_sum (num, 3, 5);
printf (" -----------\n sum : %d\n", sum);
return 0;
}
int get_sum (int (*q)[5], int p, int n)
{
int sum = 0;
for (int k = 0; k < p; k++) {
for (int i = 0; i < n; i++)
sum += q[k][i];
printf ("row[%2d] : %d\n", k, sum);
}
return sum;
}
(note: the loop output within get_sum provides are running-total of the sum after the addition of each row elements. You can tailor this to meet your needs.)
Example Use/Output
$ ./bin/get_sum
row[ 0] : 60
row[ 1] : 145
row[ 2] : 255
-----------
sum : 255
Let me know if you have any questions.
You are indexing a 1-D array as if it is a 2-D array, but there is no need to define it as 2-D, and anyway, you initialise it as if it were a 1-D array.
#include <stdio.h>
void get_sum(int *q, int p, int n); // only one start
int main(void)
{
int num[] = { 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 }; // 1-D linear array
get_sum(num, 3, 5);
return 0;
}
void get_sum(int *q, int p, int n) // added return type
{
int k, i, sum;
for (k = 0; k < p; k++) {
sum = 0;
for (i = 0; i < n; i++) {
sum = *(q + n*k + i) + sum;
}
printf("%d\n", sum); // moved out of inner loop
}
}
Program output
60
85
110
Alternatively if you do want a 2-D array and then index into it as if it were a 1-D array, you can do this. Note I have initialised the array differently but get_sum is the same.
#include <stdio.h>
void get_sum(int *q, int p, int n); // only one start
int main(void)
{
int num[3][5] = {{10,11,12,13,14}, {15,16,17,18,19}, {20,21,22,23,24}};
get_sum(&num[0][0], 3, 5);
return 0;
}
void get_sum(int *q, int p, int n) // added return type
{
int k, i, sum;
for (k = 0; k < p; k++) {
sum = 0;
for (i = 0; i < n; i++) {
sum = *(q + n*k + i) + sum;
}
printf("%d\n", sum); // moved out of inner loop
}
}
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;
}
#include "stdio.h"
void main(){
int a[2][2]={1, 2, 3, 4};
int a[2][2]={1, 2, 3, 4};
display(a, 2, 2);
show(a, 2, 2);}
}
display(int *k, int r, int c){
int i, j, *z;
for(i = 0; i < r; i++){
z = k + i;
printf("Display\n");
for(j = 0; j < c; j++){
printf("%d", *(z + j));
}
}
}
show(int *q, int ro, int co){
int i, j;
for(i = 0; i < ro; i++){
printf("\n");
for(j = 0; j < co; j++){
printf("%d", *(q + i*co + j));
}
}
}
Output:
Display
12
23
Show
12
34
Why Display() is not showing 1223 while show() gives 1234? Both uses the same logic to display the 2d array. Can any one help please?
In display you are using two counters, i for rows and j for columns. Since the array is laid out sequentially in memory you need to increase i by the size of a column, i.e. c, each time you want to move from one row to the next. So, you should add i*c to k, not i.
The complete function:
display(int *k,int r,int c){
int i,j,*z;
for(i=0;i<r;i++){
z=k+i*c;
printf("Display\n");
for(j=0;j<c;j++){
printf("%d",*(z+j));
}
}
}
To access 2D array using pointers:
#define R 2
#define C 2
...
int A[R][C]={1, 2, 3, 4};
for(i=0;i<R;i++)
for(j=0;j<C;j++)
printf("%d ",*(*(A+i)+j));
...