Boubble sorting with arrays with C - c

#include <stdio.h>
int main(){
void sorting(){
int a[4];
a[0]=1;
a[1]=6;
a[2]=15;
a[3]=3;
a[4]=19;
int size = 4;
int t =1;
if (size ==0) return; // ie if you reach to the end stop
int i;
for (i=0;i<size-1;i++){
if(a[i+1] >a[i]) { //if the +1 element is bigger than before it do the swap
int j;
j= a[i+1];
a[i+1]=a[i]; //swap
a[i] = j; //swap
}
}
sorting(*a,size - 1);//recursion
void print_int() {
int i; // Loop counter
for (i = 0; i < 4; i++) {
printf("%d\n", a[i]);
}}
}
It compiles ok but when I try to run the file nothing appears? My intentions were to create an array sort them then display them.
Also, the code where the recursion happened "sorting(*a,size - 1);//"
if I tried to replace *a with a[] an error will happen. Why is that?
the error is "error expected expression before ']' token"!
thank you.

int a[4];
But you access a[4]=19; index 4 that is out of bound. You can access highest index 3.
I think function void sorting() should be defined outside main .Nested functions are GNU extensions in GCC.

Your code has to many problems. Here is a working Array sort:
#include <stdio.h>
void bubble_sort(int *array, int length){
int i,j, k, temp;
for (i = 0 ; i < length-1; i++){
for (k = 0 ; k < length-i-1; k++){
if (array[k] > array[k+1]){
temp = array[k];
array[k] = array[k+1];
array[k+1] = temp;
}
}
}
printf("The sorted Array List:\n\n");
for ( j = 0 ; j < length ; j++ ){
printf("%d ", array[j]);
}
}
int main(void){
int array[] = {1,6,15,3,19};
int length = sizeof array / sizeof array[0];
bubble_sort(array, length);
printf("\n");
return 0;
}
You should read about functions declarations and definitions.
About arrays you should know that if you declare:
int array[4];
Your working array is from 0 to 3 and not from 0 to 4.
Take a look at the following:
int main(void){
int array[] = {1,6,15,3,19};
int size = 5;
int i;
for(i=0;i<size;i++){
printf("%d ",array[i]);
}
return 0;
}
I have size=5 and not size=4- like you tried. You should be careful about number of Array elements.

Aside from all the problems spotted by others, you must repeatedly execute the for loop until no more exchanges are made, which is the standad way of bubbling. As you use recursion, it is of course nonsense to declare the array to be sorted (and its size) inside the function called recursively.

Related

The count of duplicate elements is double what it should be

I am working on an old exam and the problems states that a given array (int zahlen[]={1,4,5,1,5,7,9,2,3,4}) has values that are the same. The task is to replace the values that are the same with '-1'. After each replacement, a given variable, count, has to be increased by one.
My problem is that the variable count is two-times higher than normal (In this case there are only 3 of the same numbers and the variable shows 6.)
The function is called array_unique. I am would be grateful for a brief explanation of my mistake.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("chcp 1252");
int zahlen[]={1,4,5,1,5,7,9,2,3,4};
int len = sizeof(zahlen)/sizeof(int);
int erg = array_unique(zahlen,len);
printf("Es wurden %d doppelte Zahlen gelöscht: \n",erg);
printf("Das Array hat nun folgende Werte: ");
printArrayUnique(zahlen,len);
return 0;
}
void printArrayUnique(int *array, int len){
for(int i=0; i<len; i++){
if(array[i]!=-1){
printf("%d ",array[i]);
}
}
}
int array_unique(int *array, int len){
int count=0;
for(int i=0; i<len;i++){
for(int j=i+1; j<len;j++){
if(array[i]==array[j]){
array[j] = -1;
count++;
}
}
}
return count;
}
I have not figured out any other solution to fix the faulty value of count.
The issue is due to the fact that your are counting duplicates more than once; so, when you have found a duplicate entry, you correctly replace that with -1 but then, later in the loops, you will be (potentially, at least) comparing two or more of those -1 values.
Just add a check that either value is not -1 (along with the test for equality) before incrementing the count variable:
int array_unique(int* array, int len)
{
int count = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (array[i] == array[j] && array[j] != -1) {
array[j] = -1;
count++;
}
}
}
return count;
}
Note also that, as mentioned in the comments, you really do need declarations of your functions before you use them. Add the following two lines before the main function:
void printArrayUnique(int* array, int len);
int array_unique(int* array, int len);

