Printing only unique elements in an array - c

Edit: I need to maintain the order in which the elements are present in the original array, so sorting won't work.
I have a 1-D array containing some elements and I am using printf() in C but I only want to print an element if and only if it has not already been printed before.
I am thinking of using nested loops to compare if the element I am about to print from the current position in the array was already present in a lower index of the array but it's not working. What am I missing? Or is my whole approach wrong?
So far, I have tried this, which is not working:
int arr[20];
After this I take user input for no. of elements in p and of course, p<20. Then, user enters the elements one by one. I use scanf() for this.
for(i=1;i<=p;i++)
{
for(j=i+1;j<=p;j++)
{
if(arr[i]!=arr[j])
{
printf("%d",arr[j]);
}
}
}

You need to check all previous items before you know if the item has already occurred.
#include <stdio.h>
#include <stdlib.h>
int compareFunc(const void *op1, const void *op2 )
{
int *a, *b;
a = (int*)op1;
b = (int*)op2;
return *a - *b;
}
void printUnique(int *array, int numElems)
{
int curPrintIndex, curCompareIndex;
char alreadySeen;
for (curPrintIndex=0; curPrintIndex<numElems; curPrintIndex++)
{
alreadySeen = 0;
for (curCompareIndex=0; curCompareIndex<curPrintIndex; curCompareIndex++)
{
if (array[curCompareIndex] == array[curPrintIndex])
{
alreadySeen = 1;
break;
}
}
if (alreadySeen == 0)
printf("%d\n", array[curPrintIndex]);
}
}
int main()
{
const int numItems = 100;
int *array, i, lastVal;
array = calloc(numItems, sizeof(int) );
for (i=0; i<numItems; i++)
array[i] = rand()%numItems;
printUnique(array, numItems);
free(array);
return 0;
/*
qsort(array, numItems, sizeof(int), compareFunc);
printf("%d\n", array[0]);
lastVal = array[0];
for (i=1; i<numItems; i++)
{
if (array[i] != lastVal)
{
lastVal = array[i];
printf("%d\n", array[i]);
}
}
*/
}

#include <stdio.h>
int main(void){
int arr[20] = { 4,8,4,2,4,8,1,3,2,7 };//the elements are positive integers.
int i, j, p = 10;
for(i=0;i<p-1;i++){
if(arr[i] < 0)
continue;
for(j=i+1;j<p;j++){
if(arr[j] > 0 && arr[i]==arr[j])
arr[j] *= -1;
}
}
for(i=0; i < p; ++i)
if(arr[i] > 0)
printf("%d ", arr[i]);
puts("");
return 0;
}

Related

Sorting unique vectors in c

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.

I have to arrange the elements in this array from greatest to smallest using 2 methods, but the output is completely different

Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int IndexOfMaxInRange(int ra[], int first, int last)
{
int index = first;
int max = ra[first];
for(int i = first+1; i < last; i++)
{
if(ra[i] > max)
{
index = i;
}
}
return index;
}
void SwapElement(int ra[], int iOne, int iTwo)
{
int temp = ra[iOne];
ra[iTwo] = ra[iOne];
ra[iOne] = temp;
}
void SortArray(int ra[],int length)
{
for(int i = 0; i < length; i++)
{
SwapElement(ra, i, IndexOfMaxInRange(ra, i, (length-1)));
}
}
int main(void)
{
int ra[5] = {2,5,8,3,4};
int length = sizeof (ra) / sizeof (ra[0]);
SortArray(ra, length);
for(int i = 0; i < length; i++)
{
printf("%d ", ra[i]);
}
return(EXIT_SUCCESS);
}
I am supposed to arrange the elements from greatest to smallest, but my output is: "2 5 5 2 4"
I know I am doing something wrong, but I can't put my eye on it, thanks in advance for all the feedback.
First of all, the swap was incorrect, you lost ra[iTwo] in the process. Change to
void SwapElement(int ra[], int iOne, int iTwo)
{
int temp = ra[iOne];
ra[iOne] = ra[iTwo];
ra[iTwo] = temp;
}
Second error is that you are not updating the current max in IndexOfMaxInRange
if(ra[i] > max)
{
max = ra[i];
index = i;
}
Now it should work.

Stack smashing error when manipulating array of ints in function

So I'm trying to make a simple program that takes an array that is partially full and adds an integer to the beginning shifting all existing elements to the right. It seems what I have here adds and shifts things properly but once all the code executes, I get a stack smashing detected error.
Here is my code:
#include <stdio.h>
void addCommand(int *, int, int);
void main() {
int i;
int list[10];
list[0] = 1;
list[1] = 5;
printf("Before add:\n");
for (i = 0; i < 2; i++) {
printf("%d\n", list[i]);
}
addCommand(list, sizeof(list), 4);
printf("Adding 4:\n");
for (i = 0; i < 3; i++) {
printf("%d\n", list[i]);
}
}
void addCommand(int *arr, int size, int new) {
int k;
printf("%d", arr[0]);
for (k = size - 1; k >= 0; k--) {
if (&arr[k] != NULL) {
if (k > 0) {
arr[k] = arr[k-1];
} else {
arr[k] = new;
}
}
}
}
And here's the output:
If anyone could point out what I'm doing wrong here, it would be much appreciated!
addCommand(list, sizeof(list), 4);
above line doesn't pass number of element in list array. you have to do something like this:
sizeof(arr)/sizeof(arr[0])

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;
}

