I Made a selection and bubble sort for the array , the selection sort is ok ,but the bubble sort start sorting from the element no (5) of the array and from {0 to 4} no sorting
#include <stdio.h>
#include <stdlib.h>
//// Makeing a swaping Function/////
void swap(int* x,int* y)
{
int temp= *y;
*y= *x;
*x= temp;
}
//// Makeing a sorting Function selection_ sort/////
void selection_sort_elements(int array[],int len)
{
int i,j;
int flag =1;
for (i=0;i<len;i++)
{
printf("Number of Iteration: %d \n",i);
for(j=i+1;j<len;j++)
{
if(array[i]>array[j])
{
swap(&array[i],&array[j]);
}
}
}
}
//// Makeing a sorting Function Bubble sort/////
void bubble_sort_elements(int array[],int len)
{
int i=0,j=0;
//int flag =1;
for (i = 0; i < len ;i++)
{
printf("Number of Iteration: %d \n",i);
//if(flag == 0){
// return;
//}
//flag=0;
for(j = i+1 ; j < len ;j++)
{
if(array[j] < array[j-1])
{
// flag=1;
swap(&array[j],&array[j-1]);
}
}
}
}
int main()
{
int arr[10];
int i=0;
printf("Please Enter A Five Element Of The Array\n");
for (i=0;i<10;i++)
{
scanf("%d",&arr[i]);
}
printf(" You Entered The Array:");
for (i=0;i<10;i++)
{
printf(" %d ", arr[i]);
}
bubble_sort_elements(arr,sizeof(arr)/sizeof(arr[0])); // Calling Sorting Function
printf("\n Now We Sorted Your Array :");
for (i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf(" %d ", arr[i]);
}
//Getting The max Number in the array and its position
printf("\n The MAX Number In The Array IS %d And it location is %d ", arr[(sizeof(arr)/sizeof(arr[0]))-1], sizeof(arr)/sizeof(arr[0])-1);
//Getting The Min Number in the array and its position
printf("\n The Min Number In The Array IS %d And it location is %d ", arr[0], sizeof(arr)/sizeof(arr[0])-sizeof(arr)/sizeof(arr[0]));
return 0;
}
I Made a selection and bubble sort for the array , the selection sort is ok ,but the bubble sort start sorting from the element no (5) of the array and from {0 to 4} no sorting
I uploaded image for the response
Your bubble-sort algorithm is wrong. You either need an ascending sweep with a continuously reduced ceiling, or a descending sweep with a continuously advanced floor. You have an ascending sweep with a continuously advancing floor. Your inner loop should be for (j = 1; j<(len-i); ++j) if you want to keep the ascending sweep, but fix the algorithm to use a continuously reduced ceiling.
void bubble_sort_elements(int array[], size_t len)
{
size_t i = 0, j = 0;
for (i = 0; i < len; i++)
{
printf("Number of Iteration: %zu \n", i);
for (j = 1; j<(len-i); ++j)
{
if (array[j] < array[j - 1])
{
// flag=1;
swap(&array[j], &array[j - 1]);
}
}
}
}
Alternatively, you can forego the i and just continuously reduce len on the outer loop:
void bubble_sort_elements(int array[], size_t len)
{
while (len-- > 0)
{
for (size_t j = 0; j<len; ++j)
{
if (array[j+1] < array[j])
swap(array+j, array+j+1);
}
}
}
Finally, if you want swap detection to short-circuit an already-sorted sequence once it falls into place, the latter algorithm is immediately adaptable to that:
void bubble_sort_elements(int array[], size_t len)
{
int swapped = 1;
while (len-- > 0 && swapped)
{
swapped = 0;
for (size_t j = 0; j<len; ++j)
{
if (array[j+1] < array[j])
{
swap(array+j, array+j+1);
swapped = 1;
}
}
}
}
Related
This C code is for deleting all occurrences of an integer in an array. However, when I executed it, there is a problem with displaying the final array, the code doesn't display the rest of the array once it finds the first occurrence.
unsigned int T[10], n, i, j, exist, integerDeleteOccurences;
printf("Array length : ");
scanf("%u", &n);
for(i=0; i<n; i++)
{
printf("T[%u] : ", i);
scanf("%u", &T[i]);
}
for(i=0; i<n; i++)
{
printf("%u | ", T[i]);
}
printf("The number you want to delete its occurences : ");
scanf("%u", &integerDeleteOccurences);
exist = 0;
for (i=0; i<n; i++)
{
if (T[i] == integerDeleteOccurences)
{
j = i;
for (j=i; j<n-1; j++);
{
T[j] = T[j+1];
}
exist = 1;
i--;
n--;
}
}
if (exist == 1)
{
for (i=0; i<n; i++)
{
printf("%u | ", T[i]);
}
}
else if (exist == 0)
{
printf("This number doesn't exist in the array ! \n");
}
It is far to complicated.
size_t removeFromArray(int *arr, size_t size, int val)
{
int *tail = arr;
size_t newSize = size;
if(arr)
{
while(size--)
{
if(*tail == val) { tail++; newSize--;}
else
*arr++ = *tail++;
}
}
return newSize;
}
When working with statically allocated arrays (i.e. you know the maximum possible size), you should handle them by keeping track of their current size.
Here's a function that delete all occurrencies of an element, given an array and its size, and returns the number of deletions:
int deleteAllOccurrencies(int* arr, int size, int el)
{
int occurrencies = 0;
for (int i = 0; i < size; i++)
{
if (arr[i] == el)
{
occurrencies++;
// shift following elements
for (int j = i; j < size; j++)
{
arr[j] = arr[j + 1];
}
}
}
return occurrencies;
}
Edit with alternative solution (suggested by chqrlie)
The above function loops through an array of integers and for each occurrency found, removes the element from the array and shifts the following values by one position. However, that is not much efficient, since the time complexity of that approach is O(n²).
A better solution would be to loop through the array by using two indexes:
i, which is used to check each value in the starting array, and is increased at the end of each loop;
j, which is used to update only the array elements that are different from the one want to delete, and is increased only when that value is different.
This way we are able to get a much more efficient check, reaching a time complexity of O(n):
int deleteAllOccurrencies(int* arr, int size, int el)
{
int occurrencies = 0;
for (int i = 0, j = 0; i < size; i++)
{
if (arr[i] == el)
{
occurrencies++;
}
else
{
arr[j++] = arr[i];
}
}
return occurrencies;
}
Example Usage
#include <stdio.h>
#define MAX_SIZE 10
int deleteAllOccurrencies(int* arr, int size, int el);
void printArray(int* arr, int size);
int main(int argc, char** argv)
{
int array[MAX_SIZE] = { 1, 2, 3, 4, 2, 6, 7, 8, 2, 10 };
int size = MAX_SIZE, res;
printf("Array: ");
printArray(array, size);
res = deleteAllOccurrencies(array, size, 2);
size = MAX_SIZE - res;
printf("\nResult: %d occurrencies found!\n", res);
printf("Resulting array: ");
printArray(array, size);
return 0;
}
int deleteAllOccurrencies(int* arr, int size, int el)
{
int occurrencies = 0;
for (int i = 0, j = 0; i < size; i++)
{
if (arr[i] == el)
{
occurrencies++;
}
else
{
arr[j++] = arr[i];
}
}
return occurrencies;
}
void printArray(int* arr, int size)
{
printf("[ ");
for (int i = 0; i < size; i++)
{
printf("%d", arr[i]);
if (i < size - 1)
printf(", ");
}
printf("]\n");
}
I am having trouble achieving the wanted results. The program should ask for 20 inputs and then go over each to see if they appear more than once. Then only print out those that appeared once.
However currently my program prints out random numbers that are not inputted.
For example:
array = {10,10,11,12,10,10,10.....,10} should return 11 and 12
#include <stdio.h>
void main() {
int count, size=20, array[size], newArr[size];
int number=0;
for(count = 0; count < size; count++) {
// Ask user for input until 20 correct inputs.
printf("\nAnna %d. luku > ", count+1);
scanf("%d", &number);
if( (number > 100) || (number < 10) ) {
while(1) {
number = 0;
printf("Ei kelpaa.\n");//"Is not valid"
printf("Yrita uudelleen > ");//"Try again >"
scanf("%d", &number);
if ( (number <= 100) && (number >= 10) ) {
break;
}
}
}
array[count] = number;
}
for(int i=0; i < size; i++) {
for(int j=0; j<size; j++){
if(array[i] == array[j]){
size--;
break;
} else {
// if not duplicate add to the new array
newArr[i] == array[j];
}
}
}
// print out all the elements of the new array
for(int k=0; k<size; k++) {
printf("%d\n", newArr[k]);
}
}
You don't need the newArr here, or the separate output loop. Only keep a count that you reset to zero at the beginning of the outer loop, and increase in the inner loop if you find a duplicate.
Once the inner loop is finished, and the counter is 1 then you don't have any duplicates and you print the value.
In code perhaps something like:
for (unsigned i = 0; i < size; ++i)
{
unsigned counter = 0;
for (unsigned j = 0; j < size; ++j)
{
if (array[i] == array[j])
{
++counter;
}
}
if (counter == 1)
{
printf("%d\n", array[i]);
}
}
Note that the above is a pretty naive and brute-force way to deal with it, and that it will not perform very well for larger array sizes.
Then one could implement a hash-table, where the value is the key, and the count is the data.
Each time you read a value you increase the data for that value.
Once done iterate over the map and print all values whose data (counter) is 1.
Use functions!!
Use proper types for indexes (size_t).
void printdistinct(const int *arr, size_t size)
{
int dist;
for(size_t s = 0; s < size; s++)
{
int val = arr[s];
dist = 1;
for(size_t n = 0; n < size; n++)
{
if(s != n)
if(val == arr[n]) {dist = 0; break;}
}
if(dist) printf("%d ", val);
}
printf("\n");
}
int main(void)
{
int test[] = {10,10,11,12,10,10,10,10};
printdistinct(test, sizeof(test)/sizeof(test[0]));
fflush(stdout);
}
https://godbolt.org/z/5bKfdn9Wv
This is how I did it and it should work for your:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdarg.h>
void printdistinct(const int *muis, size_t size);
int main()
{
int loop=20,i,muis[20],monesko=0;
for(i=0; i<loop; i++){
monesko++;
printf ("Anna %d. luku: \n",monesko);
scanf("%d", &muis[i]);
if (muis[i]<10 || muis[i]>100){
printf("Ei kelpaa!\n");
muis[i] = muis[i + 1];
printf("YRITÄ UUDELLEEN:\n ");
scanf("%d", &muis[i]);
}
}
printdistinct(muis, sizeof(muis)/sizeof(muis[0]));
fflush(stdout);
return 0;
}
void printdistinct(const int *muis, size_t size)
{
for(size_t s = 0; s < size; s++)
{
int a = muis[s];
int testi = 1;
for(size_t n = 0; n < size; n++){
if(s != n) {
if(a == muis[n]){
testi = 0;
break;
}
}
}
if(testi) {
printf("%d \n", a);
}
testi = 1;
}
printf("\n");
}
This approach uses some memory to keep track of which elements are duplicates. The memory cost is higher, but the processor time cost is lower. These differences will become significant at higher values of size.
char* duplicate = calloc(size, 1); // values are initialized to zero
for (unsigned i = 0; i < size; ++i)
{
if(!duplicate[i]) // skip any value that's known to be a duplicate
{
for (unsigned j = i + 1; j < size; ++j) // only look at following values
{
if (array[i] == array[j])
{
duplicate[i] = 1;
duplicate[j] = 1; // all duplicates will be marked
}
}
if (!duplicate[i])
{
printf("%d\n", array[i]);
}
}
}
What you can do is you can initialize a hashmap that will help you store the unique elements. Once you start iterating the array you check for that element in the hashmap. If it is not present in the hashmap add it to the hashmap. If it is already present keep iterating.
This way you would not have to iterate the loop twice. Your time complexity of the algorithm will be O(n).
unordered_map < int, int > map;
for (int i = 0; i < size; i++) {
// Check if present in the hashmap
if (map.find(arr[i]) == map.end()) {
// Insert the element in the hash map
map[arr[i]] = arr[i];
cout << arr[i] << " ";
}
}
I just started learning C language and I made this program which prints elements of an array in descending order and then print the 2-digit elements of the same array in descending order. Now I want to print elements of that array except those which contain the digit 5. This is the program I made:
#include<stdio.h>
#include<conio.h>
int main(void)
{
int array[20] = {2,5,1,3,4,10,30,50,40,20,70,90,80,60,100,150,130,110,120,140};
printf("original array:\n");
for(int i=0;i<20;i++)
{
printf("%i\n", array[i]);
}
// To sort elements of array in descending order
int i,j,temp;
for(i=0;i<20;i++)
{
for(j=i+1;j<20;j++)
{
if(array[i]>array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
// Now to print the sorted array
printf("arranged array in descending order:\n");
for(int x = 19;x>=0;x--)
{
printf("%i\n", array[x]);
}
// To print only 2-digit elements of the array
printf("following are only 2-digit elements of array in descending order:\n");
for(int k = 19;k>=0;k--)
{
if(array[k]>9 && array[k]<100)
{
printf("%i\n", array[k]);
}
}
}
What logic should I make so that only elements containing '5' are not printed?
Thanks in advance :)
This function returns 1 if number contains digit d or 0 if not.
int has(int x, int d)
{
while(x)
{
if(abs(x % 10) == d)
{
return 1;
}
x /= 10;
}
return 0;
}
Use functions to better organize your code. First, define a swap() function:
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = *a;
}
Then, write a sorting algorithm. To follow your case:
void bubble_sort(int *array, int size)
{
int i, j, swap_oper;
for (i = 0; i < size - 1; ++i) {
swap_oper = 0;
for (j = 0; j < size - i - 1; ++j) {
if (array[j] > array[j+1]) {
swap(&array[j], &array[j+1]);
swap_oper = 1;
}
}
if (swap_oper == 0)
break;
}
}
To print all numbers except those containing 5, define a function that checks whether a number has 5s in it:
int contains_five(int n)
{
while (n != 0) {
if (n % 10 == 5)
return 1; // true
n /= 10;
}
return 0; // false
}
Then you can use it like this:
void print_array(int *array, int size)
{
int i;
for (i = 0; i < size; ++i) {
if (!contains_five(array[i]))
printf("%d ", array[i]);
}
}
Those are integers stored in binary, so testing for a digit ( base 10 ) is really a matter of how it's displayed.
Try
char str [33];
for(int k = 19;k>=0;k--)
{
//convert to a string first
sprintf(str, "%d", array[k])
//test for presence of ASCII '5'
if(!strstr(str, '5'))
{
printf("%i\n", array[k]);
}
}
I am trying to create a function that will rearrange an array so it is in descending order. The array is made up from positive integers, with no two equal elements. This is what I have:
int check (int *v, int n){
int i;
for (i=0; i<n; i++){
if (v[i] != -1){
return -1;
break;
}
else return 1;
}
}
void sortVector (int *v, int n){
int i, k, j=0, vp[n];
while (check(v,n) == -1){
for (i=0; i<n; i++){
for (k=i+1; k<n; k++){
if (v[k] > v[i]) break;
else if (k == n-1){
vp[j] = v[i];
v[i] = -1;
j++;
}
}
}
}
for (i=0; i<n; i++)
v[i] = vp[i];
}
Which is not working correctly. I've been thinking about this for the past week so some pointers would be great. Thanks.
I tried to follow the idea that you have stated in your comment by starting from your code above and made few changes and here is the two final functions
#include <stdio.h>
int check (int *v, int n)
{
int i;
for (i=0; i<n; i++)
{
if (v[i] != -1)
{
return -1; // break is useless because return has the same effect
}
}
return 1; // you need to add a return here to handle all the cases
// the case if the loop is not entered you need to return a value
}
void sortVector (int *v, int n)
{
int i, k, j=0, vp[n];
int maxIndex=0;//you need to add this variable in order to keep track of the maximum value in each iteration
while (check(v,n) == -1)
{
for (i=0; i<n; i++)
{
maxIndex=i; //you suppose that the maximum is the first element in each loop
for (k=i+1; k<n; k++)
{
if (v[k] > v[maxIndex])
maxIndex=k; // if there is another element greater you preserve its index in the variable
}
//after finishing the loop above you have the greatest variable in the array which has the index stored in maxIndex
vp[i] = v[maxIndex]; // put it in vp array
v[maxIndex]=v[i];//put it in treated elements zone
v[i]=-1;// make it -1
j++;
}
}
for (i=0; i<n; i++)
v[i] = vp[i];
}
This is the test
int main()
{
int tab[]= {1,152,24,11,9};
sortVector (tab, 5);
int i=0;
for(i=0; i<5; i++)
{
printf("%d ",tab[i]);
}
return 0;
}
which gives the desired output
152 24 11 9 1
Note: You can improve your code by making swaps on the same array instead of allocating another array !
There are really lots of algorithms for sorting. A simple algorithm is to find the minimum element in your array and put it in the first position by swapping it with whatever item was in the first position and then recursively sorting the array but this time starting at the next position.
void sort(int a[], int l, int r)
{ if(l == r) return; /* 1-elemnt array is already sorted */
int min = l;
for(int i = l+1; i <= r; i++)
{ if(a[i] < a[min])
{ min = i;
}
}
swap(a[l], a[min]);
sort(a, l+1, r);
}
You can also do it iteratively.
Perhaps, the intention like following
int check (int *v, int n){
int i;
for (i=0; i<n; i++){
if (v[i] != -1){
return -1;
//break; //This code that does not reach
}
//else return 1; //move to after for-loop
}
return 1;
}
void ordenaVetor (int *v, int n){
int i, k, j=0, vp[n];
while (check(v,n) == -1){
for (i=0; i<n; i++){
if(v[i]<0) continue;//Element of -1 excluded. v[k] too.
for (k=i+1; k<n; k++){
if (v[k]>=0 && v[i] < v[k]) break;
}
if (k == n){
vp[j] = v[i];
v[i] = -1;
j++;
break;//start over
}
}
}
for (i=0; i<n; i++){
v[i] = vp[i];
}
}
You could use an existing sort implementation instead of reinventing the wheel:
#include <stdlib.h>
int desc(void const *a, void const *b)
{
if ( *(int *)a < *(int *)b ) return 1;
return -1;
}
void sortVector (int *v, int n)
{
qsort(v, n, sizeof *v, desc);
}
My code for selection-sort
#include <stdio.h>
void selection_sort(int a[], int n);
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be sorted: ",size);
while(i++ < size)
scanf("%d",&b[i]);
selection_sort(b, size);
printf("Sorted integers(by selection sort) are: ");
for(int i = 0; i < size; i++)
printf("%d",b[i]);
return 0;
}
void selection_sort(int a[], int n)
{
while(n >= 0 )
{
if(n == 0)
break;
else
{
int i = 0, c = 0;
int largest = a[0];
while(i++ < n)
if(largest < a[i])
{
c = i ;
largest = a[i];
}
int temp = a[--n];
a[n] = largest;
a[c] = temp;
selection_sort(a, n);
}
}
}
on sorting the array in ascending order
3 4 1 2
is giving weird output
2293388 4 3 0
I checked this many time but failed to remove the problem.
What should I do to work it properly?
Algorithm used :
1. search for largest element in the array.
2. Move largest element to the last position of array.
3. Call itself recursively to sort the first n -1 element of the array.
Please don't give any other solution otherwise I will get confused.
EDIT
Ah, I see what goes wrong. First of all, while (i++ < n) does not do exactly what you expect it to do. It checks if the condition i < n is true, then it increments i. However, it seems that after the conditional check, i is already incremented in the body. So for example,
while (i++ < n)
printf ("%d ", i);
will print out (with n=4):
1 2 3 4
So you first need to change that. Secondly, the outer while-loop is not at all necessary. Using one loop will suffice. Again, change the while loop in here to while (i < n) and increment i in the body. SO the final code will be:
#include <stdio.h>
void selection_sort(int a[], int n);
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d", &size);
int b[size], i = 0;
printf("Enter %d integers to be sorted: ", size);
while(i < size) {
scanf("%d", &b[i]);
i++;
}
selection_sort(b, size);
printf("Sorted integers(by selection sort) are: ");
i = 0;
for(i = 0; i < size; i++)
printf("%d ", b[i]);
printf ("\n");
return 0;
}
void selection_sort(int a[], int n)
{
if(n == 0)
return;
else
{
int i = 0, c = 0;
int largest = a[0];
while(i < n) {
if(largest < a[i])
{
c = i;
largest = a[i];
}
i++;
}
int temp = a[--n];
a[n] = a[c];
a[c] = temp;
selection_sort(a, n);
}
}
I tested this with your given input (3 4 1 2) and it prints out a sorted list: 1 2 3 4.
Whenever you see such weird big numbers, its usually an array out of bounds issue. Please take a small data-set, say 5-6 numbers, and walk through your program. I am sure you can fix it. Good luck!!