Storing numbers in array in C - c

I have three one-dimensional arrays. The task is to store the numbers which exist in each of the three arrays in a forth array. Here is my solution which as you see isn't correct. I'm also interested in a faster algorithm if possible because it's O(N3) difficulty.
#include <stdio.h>
main(){
int a[5]={1,3,6,7,8};
int b[5]={2,5,8,7,3};
int c[5]={4,7,1,3,6};
int i,j,k;
int n=0;
int d[5];
for(k=0; k<5; k++){
for(j=0; j<5; j++){
for(i=0; i<5; i++){
if(a[i]==b[j] && b[j]==c[k])
{d[n]=a[i];
n++;}
else
d[n]=0;
}}}
//Iterate over the new array
for(n=0;n<5;n++)
printf("%d\n",d[n]);
return 0;
}

One way to improve to O(n log n) is to sort all three arrays first.
Then use three pointers one for each array. You always move the one that points to the lowest value and after every such move check whether the three values are the same.
To improve even further you can use hashtable.
Iterate through the first array and put it's values in a hashtable as keys.
Then iterate through the second array and every time when the value exists as a key in the first hashtable, put it in a second one.
Finally iterate over the third array and if a value exists in the second hashtable as a key store it in the forth array. This is O(n) assuming the hashtable operations are O(1).

Your mistake is that you're using one of your three nested counters (which are being used to index the input arrays) as the index into the output array. You need to have a fourth index (let's call it n), which starts at zero, only increments every time a satisfactory value has been found.

Sort second and third arrays beforehand and use binary search on them to determine is some element is present.
If element is present in all of your arrays - it will present in the first. So, go through first (unsorted) array and check if its element is in second and third.
If you take the shortest array as the first - it will make algorithm slightly faster too.

You did't store them on d[] the right way.
Once found you can skip the rest of a[] and b[] for that element of c[].
#include <stdio.h>
main(){
int a[5]={1,3,6,7,8};
int b[5]={2,5,8,7,3};
int c[5]={4,7,1,3,6};
int i,j,k;
int n=0;
int found;
int d[5];
for(k=0; k<5; k++){
found=0;
for(j=0; j<5 && !found; j++){
if (b[j]==c[k]) {
for(i=0; i<5 && !found; i++){
if(a[i]==b[j]) {
d[n++]=c[k];
found=1;
}
}
}}}
//Iterate over the new array
for(i=0;i<5;i++)
printf("%d\n",d[i]);
return 0;
}

Related

C: I made a program to sort an array in ascending order and cannot figure the reason for a certain step in the for loops

I am making a program to sort numbers in an array using the bubble sort method in c and I know how to do it but I cannot figure out what the second for loop's j<n-i-1subtraction of i from the length of the array is for. It is probably a simple explanation but I cannot for the life of me scramble my small brain for the answer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int input[10],swap;
printf("Input Numbers: ");
scanf("%d%d%d%d%d%d%d%d%d%d",&input[0],&input[1],&input[2],&input[3],&input[4],&input[5],&input[6],&input[7],&input[8],&input[9]);
int n=10;
for(int i=0;i<n-1;i++){
for(int j=0;j<n-i-1;j++){
if(input[j]>input[j+1]){
swap=input[j];
input[j]=input[j+1];
input[j+1]=swap;
}
}
}
printf("Sorted List: {");
for(int i=0;i<10;i++){
if(i<9){
printf("%d, ",input[i]);
}
else{
printf("%d}",input[i]);
}
}
return 0;
}
In the first iteration of the i loop, the greatest element is bubbled to the end of the n elements in the array. After that, we know the last element is done. So we only need to do the n-1 remaining elements.
In the second iteration of the i loop, the next greatest element is bubbled to the end of the n-1 elements we were working on. After that, we know the last two elements are done. So we only need to do the n-2 remaining elements.
This continues, so that in each iteration, we only need to work on n-i elements. Since elements j and j+1 are compared, we only need j to reach n-i-2, i.e., be less than n-i-1., as that will give j+1 up to n-i-1. (The number of elements from index 0 to index n-i-1 is n-i.)

developing a function that returns number of distinct values that exist in array