Trying to write a program to fill an array with random numbers in C

My issue is that I am getting segmentation fault (core dumped) each time I try, I have yet to clean up my code, but I am stumped.
I must enter the values in with the compiler e.g "./filename 0 100" whereby 0 is min and 100 is max.
It must then fill the array of 10 elements with random numbers (0-100). I am so close, just can't fathom the main function.
Also, how can I print the array {0,1,2,3} in format "[0,1,2,3]" including the commas, without it looking like "[0,1,2,3, ]"
#include <stdlib.h>
#include <stdio.h>
int getRandom(int min, int max);
void fillArray(int data[], int size, int min, int max);
void printArray(int data[], int size);
int main(int argc, char *argv[]) {
int a;
int b;
if (argc>=3){
a = atoi(argv[1]);
b = atoi(argv[2]);
int arr[10];
printf("\t An array with random values from 0 to 100 \n");
fillArray(arr,10 ,a, b);
printArray(arr, 10);
} else {
printf("Incorrect number of arguments - please call with assignment min max\n");
}
return 0;
}
int getRandom(int min, int max) {
int result = 0;
int low = 0;
int high = 0;
if (min<max) {
low = min;
high = max+1;
} else {
low = max + 1;
high = min;
}
result = (rand() % (high-low)) + low;
return result;
}
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){
data[i] = getRandom(min,max);
}
}
void printArray(int data[], int size){
int i;
printf("[");
for(i=0; i<size; i++){
printf("%d,", data[i]);
}
printf("]");
}
I agree with #Steve Friedl that the main problem with your program lies in the fillArray function. There i should run from 0 to size.
As for your second question, testing whether you're printing the last number helps to suppress the unwanted comma:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", data[i]);
if (i < size - 1)
printf(",");
}
printf("]");
}
If you prefer a more compact solution (although with an optimizing compiler there's not really a difference), you could write it as:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d%c", data[i], i < size-1 ? ',' : ']');
}
}
Also, in your main function, you should include a and b in your printing:
printf("\t An array with random values from %d to %d \n", a, b);
I believe this is blowing things up for you:
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){ // <-- HERE
data[i] = getRandom(min,max);
}
}
The calling function allocates 10 items in the arr array, and that's passed as the size parameter, but you're not using that parameter to limit filling up the array. If the max value is 100, then it's trying to fill one hundred slots instead of just ten.
for (i = 0; i < size; i++)
data[i] = getRandom(min,max);
should fix at least this issue.
EDIT: The comma thing, I prefer to add commas before the items unless this is the first. In this case it doesn't matter much, but it's more general, especially for variable-length lists where you don't know you're at the end until you get there. Augmenting the helpful response from #JohanC :
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
if (i > 0) printf(",");
printf("%d", data[i]);
}
printf("]");
}

Find partial sum of 'X' numbers in array in c

