Deleting Duplicates in array and replacing them with unused values - c

My objective for this program is to let the user determine the size of the array and dynamically allocate memory for whatever size they choose. Once the user defines the size of the array, random numbers that do no exceed the size of the array are placed into all of the allotted positions. Where I am having issues is removing duplicates from the array and replacing them with a value that is not being used,
Example:
Please enter the size of the array:
User Input: 5
Output of code: 5, 3, 3, 1, 2
I would need it to be something like this:
Please enter the size of the array:
User Input: 3
Output of program: 3, 1, 2
Currently reading "C Programming - A Modern Approach" by K.N. King (Second Edition).
if someone could point me in the right direction on how to approach this, it would be much appreciated.Here is my code thus far.
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef int bool;
int main() {
int *UserData;
int TempPost;
int replace;
int UserInput;
int i;
int result;
bool digit_seen[UserInput];
int digit;
srand ((unsigned) time(NULL));
printf("Please enter the size of the array using a whole number: \n");
scanf("%d", &UserInput);
UserData = malloc(sizeof(int) * (UserInput ) +1);
for(i=0; i < UserInput; i ++) {
result = (( rand() % UserInput) + 1);
}
// check for duplicate values while putting values in array
while(UserInput>0){
digit = UserInput % UserInput;
if(digit_seen[digit])
break;
digit_seen[digit] = true;
UserInput /= UserInput;
if(UserInput > 0)
printf("Repeated digit \n");
else
printf("No repeated digit \n");
}
// Sorting the array using a Bubble sort
while(1){
replace = 0;
for (i=0; i<(UserInput - 1); i++){
if(UserData[i]>UserData[i+1]){
TempPost = UserData[i];
UserData[i] = UserData[i+1];
UserData[i+1] = TempPost;
replace = 1;
}
}
if(replace==0){
break;
}
}
printf("%d \n", result);
return 0;
}

It's not the most efficient way, but you can do it as you're generating the random numbers. When you pick a random number, go through all the previous elements of the array and see if it's already been used. Keep looping until you pick an unused number.
for (i = 0; i < UserInput; i++) {
do {
result = ( rand() % UserInput) + 1;
} while (in_array(result, UserData, i-1));
UserData[i] = result;
}
int in_array(int val, int* array, int array_size) {
for (int i = 0; i < array_size; i++) {
if (array[i] == val) {
return 1;
}
}
return 0;
}
A slightly more efficient way to do it is to initialize the array to 0. Then instead of picking random numbers, pick a random index to fill in, and repeat this until you pick an index that contains 0.
UserData = calloc(UserInput, sizeof(int));
for (i = 1; i <= UserInput; i++) {
int index;
do {
index = rand() % UserInput;
} while (UserData[index] != 0)
UserData[index] = i;
}

What you can do is shuffle the array instead. Just fill the array with all the numbers in order using a simple for loop, then shuffle it with something like this:
//read user input
//create array and fill with all the numbers in order
//[0,1,2,3,4,5 .. ... ]
int index, temp;
// size is the size of the array
for(int i = 0; i < size; i++)
{
index = rand()%size;//random place to pick from
temp = array[i];
array[i] = array[index];
array[index] = temp;
}
This is a lot more effecient -and less error prone- than your current approach.

Related

The wrong data is displayed in the output on c