I want to create a function that can return the number distinct values present in a given array. If for eg the array is
array[5] = { 1 3 4 1 3}, the return value should be 3(3 unique numbers in array).
I've so far only got this:
int NewFucntion(int values[], int numValues){
for (i=0; i<numValues; i++){
Im a new coder/New to C language and im stuck on how to proceed. Any guidance would be much appreciated. Thanks
Add elements from the array to the std::set<T> and since the set is not allowing duplicate elements, you can then only get the number of elements from the set which gives you the number of distinct elements.
For example:
#include<set>
int NewFucntion(int values[], int numValues){
std::set<int> set;
for(int i=0; i<numValues; i++){
set.insert(values[i]);
}
return set.size();
}
int distinct(int arr[], int arr_size){
int count = arr_size;
int current;
int i, j;
for (i = 0; i < arr_size; i++){
current = arr[i];
for (j = i+1; j < arr_size; j++) // checks values after [i]th element.
if (current == arr[j])
--count; // decrease count by 1;
}
if (count >= 0)
return count;
else return 0;
}
Here's the explanation.
The array with its size is passed as an argument.
current stores the element to compare others with.
count is the number that we need finally.
count is assigned the value of size of the array (i.e we assume that all elements are unique).
(It can also be the other way round)
A for loop starts, and the first (0th) element is compared with the elements after it.
If the element reoccurs, i.e. if (current==arr[j]), then the value of count is decremented by 1 (since we expected all elements to be unique, and because it is not unique, the number of unique values is now one less than what it was initially. Hence --count).
The loops go on, and the value is decremented to whatever the number of unique elements is.
In case our array is {1,1,1,1}, then the code will print 0 instead of a negative value.
Hope that helps.
Happy coding. :)
I like wdc's answer, but I am going to give an alternative using only arrays and ints as you seam to be coding in c and wdc's answer is a c++ answer:
To do this thing, what you need to do is to go through your array as you did, and store the new numbers you go over in a different array lets call it repArray where there wont be any repetition; So every time you add something to this array you should check if the number isn't already there.
You need to create it and give it a size so why not numValues as it cannot get any longer than that. And an integers specifying how many of it's indexes are valid, in other words how many you have written to let's say validIndexes. So every time you add a NEW element to repArray you need to increment validIndexes.
In the end validIndexes will be your result.

Avoiding duplicates in a 2D array?

I am doing a program in C which needs to take in a set of values (integers) into a 2D array, and then performs certain mathematical operations on it. I have decided to implement a check in the program as the user is inputting the values to avoid them from entering values that are already present in the array.
I am however unsure of how to go about this check. I figured out I might need some sort of recursive function to check all the elements previous to the one that's being entered, but I don't know how to implement it.
Please find below a snippet of my code for illustrative purposes:
Row and col are values inputted by the user for the dimension of the array
for (int i=0; i<row;i++){
for (int j=0; j<col; j++){
scanf("%d", &arr[i][j]); //take in elements
}
}
for (int i = 0; i < row; i++)
{
for (int j = 0; i < col; j++)
{
if (arr[i][j] == arr[i][j-1]){
printf("Duplicate.\n");}
else {}
}
}
I know this is probably not correct but it's my attempt.
Any help would be much appreciated.
I would suggest that your store every element you read in a temporary 1D array. Everytime you scan a new element, traverse the 1D array checking if the value exists or not. Although this is not optimal, this will be at least less expensive than traversing the 2D array everytime.
Example:
int temp[SIZE];
int k,elements = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
scanf("%d", &arr[i][j]); //take in elements
temp[elements] = arr[i][j];
elements++;
for (int k = 0; k < elements; k++) {
if (temp[k] == arr[i][j])
printf("Duplicate.\n"); //or do whatever you wish
}
}
}
A balanced tree inserts and searches in O(log N) time.
Since the algorithms are quite simple & standard and were published in the seminal books by Knuth, there are plenty of implementations out there, including a clear and concise one at codereview.SE (which is thus automatically CC-BY-SA 3.0; do apply a bugfix in the answer). Using it (as well as virtually any other one) is simple: start with node* root = NULL;, then insert and search, and finally free_tree.
Asymptotically, the best method is a hash table with O(1) for both, but that is probably an overkill (the algorithms are much more complex and memory footprint is larger) unless you have a lot of numbers. For C++, there's a standard implementation, yet there are plenty 3rd-party ones for C, too.
If your number of input values is small, even the tree may be an overkill, and simply looking through previous values would be fast enough. If your 2D array is contiguous in memory, you can access it as 1D with int* arr1d = (int*)&arr2d.

Array in JAVA., repeat?

I'm writing a function using java language that takes in a 1D array and the size of the array as inputs to the function. I want to find out how many function values of are in the array. How would I do this?
Approach 1(O(nlogn)):
Sort the array.
Compare the adjacent elements in array
Increment the count whenever the adjacent elements are unequal. Please take care of three consecutive same elements using an extra variable.
Approach 2(O(n) but space complexity of O(n)):
Create a Hash Table for value.
Insert a value if not present in the hash table.
Count and print the values for present in hashtable
#Find unique items from array:
1. Create one new array
2. Take each item from existing array
3. Check if the item is exist in new array
4. **If not exist push the item into new array** else go for next item
5. After iterating all item in array get the length of new array
#include <stdio.h>
int main ()
{
int n[10] = {1,2,5,5,3,4,1,4,5,11};
int count = 0; int i = 0;
for (i=0; i< 10; i++)
{
int j;
for (j=0; j<i; j++)
if (n[i] == n[j])
break;
if (i == j)
count += 1;
}
printf("The counts are: %d distinct elements", count);
return 0;
}

Sorting columns(comparison lexicography) in matrix | C

