The program should eliminate any repeating digits and sort the remaining ones in ascending order. I know how to print unique digits but I donĀ“t know how to create a new vector from them that i can later sort.
#include <stdio.h>
void unique(double arr[], int n) {
int i, j, k;
int ctr = 0;
for (i = 0; i < n; i++) {
printf("element - %d : ",i);
scanf("%lf", &arr[i]);
}
for (i = 0; i < n; i++) {
ctr = 0;
for (j = 0, k = n; j < k + 1; j++) {
if (i != j) {
if (arr[i] == arr[j]) {
ctr++;
}
}
}
if (ctr == 0) {
printf("%f ",arr[i]);
}
}
}
int main() {
double arr[100];
int n;
printf("Input the number of elements to be stored in the array: ");
scanf("%d", &n);
unique(arr, n);
}
You can always break a larger problem down into smaller parts.
First create a function that checks if a value already exists in an array.
Then create a function that fills your array with values. Check if the value is in the array before adding it. If it is, you skip it.
Then create a function that sorts an array. Alternatively, qsort is a library function commonly used to sort arrays.
This is far from efficient, but should be fairly easy to understand:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NUMS 256
int find(double *arr, size_t length, double val)
{
for (size_t i = 0; i < length; i++)
if (val == arr[i])
return 1;
return 0;
}
size_t fill_with_uniques(double *arr, size_t limit)
{
size_t n = 0;
size_t len = 0;
while (n < limit) {
double value;
printf("Enter value #%zu: ", n + 1);
if (1 != scanf("%lf", &value))
exit(EXIT_FAILURE);
/* if value is not already in the array, add it */
if (!find(arr, len, value))
arr[len++] = value;
n++;
}
return len;
}
int compare(const void *va, const void *vb)
{
double a = *(const double *) va;
double b = *(const double *) vb;
return (a > b) - (a < b);
}
int main(void)
{
double array[MAX_NUMS];
size_t count;
printf("Input the number of elements to be stored in the array: ");
if (1 != scanf("%zu", &count))
exit(EXIT_FAILURE);
if (count > MAX_NUMS)
count = MAX_NUMS;
size_t length = fill_with_uniques(array, count);
/* sort the array */
qsort(array, length, sizeof *array, compare);
/* print the array */
printf("[ ");
for (size_t i = 0; i < length; i++)
printf("%.1f ", array[i]);
printf("]\n");
}
Above we read values from stdin. Alternatively, fill_with_uniques could take two arrays, a source and a destination, and copy values from the former into the latter, only when they would be unique.
Remember to never ignore the return value of scanf, which is the number of successful conversions that occurred (in other words, variables assigned values). Otherwise, if the user enters something unexpected, your program may operate on indeterminate values.
Related
So I'm very new to programming and the C language, and I would like to find the simplest, fastest, and most efficient way to count all the distinct elements of a 1D array. This was actually for a school assignment, but I've been stuck on this problem for days, since my program was apparently too slow for the online judge and it got a TLE. I've used regular arrays and dynamically allocated arrays using malloc, but neither worked.
Anyways, here's the latest code of it(using malloc):
#include <stdio.h>
#include <stdlib.h>
int distinct(int *arr, int N){
int j, k, count = 1;
for(j = 1; j < N; j++){
for(k = 0; k < j; k++){
if(arr[j] == arr[k]){
break;
}
}
if(j == k){
count++;
}
}
return count;
}
int main(){
int T, N, i = 0;
scanf("%d", &T);
do{
scanf("%d", &N);
int *arr;
arr = (int*)malloc(N * sizeof(int));
for(int j = 0; j < N; j++){
scanf("%d", &arr[j]);
}
int count = distinct(arr, N);
printf("Case #%d: %d\n", i + 1, count);
i++;
}while(i < T);
return 0;
}
The most efficient way depends on too many unknown factors. One way is to sort the array and then to count distinct elements in there, skipping the duplicates as you go. If you have sorted the array and gotten this:
1 1 1 1 2 2 2 2 3 3
^ ^ ^
+-skip--+-skip--+-- end
... you can easily see that there are 3 distinct values in there.
If you don't have a favourite sorting algorithm handy, you could use the built-in qsort function:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
Example:
#include <stdio.h>
#include <stdlib.h>
int compar(const void *l, const void *r) {
const int* lhs = l;
const int* rhs = r;
if(*lhs < *rhs) return -1; // left side is less than right side: -1
if(*lhs > *rhs) return 1; // left side is greater than right side: 1
return 0; // they are equal: 0
}
int distinct(int arr[], int N){
// sort the numbers
qsort(arr, N, sizeof *arr, compar);
int count = 0;
for(int i=0; i < N; ++count) {
int curr = arr[i];
// skip all numbers equal to curr as shown in the graph above:
for(++i; i < N; ++i) {
if(arr[i] != curr) break;
}
}
return count;
}
int main() {
int T, N, i = 0;
if(scanf("%d", &T) != 1) return 1; // check for errors
while(T-- > 0) {
if(scanf("%d", &N) != 1) return 1;
int *arr = malloc(N * sizeof *arr);
if(arr == NULL) return 1; // check for errors
for(int j = 0; j < N; j++){
if(scanf("%d", &arr[j]) != 1) return 1;
}
int count = distinct(arr, N);
free(arr); // free after use
printf("Case #%d: %d\n", ++i, count);
}
}
I'm trying to write a program that sorts an array of size N via a selections sort and then conducts a binary search for a random number in that array and displays the index in which that number is present. I noticed that without my binary search function I begin to get a stack overflow when N is greater than 1e5 and when I try to run the binary search I run into the error "read access violation". I would greatly appreciate any help on this especially considering my N is supposed to be 1e6.
#define N 10
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//function prototypes
void selectionSort(int array[], size_t length);
void swap(int* elementPtr, int* element2Ptr);
void printPass(int array[], size_t length, unsigned int pass, size_t index);
size_t binarySearch(const int b[], int searchKey, size_t low, size_t high);
unsigned long long int counter = 0;
unsigned long long int counter2 = 0;
long long unsigned int counter3 = 0;
int main(void) {
int array[N];
srand(time(NULL));
for (size_t i = 0; i < N; i++) {
array[i] = rand() % 90 + 10; // give each element a value
}
/*
puts("Unsorted array:");
for (size_t i = 0; i < N; i++) { //print the array
printf("%d ", array[i]);
}
puts("{\n");
*/
selectionSort(array, N);
/*
puts("Sorted array:");
for (size_t i = 0; i < N; i++) { //print the array
printf("%d ", array[i]);
}
*/
printf("\nTotal amount of comparisons: %d\n", counter);
printf("Total amount of swaps: %d", counter2);
int value = rand() % N + 1;
int index = binarySearch(array, value, 0, N);
printf("\nThe amount of times the value was compared was: %d\n", counter3);
if (index != -1) {
printf("%d was first found on index %d\n", value, index);
}
else printf("%d was not found on the array\n", value);
}
void selectionSort(int array[], size_t length) {
//loop over length - 1 elements
for (size_t i = 0; i < length - 1; i++) {
size_t smallest = i; //first index of remaining array
//loop to find index of smallest element
for (size_t j = i + 1; j < length; j++) {
counter++;
if (array[j] < array[smallest]) {
smallest = j;
}
}
swap(array + i, array + smallest); //swap smallest element
//printPass(array, length, i + 1, smallest); //output pass
}
}
//function that swaps two elements in the array
void swap(int* elementPtr,int* element2Ptr)
{
counter2++;
int temp;
temp = *elementPtr;
*elementPtr = *element2Ptr;
*element2Ptr = temp;
}
//function that prints a pass of the algorithm
void printPass(int array[], size_t length, unsigned int pass, size_t index) {
printf("After pass %2d: ", pass);
//output elements till selected item
for (size_t i = 0; i < index; i++) {
printf("%d ", array[i]);
}
printf("%d ", array[index]); //indicate swap
//finish outputting array
for (size_t i = index + 1; i < length; i++) {
printf("%d ", array[i]);
}
printf("%s", "\n "); //for alignment
//indicate amount of array that is sorted
for (unsigned int i = 0; i < pass; i++) {
printf("%s", "-- ");
}
puts(""); //add newline
}
size_t binarySearch(const int b[], int searchKey, size_t low, size_t high) {
counter3++;
if (low > high) {
return -1;
}
size_t middle = (low + high) / 2;
if (searchKey == b[middle]) {
return middle;
}
else if (searchKey < b[middle]) {
return binarySearch(b, searchKey, low, middle - 1);
}
else {
return binarySearch(b, searchKey, middle + 1, high);
}
}
For N as big as 1e5 or 1e6, you can't afford allocating it on stack. The size of an int is 4 bytes and so you'll consume 4e5 bytes from stack just for your array.
You will need to dynamically allocate the array and instead of
int array[N];
you should have
int *array = malloc(sizeof(int) * N);
and after you are done with everything, don't forget to
free(array);
Now you should have enough space on stack for the recursive binary search.
UPDATE:
After I've run the code myself, indeed, the binarySearch function always yields segmentation fault. The problem is the type of the parameters, namely size_t. There are cases where high argument from the binarySearch function becomes -1. But because the size_t is an unsigned type, you have an integer underflow, thus high will become maxint. So your condition if (low > high) would never become true. You'll have to change the types of low and high to a signed integer to have the function working.
Still, I suggest going for the dynamic allocation, even though your stack might cope with that.
Even outside of the great answer that was posted, I am seeing other problems with this code. I have issues running it with N = 2, N =5, and N = 10.
I believe you have some problems with passing the variables into your binary search function. I think that you are passing incorrect values that are overflowing and causing all sorts of memory nightmares. This is causing your read access violations.
Do your small cases function appropriately? Despite the suggestions to minimize your footprint. I would double check simple cases are functioning.
So the problem here was to write a program that uses pointers to point to functions and write it in such a way that it collects 10 doubles, gives feedback to the user of the program, sorts them and print the sorted results as proof. The problem is, the program either prints the printf statement in the beginning infinitely, or collects numbers infinitely.
Here is some code
#include <stdio.h>
void func1(double x);
void below_five(void);
void above_five(void);
void other(void);
void sort(double *p[], int n);
void print_doubles(double *p[], int n);
int main(void){
double *numbers[9];
int nbr;
printf("\nEnter 10 doubles that are less than 5 or greater than 5, type 0 to exit");
for(int i = 0; i < 10 ; i++)
{
scanf("%d", &nbr);
func1(nbr);
numbers[i] = nbr;
if(nbr == 0)
break;
}
sort(numbers, 10);
print_doubles(numbers, 10);
return 0;
}
void func1(double val)
{
double (*ptr)(void);
if(val <= 5.00){
ptr = below_five;
}else if((val > 5.00) && (val <= 10.00)){
ptr = above_five;
}else
ptr = other;
}
void below_five(void){
puts("You entered a number below or equal to five");
}
void above_five(void){
puts("You entered a number above five");
}
void other(void){
puts("You entered a number well above five.");
}
void sort(double *p[], int n)
{
double *tmp;
for(int i = 0; i < n; i++)
{
if(p[i] > p[i+1]){
tmp = p[i];
p[i] = p[i+1];
p[i + 1] = tmp;
}
}
}
void print_doubles(double *p[], int n)
{
int count;
for(count = 0; count < n; count++)
printf("%d\n", p[count]);
}
Like I said, what I expect it to be able to do is collect doubles into the scanf method and then print the numbers after sorting them, but it seems the for loop collects doubles forever without end in this case.
What have I done wrong, exactly?
See my comments in your updated code.
There are other modifications required, but the minimum updates needed to work your code is below
#include <stdio.h>
void func1(double x);
void below_five(void);
void above_five(void);
void other(void);
void sort(double p[], int n); /* Simply use a array notation,
arrays passed to functions decays to pointer */
void print_doubles(double p[], int n); /* Simply use a array notation,
arrays passed to functions decays to pointer */
int main(void){
double numbers[10];
double nbr; // Change type to double, as you're reading doubles
printf("\nEnter 10 doubles that are less than
5 or greater than 5, type 0 to exit\n");
for(int i = 0; i < 10 ; i++)
{
scanf("%lf", &nbr); // Use correct format specifier to read doubles
func1(nbr);
numbers[i] = nbr;
if(nbr == 0)
break;
}
sort(numbers, 10);
print_doubles(numbers, 10);
return 0;
}
void func1(double val)
{
double (*ptr)(void);
if(val <= 5.00){
ptr = below_five;
}else if((val > 5.00) && (val <= 10.00)){
ptr = above_five;
}else
ptr = other;
/* Why you set the pointer to function if you don't call it,
so call it here*/
(*ptr)();
}
void below_five(void){
puts("You entered a number below or equal to five");
}
void above_five(void){
puts("You entered a number above five");
}
void other(void){
puts("You entered a number well above five.");
}
void sort(double p[], int n) /* Your sorting routine is wrong ,
see the modified code */
{
double tmp;
for(int j = 0; j < n-1; j++)
for(int i = 0; i < n-j-1; i++)
{
if(p[i] > p[i+1]){
tmp = p[i];
p[i] = p[i+1];
p[i + 1] = tmp;
}
}
}
void print_doubles(double p[], int n)
{
int count;
for(count = 0; count < n; count++)
printf("%lf\n", p[count]); // Use correct format specifier
}
Demo Here
Ok I need to write two functions iterative and recursive to count negative elements in an array and then I need to build main. I was only able to write the recursive function but I cannot call it from main, it is an error somewhere. Can someone help me out solve it and help me with the iterative method?
#include <stdio.h>
main()
{
int vektor[100];
int i, madhesia;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
/* Input array elements */
printf("Elementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
int ret = numero(vektor, madhesia);
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(array, size)
{
int count = 0;
for (int j = 0; j < size; j++)
{
if (array[j] < 0)
{
count++;
}
}
return count;
}
A working piece of code is this.You really need to take a look at pointers and the way they work.
Here you can see that I have a pointer ->pointing-< at the start of the array , so by passing the starting address of the array , and the length of the array , your functions knows what it is needed to be done.
#include <stdio.h>
int numero(int* array, int size);
int* recursive_count(int* array, int size , int* counter );
int main()
{
int vektor[100];
int* vekt_ptr = &vektor[0];
int i, madhesia;
int counter;
counter=0;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
/* Input array elements */
printf("Elementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
//int ret = numero(vekt_ptr, madhesia);
recursive_count(vekt_ptr, madhesia , &counter );
int ret = counter;
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(int* array, int size)
{
int count = 0;
int j;
for (j = 0; j < size; j++)
{
if (array[j] < 0)
{
count++;
}
}
return count;
}
int* recursive_count(int* array, int size , int* counter )
{
size--;
if(array[size] < 0 )
{
(*counter)++;
}
if(size==0)
{
return NULL;
}
return recursive_count(array++, size , counter );
}
Let's assume that you want to create dynamically an array of X length.
The compiler is going to have some memory for your array , depending on the length.
You initialize your array , lets say [2][45][1][-5][99]
When you call the function you have to pass where this is stored in memory.
int* vekt_ptr = &vektor[0]; -s going to give as something like 0x56c2e0.
This number is the address of your array , which is the address of the starting point of the array.This is equal with the address of first byte.
So when your function starts , it knows where your array starts and how long it is.
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
Any function used in a program shall be declared before its usage.
This function declaration of the function definition
int numero(array, size)
{
// ...
}
is invalid because the types of the parameters array and size are undefined.
For the size of an array and for the count of elements it is better to use an unsigned integer type like for example size_t or at least unsigned int.
The program can look the following way
#include <stdio.h>
#define N 100
size_t iterative_numero( const int array[], size_t size );
size_t recursive_numero( const int array[], size_t size );
int main( void )
{
int vektor[N];
size_t madhesia = 0;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%zu", &madhesia);
if ( N < madhesia ) madhesia = N;
/* Input array elements */
printf("Elementet: ");
for ( size_t i = 0; i < madhesia; i++ )
{
scanf( "%d", &vektor[i] );
}
size_t ret = iterative_numero(vektor, madhesia );
printf("\nTotal negative elements in array = %zu\n", ret);
ret = recursive_numero(vektor, madhesia );
printf("Total negative elements in array = %zu\n", ret);
return 0;
}
size_t iterative_numero( const int array[], size_t size )
{
size_t count = 0;
for ( size_t i = 0; i < size; i++)
{
if ( array[i] < 0 )
{
count++;
}
}
return count;
}
size_t recursive_numero( const int array[], size_t size )
{
return size == 0 ? 0 : ( array[0] < 0 ) + recursive_numero( array + 1, size - 1 );
}
the program output might look like
Madhesia e vektorit: 10
Elementet: 0 -1 2 -3 4 -5 6 -7 8 -9
Total negative elements in array = 5
Total negative elements in array = 5
First of all what you did is the iterative method, not recursive. Here I have called a recursive function from the main function.
#include <stdio.h>
int main()
{
int vektor[100];
int i, madhesia;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
/* Input array elements */
printf("\nElementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
printf("\nno of elements:%d",madhesia);
printf("\n");
for (i = 0; i < madhesia; i++)
{
printf("%d", vektor[i]);
}
printf("\n");
i=0;
int ret = numero(vektor,madhesia,0,i);
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(int array[],int size,int count,int j)
{
if (j<=size-1)
{
if(array[j]<0)
{
count++;
j++;
numero(array,size,count,j);
}
else
{
j++;
numero(array,size,count,j);
}
}
return count;
}
Put function prototype of numero() before main() to be able to call it. Declare function parameters with type:
int numero(int array[], int size);
int main() {
...
#include<stdio.h>
int numero(int *, int); //Function Prototype (1)
int main() //Return Type (2)
{
int vektor[100];
int i, madhesia;
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
printf("Elementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
int ret = numero(vektor, madhesia);
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(int* array,int size) //Parameters Data Type (3)
{
int count = 0;
for (int j = 0; j < size; j++)
{
if (array[j] < 0)
{
count++;
}
}
return count;
}
Errors:
You have declared the function after "main()" so the program doesn't know that there is a function, so you have to give the function prototype before "main()" so that the program knows there is function ahead.
You missed writing the return type of "main()" which is integer.
In the function declaration you forgot to write the data type of the parameters.
NOTE: The array is always passed by reference so it has to taken in an integer pointer instead of a normal integer.
Some possible implementations:
int iterativeCountNegativeIntegers (int *array, int size)
{
int result = 0;
for (int i = 0; i < size; ++ i)
if (array[i] < 0)
result += 1;
return result;
}
int recursiveCountNegativeIntegers (int *array, int size)
{
if (size == 0)
return 0;
int partial = *array < 0;
return partial + recursiveCountNegativeIntegers(array+1, size-1);
}
The same, condensed:
int iterativeCountNegativeIntegers_1 (int *array, int size)
{
int result = 0;
while (--size >= 0)
result += *array++ < 0;
return result;
}
int recursiveCountNegativeIntegers_1 (int *array, int size)
{
return (size == 0) ? 0
: (*array < 0) + recursiveCountNegativeIntegers_1(array+1, size-1);
}
I have a function that takes array 1 and copies/manipulates it to array 2. Basically what it does is take the user input in array one, lets say (2, 3, 3) and array 2 is stored as (2, 0, 3, 0, 3). I know this works because it worked without implementing a function but sadly I have to have one. I cannot for the life of me figure out how to call the function, I believe I don't need a return since its a void and not returning a value. Below is my code any help would be appreciated.
#include <stdio.h>
void insert0(int n, int a1[], int a2[]);
int main() {
int i = 0;
int n = 0;
int a1[n];
int a2[2*n];
printf("Enter the length of the array: ");
scanf("%d",&n);
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&a1[i]);
}
insert0(); //call function which is wrong and I cannot get anything to work
for( i = 0; i < n*2; i++){ //prints array 2
printf("%d", a2[i]);
}
void insert0 (int n, int a1[], int a2[]){ //inserts 0's between each number
for(i = 0; i < n; i++){
a2[i+i] = a1[i];
a2[i+i+1] = 0;
}
}
}
Modifying n after declaraing a1 and a2 won't magically increase their size. Declare a1 and a2 after reading the size into n to use variable-length arrays.
You must pass proper arguments to call insert0.
Defining functions inside functions is GCC extension and you shouldn't do that unless it is required.
a2 should have n*2 - 1 elements, not n*2 elements.
After moving it out of main(), i is not declared in insert0, so you have to declare it.
You should check if readings are successful.
Corrected code:
#include <stdio.h>
void insert0(int n, int a1[], int a2[]);
int main() {
int i = 0;
int n = 0;
printf("Enter the length of the array: ");
if(scanf("%d", &n) != 1){
puts("read error for n");
return 1;
}
if(n <= 0){
puts("invalid input");
return 1;
}
int a1[n];
int a2[2*n-1];
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
if(scanf("%d", &a1[i]) != 1){
printf("read error for a1[%d]\n", i);
return 1;
}
}
insert0(n, a1, a2);
for( i = 0; i < n*2-1; i++){ //prints array 2
printf("%d", a2[i]);
}
}
void insert0 (int n, int a1[], int a2[]){ //inserts 0's between each number
int i;
for(i = 0; i < n; i++){
a2[i+i] = a1[i];
if (i+1 < n){ // don't put 0 after the last element
a2[i+i+1] = 0;
}
}
}