can you help me with code which returns partial sum of 'X' numbers in array in c?
Complete :
int arr_sum( int arr[], int n )//Recursive sum of array
{
if (n < 0) //base case:
{
return arr[0];
}
else
{
return arr[n] + arr_sum(arr, n-1);
}
}
void sum_till_last (int *ar,int si )
{
**int sum,i;// the problem some where here
ar=(int*) malloc(si*sizeof(int));
for (i=0; i<si;i++)
{
sum=arr_sum(ar,i);
ar [i]=sum;
}
free (ar);**
}
void main ()
{
int i;
int a [5];
for (i = 0; i < 5; i++)
scanf_s("%d", &a[i]);
sum_till_last(a,5);
printf("%d\n",a[5]);
}
\i want to create new array with this this legality:
My input :
4
13
23
21
11
The output should be (without brackets or commas):
4
17
40
61
72
Now when we can see the full code, it's quite obvious that the problem is in the sum_till_last function where you overwrite the pointer you pass to the function with some new and uninitialized memory you allocate.
Drop the allocation (and the call to free of course). And fix the logical bug in arr_sum that causes you to get arr[0] + arr[0] when i is zero.
Here you go:
#include <stdio.h>
int main () {
int in_arr[5] = {4,13,23,21,11};
int out_arr[5];
int p_sum =0;
int i;
for ( i=0;i<5;i++){
out_arr[i] = in_arr[i]+p_sum;
p_sum=p_sum+in_arr[i];
}
for (i=0;i<5;i++){
printf("%d", out_arr[i] );
}
}
Fix according to your policy
#include <stdio.h>
#include <stdlib.h>
int arr_sum(int arr[], int n){
if (n == 0){//Change to this
return arr[0];
} else {
return arr[n] + arr_sum(arr, n-1);
}
}
void sum_till_last(int *ar, int si){
int sum,i;
int *temp = malloc(si * sizeof(int));//variable name ar is shadowing parameter name ar.
for(i = 0; i < si; i++){
temp[i] = arr_sum(ar, i);
if(i)
putchar(' ');
printf("%d", temp[i]);//need print out :D
}
free(temp);
}
int main(void){
int i, a[5];
for (i = 0; i < 5; i++)
scanf_s("%d", &a[i]);
sum_till_last(a, 5);
//printf("%d\n",a[5]);<-- this print only one element. and It's out of bounds element XD
}
I just made it simple so it´s easy to understand :)
I´m assuming "n" is always equal or less then array element number. Then you just print the SUM.
#include <stdio.h>
int arr_sum( int arr[], int n ){
int i=0,SUM=0;
for(; i < n;i++){
SUM= SUM+ arr[i];
printf("%d ",SUM);
}
}
int main(void) {
int array[] = {4, 13, 23, 21, 11};
arr_sum(array,5);
return 0;
}

Optimizing a 'sorting code' in C

I am working on a code I want to optimize. The code is all about sorting a double array by ascending order of its second .
The first input is an integer N, and the second is a 2D array of size N*2 (call it c), then we sort the array by ascending order of c[.][1], and when there are equal elements, say if c[i][1]==c[j][1], for two integers i and j, we sort those elements by ascending of the elements of the first columns, so c[i][1] is below c[j][1] if c[i][1]<c[j][1]. Let's take an example :
input
3
2 3
1 3
4 2
output
4 2
1 3
2 3
The fact is that the code needs to run in less than 0.5s and mine is really too slow. Here it is
#include <stdio.h>
#include <stdlib.h>
//determining the index of the max elments in an array
int max(int i, int N, int **c)
{
int j=0;
int M=0;
for(j=0;j<i;j++)
{if(c[j][1]>c[M][1]){M=j;}else{}}
return M;
}
int main ()
{
//integers used for the loops
int i;
int j;
//the size of the 2D array is N*2
int N;
scanf("%d",&N);
int **c;
int mx;
int maxi;
//this array is the output, thath is the 2D array sorted
int e[N][2];
//2D array we want to sort
c = malloc(N*sizeof(int*));
for (i=0;i<N;i++)
{
c[i] = malloc(2*sizeof(int));
for (j=0;j<2;j++)
{
scanf("%d",&c[i][j]);
}
}
//at the first step, we have initialized the value of the max
maxi=max(N,N,c);
for(i=0;i<N;i++)
{
//we sort the c[.][1], and we take the max (called 'mx') of the array. At each step of the loop, we throw away the max from the array c[.][1] (we mean the max found at the precedent step of the loop)
mx=max(N-i,N,c);
//Here, we look at the multiple occurence of the max, if there are, we sort the c[.][0] for which c[.][1]=c[mx][1] by ascending order
if(maxi==mx){int k;
for(k=0;k <N;k++){if(c[k][1]==c[mx][1]){if(c[k][0]>c[mx][0]){mx=k;}}else{}}
}else{}
//we keep the value of the max in order to verify that the same value of the max has another occurence in following steps
maxi=mx;
//e is the double array for the output
e[i][0]=c[mx][0];
e[i][1]=c[mx][1];
int j;
//here we throw away the max from the array
for(j=mx;j< N-i-1;j++){c[j][1]=c[j+1][1];c[j][0]=c[j+1][0];}
}
for(i=0;i<N;i++)
{printf("%d %d",e[N-1-i][0],e[N-1-i][1]);
printf("\n");}
}
Could anyone help ?
Your code has way too high computational complexity. Also, int e[N][2] only works under GCC extension since N is a variable determined at run time instead of compile time.
An easy (in terms of coding) way to improve it is utilizing qsort() in C standard library.
struct IntPair
{
int n[2];
};
int compareIntPair(const void* lhs, const void* rhs)
{
const struct IntPair *l = (const struct IntPair*)lhs;
const struct IntPair *r = (const struct IntPair*)rhs;
if(l->n[1] < r->n[1])
return -1;
if(l->n[1] > r->n[1])
return 1;
if(l->n[0] < r->n[0])
return -1;
if(l->n[0] > r->n[0])
return 1;
return 0;
}
int main(void)
{
//integers used for the loops
int i;
//the size of the 2D array is N*2
int N;
struct IntPair* c;
scanf("%d",&N);
c = (struct IntPair*)calloc(N, sizeof(struct IntPair));
for(i = 0; i < N; ++i)
{
scanf("%d%d", &c[i].n[0], &c[i].n[1]);
}
qsort(c, N, sizeof(struct IntPair), compareIntPair);
for(i = 0; i < N; ++i)
printf("%d %d\n", c[i].n[0], c[i].n[1]);
free(c);
return 0;
}
Edit: to answer the question in comment "could each element of the N-dynamic allocation points to 1D array of size 2?"
int compareElem(const void* lhs, const void* rhs)
{
const int *l = *(const int**)lhs;
const int *r = *(const int**)rhs;
if(l[1] < r[1])
return -1;
if(l[1] > r[1])
return 1;
if(l[0] < r[0])
return -1;
if(l[0] > r[0])
return 1;
return 0;
}
int main(void)
{
//integers used for the loops
int i;
//the size of the 2D array is N*2
int N;
int ** c;
scanf("%d",&N);
c = (int**)calloc(N, sizeof(int*));
for(i = 0; i < N; ++i)
{
c[i] = (int*)calloc(2, sizeof(int));
scanf("%d%d", &c[i][0], &c[i][1]);
}
qsort(c, N, sizeof(int*), compareElem);
for(i = 0; i < N; ++i)
{
printf("%d %d\n", c[i][0], c[i][1]);
free(c[i]);
}
free(c);
return 0;
}