I am stuck int he second part of this mission. I think i have problem with my algorithm.
Let me know please if my code is in the good direction.
This is my mession
Given set two - dimensional integers. The array consists of 5 rows and 10 columns. Each value in the system is a random number between 0 and 20. Have to write a program that performs the sorting of the array values as follows: First there arrange the values in each column so that they are sorted in ascending order (top to bottom), then - so there can sort the columns right "comes right" by comparing pairs of values in different columns in the same row (a "comparison lexicography"): comparing two values ​​in two columns in the first row, if they are the same compared to the values in the second row, and so on, and accordingly change the order of columns (see example in the third printing of the array, below). To display the array before sorting and after each of the two phases of the emergency. for example :
#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include "stdlib.h"
#define N 5
#define M 10
#define LOW 0
#define HIGH 20
void initRandomArray(int arr[N][M]);
void printArray(int arr[N][M]);
void SortInColumn(int arr[N][M],int m);
void SortColumns(int arr[][M]);
int compareColumns(int arr[][M], int col1, int col2);
void swapColumns( int col1, int col2);
int main()
{
int arr[N][M];
int m;
m=M;
srand((unsigned)time(NULL)); //To clear the stack of Random Number
initRandomArray(arr);
printf("Before sorting:\n");
printArray(arr);
printf("Sorting elements in each column:\n");
SortInColumn(arr,M);
printf("Sorting columns:\n");
SortColumns(arr);
system("pause");
return 0;
}
void initRandomArray(int arr[N][M])
{
int i,j;
for (i=0 ; i<N ; i++)
for (j=0 ; j<M ; j++)
{
arr[i][j]=LOW+rand()%(HIGH-LOW+1);
}
}
void printArray(int arr[N][M])
{
int i,j;
for (i=0 ; i<N ; i++)
{
for (j=0 ; j<M ; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
}
void SortInColumn(int arr[][M],int m)
{
int i,j,k;
int temp;
for( k=0 ; k<m ; ++k) // loops around each columns
{
for(j=0; j<N-1; j++)// Loop for making sure we compare each column N-1 times since for each run we get one item in the right place
{
for(i=0; i < N-1 - j; i++) //loop do the adjacent comparison
{
if (arr[i][k]>arr[i+1][k]) // compare adjacent item
{
temp=arr[i][k];
arr[i][k]=arr[i+1][k];
arr[i+1][k]=temp;
}
}
}
}
printArray(arr);
}
void SortColumns(int arr[][M])
{ int row=0,cols=0,i=0,n=N;
int col1=arr[row][cols];
int col2=arr[row][cols];
compareColumns(arr,col1,col2);
}
int compareColumns(int arr[][M], int col1, int col2)
{
int row=0,cols=0,j;
for ( row=0 ; row < N ; row ++ );
{
for( cols=0 ; cols < M-1 ; cols++)
{
if(arr[row][cols]>arr[row][cols+1])
{
for (j=0 ; j < M-1 ; j++)
{
col1=arr[row][cols];
col2=arr[row][cols+1];
swapColumns(col1 , col2 );
}
}
}
}
printArray(arr);
}
void swapColumns(int col1, int col2)
{
int temp;
temp=col1;
col1=col2;
col2=temp;
}
By the way is the Complexity of compareColumns function is (n^3) ?
That algorithm is too slow, you can do better.
You can exploit the fact that every number is between 0 and 20 to sort the columns in linear time. To do so, use an auxiliary 20x10 array, where array[i][j] holds how many times the value i appears in column j of the original matrix. For your example, the first column holds the values 12, 18, 13, 17, 13, thus we would have:
array[12][0] = 1
array[13][0] = 2
array[18][0] = 1
array[17][0] = 1
Building this array takes O(n) time for a matrix with n elements (in fact, the problem size is always the same - 5*10 = 50)
Aftr building that array, you now have two possibilities:
a) Overwrite the original matrix with the sorted column values. For this, you would go into each column j in the auxiliary array, and scan the values. For the first column, for example, the first non-zero value is in array[12][0], which is 1, so you write "12" in the first column in the original array, and increment the row count so that you will write the next value in the correct position. Then, you'd see that array[13][0] is 2, so you'd write "13" twice in the original matrix. You keep doing this for every column. Now you have a matrix with sorted columns, and you can apply your method for lexicographic sorting between columns.
b) Since you want lexicographic order between columns, you can see that this is equivalent to sorting columns by their accumulated sum value. So, you could store another additional array of 10 elements, where each element is a structure holding the accumulated sum for array[0..20][j], and the position j (note that for position i, array[i][j]*i is the real value for the sum). Sorting this 10-element array is very fast, and now all you have to do is iterate through this sorted array. For each position in that array, you use the original index j (stored in the structure before) to index array[0][j], and then overwrite the original matrix using the method described in a). This has the advantage that you don't need to write any sorting procedure at all, you can use your system qsort.
This solution scales well for acceptable values. For a matrix with N elements, building the auxiliary array and the accumulated sums array takes O(N). Sorting the accumulated sums array takes time proportional to the number of columns, and overwriting the original array takes O(N) time.
Note that this algorithm is quick enough, but it can consume a lot of memory for very big values. You might want to think if you can reduce memory usage by increasing runtime.
As for the code you posted, it's very incomplete, please try to provide us with something a little more polished.

Resources