Taking a sequence of (non-empty) integers the program should first request the number of integers to read and dynamically allocate an array large enough to hold the number of values you read. You should then loop in the elements of the array. Then, your program must use malloc() to dynamically allocate two arrays, one to hold all the even numbers in the array you just read, and one to hold the odd numbers in the array. You must allocate just enough space for each array to hold odd and even numbers.
That is my test case
Please enter the number of times you want to enter the temperature:
4
Please enter the numbers:
21
40
31
50
odds are: 21
odds are: 0
evens are: 0
evens are: 40
This is my code:
#include <stdio.h>
#include<stdlib.h> // for malloc
int main(void) {
int counts = 0; // set a variable named counts recored how many of the times
printf("Please enter the number of times you want to enter the temperature: \n");
scanf("%d",&counts);
int *odd_evens;
odd_evens = malloc(sizeof(int)*(counts));
printf("Please enter the numberss: \n");
for (int i = 0; i < counts; i++) { // use for loop to read temperature
scanf("%d",&odd_evens[i]); // record the temperature
}
int odds_number = 0; // calcuate how many numbers are odds
int evens_number = 0; // calcuate how many numbers are evens
for (int i = 0; i < counts; i++) {
if (odd_evens[i] %2 == 0) {
odds_number++; // odds add one
}
else if (odd_evens[i] %2 != 0) {
evens_number++; // evens add one
}
}
int *odds;
odds = malloc(sizeof(int)*(odds_number)); // create dunamic array for odds
int *evens;
evens = malloc(sizeof(int)*(evens_number)); // create dunamic array for evens
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[j] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[j] = odd_evens[j];
}
}
for(int m = 0; m < odds_number; m++) {
printf("odds are: %d\n",odds[m]);
}
for (int n = 0; n < odds_number; n++) {
printf("evens are: %d\n",evens[n]);
}
free(odd_evens);
free(odds);
free(evens);
return 0;
}
In my limited coding experience, this usually happens with invalid subscripts, but in my test code, the odd numbers are of length 2 and the even numbers are of length 2. The array range should be correct. Why does this happen?
One major problem is this loop:
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[j] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[j] = odd_evens[j];
}
}
Here you will go out of bounds of both evens and odds (leading to undefined behavior) since you use the index for odd_evens which most likely will be larger (unless all input is only odd, or only even).
You need to keep separate indexes for evens and odds:
unsigned evens_index = 0;
unsigned odds_index = 0;
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[evens_index++] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[odds_index++] = odd_evens[j];
}
}
Another problem is the printing of the even numbers:
for (int n = 0; n < odds_number; n++) {
printf("evens are: %d\n",evens[n]);
}
Here you use the odds_number size instead of evens_number.

C program to find integer closest to 10

