I can't find any errors here. The purpose of the program is to thing all possible combinations of array elements and their sums. I'm trying to write a program which will return me an array of elements where every next one does not equal any previous one or the sum of any previous combinations of elements. I started like this and encountered an error: it says that program has stopped working...
#include <stdio.h>
int m[20];
void initm(int x[]) {
for(int i=0; i<20; i++) {
m[i]=i;
}
}
void sorter(int x[]) {
for(int i=0; i<20; i++) {
for(int j=0; j<20; j++) {
/* nested for loop to get all possible combinations */
printf("%d===%d===%d", x[i], x[j], x[i]+x[j]);
}
}
}
int main() {
initm(m[20]);
sorter(m[20]);
return 0;
}
m[20] reads an int one element beyond the end of your array so
initm(m[20]);
sorter(m[20]);
should be
initm(m);
sorter(m);
Related
We want to use Bucket sort to sort numbers between 1 to 2001. the count of numbers can be 10E6.
I know the bucket sort algorithm. But the issue is that in this question, we are not permitted to use variable-length array, vector and pointer. (The only pointer related thing allowed is "pass by reference" of the array) The only solution I found is using using counting sort for each bucket, like the code below, so the code is more like counting sort than the bucket sort: (C language)
#include <stdio.h>
int buckets[201][10]={}; int numbers[1000001]={};
void bucket_sort (int a[],int n) {
for (int i =0;i<=n-1;i++)
{
int index = a[i]/10, index2 = a[i]%10;
buckets[index][index2]++;
}
int counter =0;
for (int i =0;i<=200;i++)
{
for (int j =0; j<=9;j++)
{
while (buckets[i][j])
{
a[counter] = i*10+j;
counter++;
buckets[i][j]--;
}
}
} }
int main() {
int n;
scanf("%d",&n);
if (n==0)
{
return 0;
}
for (int i =0;i<=n-1;i++)
{
scanf("%d",&numbers[i]);
numbers[i];
}
bucket_sort(numbers,n);
for (int i =0;i<=n-1 ;i++)
{
printf("%d\n", numbers[i]);
}
return 0; }
I want to know can bucket sort be implemented without variable-length array, vector and pointer and also without counting sort. Probably using Insertion or Bubble sort. Note that it must be a reasonable bucket-sort algorithm. So defining very big buckets like int bucket [201][1000000]; is also an unacceptable approach.
Given that you can't use variable length arrays or pointers, one of which is required for a bucket sort, your best bet is to go with a counting sort. You only have 2000 possible values, so create an array of size 2000 and for each value you find increments the corresponding array element.
void counting_sort(int a[], int n)
{
int count[2002] = { 0 };
int i, j;
for (i=0; i<n; i++) {
count[a[i]]++;
}
for (i=0, j=0; i<n; i++) {
while (!count[j]) {
j++;
}
a[i] = j;
count[j]--;
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I want to sort 12 integers using a "reverse bubble sort" (We call it "the drowning axe sort", whatever). My function looks good to me but something goes wrong.
Error: having typed my 12 random numbers I don't get the result printed, instead my compiler stops and does not proceed any further.
Can anyone help?
Code:
#include<math.h>
#include<math.h>
void array_clean(int a[11]) //just an array cleaner
{
for(int i=0; i<12; i++)
{
a[i] = a[i]&&0; // smth && 0 = 0 anyway
}
}
void axe_sort(int a[11]) //drowning-axe sort function
{
int place = 0;
for(int i=0; i<12; i++)
{
for(int j=0; j<12; j++)
{
if(a[j]<a[j+1])
place=a[j];
a[j] = a[j+1];
a[j+1] = place;
}
}
}
int main(void)
{
int array[11]; //declaring an integer array;
array_clean(& array[11]); // giving user-filed array to a cleaner function
printf("Enter 12 random integers you'd like to sort: ");
for(int m=0; m<12; m++)
{
scanf("%d", &array[m]); //letting user to fill an array
}
axe_sort(&array[11]); //sorting an array via our axe_sort function
for(int m=0; m<12; m++)
{
printf("%d", array[m]); //printing the sorted array
}
return 0;
}
Your array int array[11]; isn't doing what you think it is. That declares an array of 11 ints, indexed from 0 to 10 inclusive. There is no array[11] therefore trying to access this will lead to undefined behavior.
You've got the correct form of your for loop, it'll correctly iterate over 12 members of the array, numbered 0 to 11 inclusive. However you need to declare the array as int array[12]; to get it big enough to work.
Also, you're passing the array to the two functions using &array[11]. You just need to say array and it'll pass in the array correctly. What you're doing will cause the two functions to write over random memory, which definitely won't help.
Try fixing these and see what changes.
First of all, You should include stdio.h header file in order to use printf() and scanf()
You are dealing with 12 integers. Then Why did you declare an array of 11 integers???
int array[11]; //declaring an integer array; <-------- change the size to 12 from 11
The purpose of the array_clean(); is to initialize each number with 0. You can simply put 0 instead of a[i]&&0;
Here you are passing the address of 12th element.
array_clean(&array[11]); //<---------------------
You should pass the address of the base element(1st).
You can do this by two ways.
array_clean(&array[0]);
Or,
array_clean(array);
When an array is used as a value, its name represents the address of the first element.
And finally, please check your bubble sort logic.
for(int j=0; j<12; j++)
{
if(a[j]<a[j+1])
{place=a[j]; //<-----curly braces missing in the body of if
a[j] = a[j+1]; //<----error
a[j+1] = place;
}
}
For j=11, your code will try to access 12th index and that will give you a segmentation fault. Enclose the body of if with curly braces.
Here is the modified code
#include<math.h>
#include<stdio.h> // <---------- include this header file
void array_clean(int a[12]) //just an array cleaner
{
for(int i=0; i<12; i++)
{
a[i] = 0; // smth && 0 = 0 anyway
}
}
void axe_sort(int a[12]) //drowning-axe sort function
{
int i,j;
for(i=0; i<11; i++)
{
for(j=0; j<11-i; j++) //<-------- see the logic carefully
{
if(a[j] < a[j+1]) //<-----put curly braces
{int place=a[j];
a[j] = a[j+1];
a[j+1] = place;}
}
}
}
int main(void)
{
int array[12]; //declaring an integer array;
array_clean(&array[0]); // <---------------- pass the base address
printf("Enter 12 random integers you'd like to sort: ");
for(int m=0; m<12; m++)
{
scanf("%d", &array[m]); //letting user to fill an array
}
axe_sort(&array[0]); // <---------------- pass the base address
for(int m=0; m<12; m++)
{
printf("%d ", array[m]); //printing the sorted array
}
return 0;
}
I think you forgot to include the stdio.h library in your code
I am currently working on a simple code to store and display top-right triangular matrix. Well, everything was fine till I tried to input 4x4 matrix structure and gave the input. The first array of structure's (called a) last value changed although I did not put any code to change ANY of the values in a. It happens in the mReorder() function. Then I tried some try-and-errors find out the problem in the 3rd row of mReorder() function. I wonder why and how to solve it.
Here is my complete code:
#include<stdio.h>
//CMO fashion
typedef struct
{
int row;
int col;
int val;
}term;
#define MAX_TERMS 10
term a[MAX_TERMS], b[MAX_TERMS];
void mReorder(void);
int main()
{
int n, i, j;
printf("Enter the number of rows: ");
scanf("%d", &n);
if (n<1 || n>MAX_TERMS)
{
printf("\nInvalid number of rows!!");
exit(0);
}
i=nCount(n);
mRead(n,i);
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
mReorder();
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
printf("\n");
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", b[j].col, b[j].row, b[j].val);
mDisplay();
return 0;
}
void mReorder(void)
{
int i, j, k, m=1;
b[0].col=a[0].col;
b[0].row=a[0].row;
b[0].val=a[0].val;
for(i=0; i<a[0].col; i++)
for (j=1; j<=a[0].val; j++)
if (a[j].row==i)
{
b[m].col=a[j].col;
b[m].row=a[j].row;
b[m].val=a[j].val;
m++;
}
}
void mDisplay(void)
{
int i, j, k, m=1;
printf("\nThe resulting matrix is:\n");
for (i=0; i<b[0].col; i++)
{
//printf("\na");
for (k=0; k<i; k++) printf("%5c", '-');
for (j=i; j<b[0].col; j++)
{
printf("%5d", b[m].val);
m++;
}
printf("\n");
}
}
void mRead(int n, int x)
{
int i, j, m=1, val;
printf("\nEnter %d elements of the matrix: \n", x);
a[0].row=a[0].col=n;
a[0].val=x;
for (i=0; i<n; i++)
{
for (j=0; j<=i; j++)
{
scanf("%d", &val);
a[m].row=j;
a[m].col=i;
a[m].val=val;
m++;
}
}
}
int nCount(int n)
{
if (n==1)
return 1;
return (n+nCount(n-1));
}
Can you explain what's going on here?
You allocate enough space for 10 term items, but nCount(4) returns 10, and nCount(5) returns 15, etc. If you specify a value bigger than 4, you overflow your array boundaries, leading to undefined behaviour — which is something to be avoided at all costs. In practice, one of your two arrays tramples over the other, but what happens when you access the other array out of bounds is entirely up to the compiler. It may appear to work; it may crash horribly; it may corrupt other data structures.
Nominally, since you allocate 10 elements in the arrays a and b, you should be OK with the 4x4 data, but in mRead(), you set m = 1 to start with, so you end up writing to a[10] in the last iteration of the loop, which is outside the bounds of the array. Remember, C arrays are indexed from 0, so an array defined as SomeType array[N]; has elements from array[0] to array[N-1].
Note that you can rewrite nCount() as a simple (non-recursive) function:
static inline int nCount(int n) { return (n + 1) * n / 2; }
(which would need to appear before it is called, of course). Or, if you're stuck using an archaic compiler that doesn't support C99 or C11, drop the inline keyword.
I have a 2d array which has same numbers in a row.
I have to find the index of the elements in increasing order and put it in another array.
For example, assume that the input array has the following numbers:
int test[5][2]= { {12,12},{3,3},{14,14},{5,5},{8,8} }.
I have to output in result array with:
result[5] = {1,3,4,0,2}.
Just the index of the elements in increasing order...
I wrote this program, but the result array is always 1.
int main()
{
int N=5;
int result[5];
int test[5][2] = { {12,12},{3,3},{14,14},{5,5},{8,8} };
int i,j;
int smallindex = 0;
for (j=0; j<5; j++)
{
for (i=1; i<5; i++)
{
if (test[i][0] < test[i-1][0])
{
smallindex=i;
}
}
result[j]=smallindex;
}
for (j=0; j<5; j++)
{
printf("%d \t ", result[j]);
}
}
Can anyone tell me what is wrong in this?.
thanks
Make little modification for if statement in your code.
for(i=0;i<5;i++)
{
smallindex=0;
for(j=0;j<5;j++) {
//try to avoid comparing same element by checking i==j
if(test[i][0]<test[j][0])
smallindex++; // check each element with all elements.count how many elements are greater than specific element.increment count and at the end of inner loop assign to result array.
}
result[i]=smallindex;
}
I have implemented the Kruskal algorithm in C using an adjacency matrix graph representation, the problem is, it keeps popping up segmentation fault error, I've been trying to figure out what is wrong for quite a while and I can't seem to find the problem, could anyone else take a look please?
Thanks.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define MAXVERT 10
#define MAXEDGES 20
#define INF 100000
/*graph representation using an Adjacency matrix*/
typedef struct AdjMatrix
{
int nodes;
int adjMat[MAXVERT][MAXVERT];
} graph;
/*function prototypes*/
int find(int node, int *trees);
void merge(int i, int j, int *trees);
void printminimal(int min[][3], int n);
/*main algorithm*/
void kruskal(graph *g)
{
int EDGES[MAXEDGES][3]; /*graph edges*/
int MINEDGES[MAXVERT-1][3]; /*edges already in the minimal spanning tree*/
int nextedge=0;
int numedges=0;
int trees[MAXVERT]; /*tree subsets*/
int i, j, k;
int temp;
for(i=0;i<g->nodes;i++)
trees[i]=i;
k=0;
for(i=0; i<g->nodes; i++)
for(j=0; j<g->nodes; j++)
{
if(i<j)
{
EDGES[k][0]=i;
EDGES[k][1]=j;
EDGES[k][2]=g->adjMat[i][j];
k++;
}
else
break;
}
/*Bubblesort*/
for(i=0; i<g->nodes; i++)
for(j=0; j<i; j++)
{
if(EDGES[j][2] > EDGES[j+1][2])
{
temp=EDGES[j][0];
EDGES[j][0]=EDGES[j+1][0];
EDGES[j+1][0]=temp;
temp=EDGES[j][1];
EDGES[j][1]=EDGES[j+1][1];
EDGES[j+1][1]=temp;
temp=EDGES[j][2];
EDGES[j][2]=EDGES[j+1][2];
EDGES[j+1][2]=temp;
}
}
while(numedges < (g->nodes-1))
{
i=find(EDGES[nextedge][0], trees);
j=find(EDGES[nextedge][1], trees);
if((i!=j)&&(EDGES[nextedge][2]!=-1)) /*check if the nodes belong to the same subtree*/
{
merge(i,j,trees);
MINEDGES[numedges][0]=EDGES[nextedge][0];
MINEDGES[numedges][1]=EDGES[nextedge][1];
MINEDGES[numedges][2]=EDGES[nextedge][2];
numedges++;
}
nextedge++;
}
}
int find(int node, int *trees)
{
if(trees[node]!=node)
return trees[node];
else
return node;
}
void merge(int i, int j, int *trees)
{
if(i<j)
trees[j]=i;
else
trees[i]=j;
}
void printminimal(int min[][3], int n)
{
int i, weight=0;
printf("Minimal tree:\n(");
for(i=0;i<n;i++)
{
printf("(V%d,V%d), ", min[i][0],min[i][1]);
weight+=min[i][2];
}
printf(")\n Total weight sum of the minimal tree is: %d", weight);
}
int main(void)
{
int i,j;
graph *g=(graph *)malloc(sizeof(graph));
/*int adjMat[8][8] = {0,INF,INF,11,INF,1,7,
INF,0,INF,3,INF,4,8,INF,
INF,INF,0,INF,INF,INF,12,INF,
INF,3,INF,0,15,INF,INF,INF,
11,INF,INF,INF,0,20,INF,INF,
INF,4,INF,INF,20,0,INF,INF,
1,8,12,INF,INF,INF,0,5,
7,INF,INF,INF,INF,INF,5,0};*/
for(i=0;i<4;i++)
for(j=0;j<i;j++)
{
if(i==j)
{
g->adjMat[i][j]=0;
continue;
}
printf("%d-%d= ", i, j);
scanf("%d", &(g->adjMat[i][j]));
g->adjMat[j][i]=g->adjMat[i][j];
}
g->nodes=4;
kruskal(g);
}
In the kruskal function, where you intend to populate the EDGES array, you don't:
for(i=0; i<g->nodes; i++)
for(j=0; j<g->nodes; j++)
{
if(i<j)
{
EDGES[k][0]=i;
EDGES[k][1]=j;
EDGES[k][2]=g->adjMat[i][j];
k++;
}
else
break;
}
For j == 0, i is never < j, so you immediately break out of the inner loop. I suspect it should be i > j in the condition.
Since EDGES is uninitialised, find tries to access an unspecified element of trees.
I had to add the following to get this to kruskal to get it to compile from gcc:
int *dvra = trees;
You can then compile it with debug information:
gcc -g -o kruskal kruskal.c
and run it through gdb:
gdb kruskal
You can then type run and enter to start the program. I entered 1,2,3,... when prompted for values.
This then gives:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400a92 in find (node=32767, trees=0x7fffffffe110) at test.c:86
86 if(trees[node]!=node)
Hmm, that's curious. Trees holds only 10 items (value of the MAXVERT define), so accessing node 32767 goes out of bounds. If you enter 32767 in the calculator program and go to the programming (hexadecimal) mode, you will find it is 7FFF (or MAX_SHORT, the maximum 16-bit signed integer value). That's also interesting.
NOTE: You can investigate variable values by using the print command (e.g. print node) and the backtrace using the bt command.
These are coming from the while loop in kruskal (the only place that is calling find), so we need to investigate where that value is coming from. Lets quit out of gdb (press 'q' and enter then confirm with 'y' and enter).
Add the following to the while loop and run the resulting program:
printf("%d: nextedge=%d EDGES[nextedge][0]=%d EDGES[nextedge][1]=%d\n", numedges, nextedge, EDGES[nextedge][0], EDGES[nextedge][1]);
which gives:
0: nextedge=0 EDGES[nextedge][0]=-557487152 EDGES[nextedge][1]=32767
So it looks like EDGES[0] is not being initialized, which points to the if(i<j) condition in the initialization loop above the bubblesort. OK, so lets trace what is happening in the initialization loop by adding the following inside the if loop:
printf("EDGES[%d]: 0=%d 1=%d\n", k, i, j);
Rerunning this, we see that there are no lines associated with this statement, so it is not getting executed.
Changing the if condition to:
if(i<=j)
causes the statement to be executed and the segment fault to go away.