Mergesort An Array of Strings in C

I'm trying to implement a merge sort for an array of strings entered from standard input, and am at a loss at what is wrong. Right now I'm facing a segmentation fault. How should I modify my code?
main() {
char temp;
int i = 0;
char Strings[NUM][LEN];
printf("Please enter %d strings, one per line:\n", NUM);
for (i; i < 25; i++) {
fgets(&Strings[i][0], LEN, stdin);
}
i = 0;
puts("\nHere are the strings in the order you entered:");
for (i; i < 25; i++) {
printf("%s\n", Strings[i]);
}
mergesort(Strings, NUM);
i = 0;
puts("\nHere are the strings in alphabetical order");
for (i; i < 25; i++) {
printf("%s\n", Strings[i]);
}
}
int mergesort(char list[NUM][LEN], int length) { // First part
mergesort_r(0, length, list);
return 0;
}
int mergesort_r(int left, int right, char list[NUM][LEN]) { // Overloaded portion
if (right - left <= 1) {
return 0;
}
int left_start = left;
int left_end = (left + right) / 2;
int right_start = left_end;
int right_end = right;
mergesort_r( left_start, left_end, list);
mergesort_r( right_start, right_end, list);
merge(list, left_start, left_end, right_start, right_end);
}
int merge(char list[NUM][LEN], int left_start, int left_end, int right_start, int right_end) {
int left_length = left_end - left_start;
int right_length = right_end - right_start;
char *left_half[left_length];
char *right_half[right_length];
int r = 0;
int l = 0;
int i = 0;
for (i = left_start; i < left_end; i++, l++) {
strcpy(left_half[l], list[i]);
}
for (i = right_start; i < right_end; i++, r++) {
strcpy(right_half[r], list[i]);
}
for (i = left_start, r = 0, l = 0; l < left_length && r < right_length; i++) {
if (strcmp(left_half[l], right_half[r]) < 0) {
strcpy(list[i], left_half[l++]);
} else {
strcpy(list[i], right_half[r++]);
}
}
for ( ; l < left_length; i++, l++) {
strcpy(list[i], left_half[l]);
}
for ( ; r < right_length; i++, r++) {
strcpy(list[i], right_half[r]);
}
return 0;
}
I'm not sure if it's that I'm passing in my array incorrectly, or maybe it's that I am not even executing swaps properly. I'm at my wits end with this and could use some advice.
should be
char left_half[left_length][LEN];
char right_half[right_length][LEN];
#include<stdio.h>
#include<stdlib.h>
#include<string.h> //To use the string functions like strcmp and strcpy
#define MAX 10 // This is the default size of every string
void Merge(char* arr[],int low,int mid,int high) //Merging the Array Function
{
int nL= mid-low+1;
int nR= high-mid;
char** L=malloc(sizeof(char *)*nL);
char** R=malloc(sizeof(char *)*nR);
int i;
for(i=0;i<nL;i++)
{
L[i]=malloc(sizeof(arr[low+i]));
strcpy(L[i],arr[low+i]);
}
for(i=0;i<nR;i++)
{
R[i]=malloc(sizeof(arr[mid+i+1]));
strcpy(R[i],arr[mid+i+1]);
}
int j=0,k;
i=0;
k=low;
while(i<nL&&j<nR)
{
if(strcmp(L[i],R[j])<0)strcpy(arr[k++],L[i++]);
else strcpy(arr[k++],R[j++]);
}
while(i<nL)strcpy(arr[k++],L[i++]);
while(j<nR)strcpy(arr[k++],R[j++]);
}
void MergeSort(char* arr[],int low,int high) //Main MergeSort function
{
if(low<high)
{
int mid=(low+high)/2;
MergeSort(arr,low,mid);
MergeSort(arr,mid+1,high);
Merge(arr,low,mid,high);
}
}
int main()
{
printf("\nEnter the size of the array desired: ");
int size; //This is the String array size
scanf("%d",&size);
char** arr= malloc(sizeof(char *)* size); //Creating required string array
printf("\nEnter the strings of the array: ");
int i;
for(i=0;i<size;i++)
{
arr[i]=malloc(sizeof(char)*MAX);
printf("\nEnter String: ");
scanf("%s",arr[i]);
}
MergeSort(arr,0,size-1);
printf("\nThe Sorted Array is: ");
for(i=0;i<size;i++)printf("%s ->",arr[i]);
return 0;
}
This is a Working solution to the same problem. Hope it Helps!
Cheers! :)
This solution of yours might give a memory error for long inputs or repeated executions. You need to free the allocated memory or not dynamically allocate it in the first place.
The latter is an easier option. What you can do is find the length of the longest string in the array of strings before hand and pass it as an argument to the merge sort and merge function.
Let's say that length is LEN.
Then instead of dynamically allocating memory for the L and R array, just declare it as:
char L[nL][LEN] and char R[nR][LEN].
It might take a slightly larger stack memory but avoids crashing the program.

Resources