I am writing a program that will take any number of integers. The program will end when the terminal 0 has been entered. It will then output the number closest to 10 (except for the terminal character). If there are several numbers closest to 10 then it should output the last number entered.
My current code does read the numbers from the input stream, but I don't know how to implement the logic so that the program will give me the number that is closest to 10.
I know, that I need to keep track of the minimum somehow in order to update the final result.
#include <stdio.h>
int main() {
int n = 1;
int number = 1;
int numberArray[n];
int resultArray[n];
int min;
int absMin;
int result;
int finalResult;
while (number != 0) {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
for (int i = 0; i < n; i++) {
min = 10 - numberArray[i];
if (min < 0) {
absMin = -min;
}
else {
absMin = min;
}
resultArray[i] = absMin;
result = resultArray[0];
if (resultArray[i] < result) {
finalResult = resultArray[i];
}
}
printf("%d\n", finalResult);
return 0;
}
here's a simple code I wrote
One thing I must say is you can't simply declare an array with unknown size and that's what you have done. Even if the no. of elements can vary, you either take input the number of elements from the user OR (like below) create an array of 100 elements or something else according to your need.
#include <stdio.h>
#define _CRT_NO_WARNINGS
int main() {
int n = 0;
int number = 1;
int numberArray[100];
int resultArray[100];
int minNumber;
int *min;
do {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
while (number != 0);
resultArray[0] = 0;
min = &resultArray[0];
minNumber = numberArray[0];
for (int i = 0; i < n-1; i++) {
if(numberArray[i]>=10){
resultArray[i] = numberArray[i] - 10;
}
if(numberArray[i]<10){
resultArray[i] = 10 - numberArray[i];
}
if(resultArray[i] <= *min){
min = &resultArray[i];
minNumber = numberArray[i];
}
}
printf("\n%d",minNumber);
return 0;
}
I have improved your script and fixed a few issues:
#include <stdio.h>
#include <math.h>
#include <limits.h>
int main()
{
int n;
int number;
int numberArray[n];
while (scanf("%d", &number) && number != 0) {
numberArray[n++] = number;
}
int currentNumber;
int distance;
int result;
int resultIndex;
int min = INT_MAX; // +2147483647
for (int i = 0; i < n; i++) {
currentNumber = numberArray[i];
distance = fabs(10 - currentNumber);
printf("i: %d, number: %d, distance: %d\n", i, currentNumber, distance);
// the operator: '<=' will make sure that it will update even if we already have 10 as result
if (distance <= min) {
min = distance;
result = currentNumber;
resultIndex = i;
}
}
printf("The number that is closest to 10 is: %d. It is the digit nr: %d digit read from the input stream.\n", result, resultIndex + 1);
return 0;
}
Reading from the input stream:
We can use scanf inside the while loop to make it more compact. Also, it will loop one time fewer because we don't start with number = 1 which is just a placeholder - this is not the input - we don't want to loop over that step.
I used the shorthand notation n++ it is the post-increment-operator. The operator will increase the variable by one, once the statement is executed (numberArray entry will be set to number, n will be increased afterwards). It does the same, in this context, as writing n++ on a new line.
Variables:
We don't need that many. The interesting numbers are the result and the current minimum. Of course, we need an array with the inputs as well. That is pretty much all we need - the rest are just helper variables.
Iteration over the input stream:
To get the result, we can calculate the absolute distance from 10 for each entry. We then check if the distance is less than the current minimum. If it is smaller (closer to 10), then we will update the minimum, the distance will be the new minimum and I have added the resultIndex as well (to see which input is the best). The operator <= will make sure to pick the latter one if we have more than one number that has the same distance.
I have started with the minimum at the upper bound of the integer range. So this is the furthest the number can be away from the result (we only look at the absolute number value anyway so signed number don't matter).
That's pretty much it.

How to see if numbers have same digits in array?

I'm a bit stuck on one of my problems not because I don't know, but because I can't use more complex operations.(functions and multiple arrays)
So I need to make a program in C that ask for an input of an array(max 100 elements) and then program needs to sort that matrix by numbers with same digits.
So I made everything that I know, I tested my program with sorting algorithm from minimum to maximum values and it works, only thing that I can't understand is how should I test if the number have same digits inside the loop? (I can't use functions.)
So I know the method of finding if the number have the same digits but I don't know how to compare them. Here is an example of what I need.
This is what I have for now this sorts numbers from min to max.
#include <stdio.h>
int main() {
int matrix[100];
int i,j;
int temp,min;
int elements_number=0;
printf("Enter the values of matrix-max 100 elements-type -1 to end: ");
for(i=0;i<100;i++){
scanf("%d",&matrix[i]);
elements_number++;
if(matrix[i]==-1){
elements_number--;
break;
}
}
for (i=0; i<elements_number; i++) {
min=i;
for (j=i+1; j<elements_number; j++) {
if (matrix[j] < matrix[min])
min = j;
}
temp = matrix[i];
matrix[i] = matrix[min];
matrix[min] = temp;
}
for(i=0;i<elements_number;i++){
if(i!=elements_number-1){
printf("%d,",matrix[i]); }
else printf("%d.",matrix[i]);
}
return 0;
}
I need this output for these numbers:
INPUT :
1 22 43 444 51 16 7 8888 90 11 -1
OUTPUT:
1,22,444,7,8888,11,43,51,16,90.
Integers with 1 digit count as "numbers with same number of digits" like 7 and 1 in this example.
Hope that you can help.
After processing the array, the single-digit numbers should all be in the left part of the array, the other numbers in the right part. Within each part, the original order of the elements should be preserved. This is called a stable partition. It is different from sorting, because the elements are only classified into two groups. Sorting means that there is a clear relationship between any two elements in the array.
This can be done by "filtering" the array for single-digit numbers and storing the other numbers that were filtered out in a temporary second array. Then append the contents of that second array to the (now shorter) first array.
Here's how that could work:
#include <stdlib.h>
#include <stdio.h>
void print(const int *arr, int n)
{
for (int i = 0; i < 10; i++) {
if (i) printf(", ");
printf("%d", arr[i]);
}
puts(".");
}
int is_rep_digit(int n)
{
int q = n % 10;
n /= 10;
while (n) {
if (n % 10 != q) return 0;
n /= 10;
}
return 1;
}
int main()
{
int arr[10] = {1, 22, 43, 444, 51, 16, 7, 8888, 90, 11};
int aux[10]; // auxliary array for numbers with several digits
int i, j, k;
print(arr, 10);
j = 0; // number of single-digit numbers
k = 0; // number of other numbers
for (i = 0; i < 10; i++) {
if (is_rep_digit(arr[i])) {
arr[j++] = arr[i]; // pick single-digit number
} else {
aux[k++] = arr[i]; // copy other numbers to aux
}
}
k = 0;
while (j < 10) { // copy aux to end of array
arr[j++] = aux[k++];
}
print(arr, 10);
return 0;
}
Edit: I've just seen your requirement that you can't use functions. You could use Barmar's suggestion to test divisibility by 1, 11, 111 and so on. The tricky part is to find the correct divisor, however.
Anyway, the point I wanted to make here is that you don't need a full sorting algorithm here.

issues randomly populating a 2d array of structure type in C

I'm trying to populate a 20x20 matrix where each entry is of structure type. My goal is to randomly assign 100 ants and 5 doodlebugs on this 2D array. Even though I got it to work, I don't always get the amount of ants or doodlebugs I need in the matrix. I added a counting function to always verify how many of them I have each time I run the program, but I'm always slightly short. I'm trying to force those number to work (100 ants and 5 doodlebugs) by using a do/while loop in my populating function, although it's not working. Can someone spot where is my logic is failing me?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define N 20
struct cellState {
int emptyInt;
int antInt;
int dBInt;
char emptyChar;
char antChar;
char dBChar;
};
struct cellState gridState[N][N];
// function to populate world
void pop_mtx(struct cellState gridState[N][N], int antsNeeded, int dBNeeded) {
int i, j;
do {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if ((gridState[i][j].emptyInt = rand() % 3) == 0) {
gridState[i][j].emptyChar = '.';
} else
if (((gridState[i][j].antInt = rand() % 3 == 1) && antsNeeded != 0)) {
gridState[i][j].antChar = 'a';
antsNeeded--;
} else
if (((gridState[i][j].dBInt = rand() % 3 == 2) && dBNeeded != 0)) {
gridState[i][j].dBChar = 'D';
dBNeeded--;
}
}
}
} while (dBNeeded != 0 && antsNeeded != 0);
}
//function to display current state of the world
void display_mtx(struct cellState gridState[N][N]) {
int i, j;
char charToDisplay;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
charToDisplay = 'a';
else
if (gridState[i][j].dBChar == 'D')
charToDisplay = 'D';
else
charToDisplay = '.';
printf("%c ", charToDisplay);
}
printf("\n");
}
printf("\n\n");
}
//function to count ants and doodlebugs
void count_mtx(struct cellState gridState[N][N]) {
int i, j, antCount = 0, dBcount = 0;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
antCount++;
else
if (gridState[i][j].dBChar == 'D')
dBcount++;
}
}
printf("ant count: %i, doodlebug count: %i\n", antCount, dBcount);
}
int main(void) {
srand((unsigned int)time(NULL));
//populate grid state with 5 doodlebugs and 100 ants
int antsNeeded = 100, dBNeeded = 5;
pop_mtx(gridState, antsNeeded, dBNeeded);
count_mtx(gridState);
display_mtx(gridState);
}
There are several problems. First, each time you call rand() you obtain a different value, so it is possible that none of the three tests pass. You should call rand () once and save the value.
Second, there is nothing that guarantees that over NxN calls of rand() you will get as many ones and twos as you need. The outer loop is therefore necessary. You should also preserve already populated squares from one iteration to the next because it might take a long time before you reach an iteration that produces enough ones and twos.
Third, this method is biased toward the squares at the beginning of the grid. It will not give you one out of all possible distributions of 100 ants and 5 doodlebugs over 400 squares with equal probability.
Here is the proper way to do it:
Consider the grid as a uni-dimensional array. First fill it, in order, with 100 ants, 5 doodlebugs, and empty spaces. Then perform a random shuffle of the array.
This procedure will return each possible distribution of the ants and doodlebugs on the grid with equal probability.