Finding Max Number in an Array C Programming

I am trying to find the max number in an array. I have created a function and I am using the following code:
int maxValue( int myArray [], int size)
{
int i, maxValue;
maxValue=myArray[0];
//find the largest no
for (i=0;i)
{
if (myArray[i]>maxValue)
maxValue=myArray[i];
}
return maxValue;
}
However I get a syntax error before ) token. What am I doing wrong and am I even doing this right? Any help would be greatly appreciated.
You must pass a valid array with at least one member to this function:
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int
maxValue(int myArray[], size_t size) {
/* enforce the contract */
assert(myArray && size);
size_t i;
int maxValue = myArray[0];
for (i = 1; i < size; ++i) {
if ( myArray[i] > maxValue ) {
maxValue = myArray[i];
}
}
return maxValue;
}
int
main(void) {
int i;
int x[] = {1, 2, 3, 4, 5};
int *y = malloc(10 * sizeof(*y));
srand(time(NULL));
for (i = 0; i < 10; ++i) {
y[i] = rand();
}
printf("Max of x is %d\n", maxValue(x, sizeof(x)/sizeof(x[0])));
printf("Max of y is %d\n", maxValue(y, 10));
return 0;
}
By definition, the size of an array cannot be negative. The appropriate variable for array sizes in C is size_t, use it.
Your for loop can start with the second element of the array, because you have already initialized maxValue with the first element.
A for loop has three parts:
for (initializer; should-continue; next-step)
A for loop is equivalent to:
initializer;
while (should-continue)
{
/* body of the for */
next-step;
}
So the correct code is:
for (i = 0; i < size; ++i)
the paren after the for seems to be missing some contents.
normally it should be something like
for (i=0; i<size; i++)
include:
void main()
{
int a[50], size, v, bigv;
printf("\nEnter %d elements in to the array: ");
for (v=0; v<10; v++)
scanf("%d", &a[v]);
bigv = a[0];
for (v=1; v<10; v++)
{
if(bigv < a[v])
bigv = a[v];
}
printf("\nBiggest: %d", bigv);
getch();
}

Resources