missing numbers

Given an array of size n. It contains numbers in the range 1 to n. Each number is present at
least once except for 2 numbers. Find the missing numbers.
eg. an array of size 5
elements are suppose 3,1,4,4,3
one approach is
static int k;
for(i=1;i<=n;i++)
{
for(j=0;j<n;j++)
{
if(i==a[j])
break;
}
if(j==n)
{
k++;
printf("missing element is", a[j]);
}
if(k==2)
break;}
another solution can be..
for(i=0;i
Let me First explain the concept:
You know that sum of natural numbers 1....n is
(n*(n+1))/2.Also you know the sum of square of sum of first n natural numbers 1,2....n is n*(n+1)*(2n+1)/6.Thus you could solve the above problem in O(n) time using above concept.
Also if space complexity is not of much consideration you could use count based approach which requires O(n) time and space complexity.
For more detailed solution visit Find the two repeating elements in a given array
I like the "use array elements as indexes" method from Algorithmist's link.
Method 5 (Use array elements as index)
Thanks to Manish K. Aasawat for suggesting this method.
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
The only difference is that here it would be traversing 1 to n.
Notice that this is a single-pass solution that uses no extra space (besides storing i)!
Footnote:
Technically it "steals" some extra space -- essentially it is the counter array solution, but instead of allocating its own array of ints, it uses the sign bits of the original array as counters.
Use qsort() to sort the array, then loop over it once to find the missing values. Average O(n*log(n)) time because of the sort, and minimal constant additional storage.
I haven't checked or run this code, but you should get the idea.
int print_missing(int *arr, size_t length) {
int *new_arr = calloc(sizeof(int) * length);
int i;
for(i = 0; i < length; i++) {
new_arr[arr[i]] = 1;
}
for(i = 0; i < length; i++) {
if(!new_arr[i]) {
printf("Number %i is missing\n", i);
}
}
free(new_arr);
return 0;
}
Runtime should be O(2n). Correct me if I'm wrong.
It is unclear why the naive approach (you could use a bitfield or an array) of marking the items you have seen isn't just fine. O(2n) CPU, O(n/8) storage.
If you are free to choose the language, then use python's sets.
numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)
Yields the output
set([2, 5])
Here you go. C# solution:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
HashSet<int> values = new HashSet<int>( numbers ) ;
for( int value = 1 ; value <= numbers.Length ; ++value )
{
if ( !values.Contains(value) ) yield return value ;
}
}
I see a number of problems with your code. First off, j==n will never happen, and that doesn't give us the missing number. You should also initialize k to 0 before you attempt to increment it. I wrote an algorithm similar to yours, but it works correctly. However, it is not any faster than you expected yours to be:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n; j++)
{
if(a[j] == i)
{
found = true;
break;
}
}
if(!found)
{
printf("missing element is %d\n", i);
k++;
if(k==2)
break;
}
else
found = false;
}
H2H
using a support array you can archeive O(n)
int support[n];
// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
support[a[i]] += 1;
// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
if(support[i] == 0) printf("%d is missing", i);
**
for(i=0; i < n;i++)
{
while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{
swap(a[i],a[a[i]-1]);
}
for(i=0;i< n;i++)
{
if(a[i]!=i+1)
printf("%d is missing",i+1); }
this takes o(n) time and o(1) space
========================================**
We can use the following code to find duplicate and missing values:
int size = 8;
int arr[] = {1, 2, 3, 5, 1, 3};
int result[] = new int[size];
for(int i =0; i < arr.length; i++)
{
if(result[arr[i]-1] == 1)
{
System.out.println("repeating: " + (arr[i]));
}
result[arr[i]-1]++;
}
for(int i =0; i < result.length; i++)
{
if(result[i] == 0)
{
System.out.println("missing: " + (i+1));
}
}
This is an interview question: Missing Numbers.
condition 1 : The array must not contain any duplicates.
The complete solution is :
public class Solution5 {
public static void main(String[] args) {
int a[] = { 1,8,6,7,10};
Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
int ch = a[i];
if(start == ch) {
start++;
}else {
list.add(start);
start++;
//must do this
i--;
}
}//for
System.out.println(list);
}//main
}

Resources