C/C++ How can I get unique value from 2 arrays? - c++

I need to get the unique value from 2 int arrays
Duplicate is allowed
There is just one unique value
like :
int arr1[3]={1,2,3};
int arr2[3]={2,2,3};
and the value i want to get is :
int unique[]={1}
how can i do this?
im already confused in my 'for' and 'if'
this was not homework
i know how to merge 2 arrays and del duplicate values
but i alse need to know which array have the unique value
plz help me :)
and here is some code i did
int arr1[3]={1,2,3}
int arr2[3]={2,2,3}
int arrunique[1];
bool unique = true;
for (int i=0;i!=3;i++)
{
for (int j=0;j!=3;j++)
{
if(arr1[i]==arr2[j])
{
unique=false;
continue;
}
else
{
unique=true;
}
if(unique)
{
arrunique[0]=arr1[i]
break;
}
}
cout << arrunique[0];

Assuming:
You have two arrays of different length,
The arrays are sorted
The arrays can have duplicate values in them
You want to get the list of values that only appear in one of the arrays
including their duplicates if present
You can do (untested):
// Assuming arr1[], arr2[], and lengths as arr1_length
int i = 0,j = 0, k = 0;
int unique[arr1_length + arr2_length];
while(i < arr1_length && j < arr2_length) {
if(arr1[i] == arr2[j]) {
// skip all occurrences of this number in both lists
int temp = arr1[i];
while(i < arr1_length && arr1[i] == temp) i++;
while(j < arr2_length && arr2[j] == temp) j++;
} else if(arr1[i] > arr2[j]) {
// the lower number only occurs in arr2
unique[k++] = arr2[j++];
} else if(arr2[j] > arr1[i]) {
// the lower number only occurs in arr1
unique[k++] = arr1[i++];
}
}
while(i < arr1_length) {
// if there are numbers still to read in arr1, they're all unique
unique[k++] = arr1[i++];
}
while(j < arr2_length) {
// if there are numbers still to read in arr2, they're all unique
unique[k++] = arr2[j++];
}
Some alternatives:
If you don't want the duplicates in the unique array, then you can skip all occurrences of this number in the relevant list when you assign to the unique array.
If you want to record the position instead of the values, then maintain two arrays of "unique positions" (one for each input array) and assign the value of i or j to the corresponding array as appropriate.
If there's only one unique value, change the assignments into the unique array to return.

Depending on your needs, you might also want to look at set_symmetric_difference() function of the standard library. However, its treatment of duplicate values makes its use a bit tricky, to say the least.

#include <stdio.h>
#include <stdlib.h>
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int main()
{
int arr1[5] = {5,4,6,3,1};
int arr2[3] = {5, 8, 9};
int unique[8];
qsort(arr1,5,sizeof(arr1[0]),cmp);
printf("\n");
qsort(arr2,3,sizeof(arr2[0]),cmp);
//printf("%d", arr1[0]);
int i = 0;
int k = 0;
int j = -1;
while (i < 5 && k < 3)
{
if(arr1[i] < arr2[k])
{
unique[++j] = arr1[i];
i++;
}
else if (arr1[i] > arr2[k])
{
unique[++j] = arr2[k];
k++;
}
else
{
i++;
k++;
}
}
//int len = j;
int t = 0;
if(i == 5)
{
for(t = k; t < 3; t++)
unique[++j] = arr2[t];
}
else
for(t = i; t < 5; t++)
unique[++j] = arr2[t];
for(i = 0; i <= j; i++)
printf("%d ", unique[i]);
return 0;
}
This is my codes,though there is a good answer .
I didn't realize the idea that know which array have the unique value.
I also think that the right answer that you chose didn't , either.

Here is my version of the algorithm for finding identical elements in sorted arrays on Python in C ++, it works in a similar way
def unique_array(array0 : (int), array1 : (int)) -> (int):
index0, index1, buffer = 0, 0, []
while index0 != len(array0) and index1 != len(array1):
if array0[index0] < array1[index1]:
buffer.append(array0[index0])
index0 += 1
elif array0[index0] > array1[index1]:
buffer.append(array1[index1])
index1 += 1
else:
index0 += 1; index1 += 1
buffer.extend(array0[index0 : len(array0)])
buffer.extend(array1[index1 : len(array1)])
return buffer

Related

equal jump between numbers in two arrays

I want to compare two arrays. One of them is a subset of the other one. I want my function to return the minimum and equal gap between the numbers of the first subset array in the other array.
For example if I have
arr1 = 2,1,4,2,8,3
sub= 1,2,3
I want my function to return 1 because the mimimum gap between all this numbers are 1.
arr1 = 2,1,5,2,1,2,3
sub= 1,2,3
I want my function to return 0 because the mimimum gap between 1,2,3 in arr1 is 0
Here is the code I am trying to do: My code always return 0 can you help me understand why, and how can I solve this.
int gap(int* arr, int* sub, int sizeArr, int sizeSub)
{
int index = 0; int gap = 0; bool flag = true;
int i = -1;
for (int jump = 1; jump < sizeArr / sizeSub; jump++)
{
index = 0;
for (i = i +1; i < sizeArr; i++)
{
if (sub[index] == arr[i])
{
for (int j = i + jump, index = 1; j < sizeArr; j = j + jump, index++)
{
if (arr[j] != sub[index]) { flag = false; break; }
else if (arr[j] == sub[index] && index == sizeSub) { flag = true; break; }
}
}
if (!flag) { break; }
else { gap = jump; break; }
}
}
return gap;
}
You initially took gap equally 0 but i think more suit to not store gap
and start iterate jump from 0. And return jump immediately after you found that it is suit.
Also i think that store index in such manner as you it is bad idea, because you code return wrong answer on
int a[] = { 2,1,4,4,2,8,5,3 };
int s[] = { 1,2,3 };
I think you should declare variable as soon as possible, otherwise there will be undesirable side effects.
So you code can be rewritten as
int gap(int *arr, int *sub, int sizeArr, int sizeSub)
{
for (int jump = 0; 1 + (jump + 1) * (sizeSub - 1) <= sizeArr; jump++) {
for (int start_index = 0; start_index + (jump + 1) * (sizeSub - 1) < sizeArr; start_index++) {
bool flag = true;
for (int index = 0; index < sizeSub; ++index) {
if (arr[start_index + index * (jump + 1)] != sub[index]) {
flag = false;
break;
}
}
if (flag) {
return jump;
}
}
}
return -1; //or some value that indicate that there is no answer
}

Generate numbers from 2 to 10,000. The numbers printed can only be a multiple of 2 prime numbers

Homework: I'm just stumped as hell. I have algorithms set up, but I have no idea how to code this
Just to be clear you do not need arrays or to pass variables by reference.
The purpose of the project is to take a problem apart and using Top-Down_Design or scratch pad method develop the algorithm.
Problem:
Examine the numbers from 2 to 10000. Output the number if it is a Dual_Prime.
I will call a DualPrime a number that is the product of two primes. Ad where the two primes are not equal . So 9 is not a dual prime. 15 is ( 3 * 5 ) .
The output has 10 numbers on each line.
My Algorithm set-up
Step 1: find prime numbers.:
bool Prime_Number(int number)
{
for (int i = 2; i <= sqrt(number); i++)
{
if (number % 1 == 0)
return false;
}
return true;
}
Step 2: store prime numbers in a array
Step 3: Multiply each array to each other
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int j = 0; j < Size- 1; j++)
{
Dual_Prime[] = Arr[j] * Arr[j + 1]
}
}
Step 4: Bubble sort
void Bubble_Sort(int Array[], int Size) // Sends largest number to the right
{
for (int i = Size - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (Array[j] > Array[j + 1])
{
int Temp = Array[j + 1];
Array[j + 1] = Array[j];
Array[j] = Temp;
}
}
Step 5: Display New Array by rows of 10
void Print_Array(int Array[], int Size)
{
for (int i = 0; i < Size; i++)
{
cout << Dual_Prime[i] << (((j % 10) == 9) ? '\n' : '\t');
}
cout << endl;
}
I haven't learned dynamic arrays yet,
Although dynamic arrays and the sieve of Eratosthenes are more preferable, I tried to write minimally fixed version of your code.
First, we define following global variables which are used in your original implementation of Multiply_Prime_Numbers.
(Please check this post.)
constexpr int DP_Size_Max = 10000;
int DP_Size = 0;
int Dual_Prime[DP_Size_Max];
Next we fix Prime_Number as follows.
The condition number%1==0 in the original code is not appropriate:
bool Prime_Number(int number)
{
if(number<=1){
return false;
}
for (int i = 2; i*i <= number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
In addition, Multiply_Prime_Numbers should be implemented by double for-loops as follows:
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int i = 0; i < Size; ++i)
{
for (int j = i+1; j < Size; ++j)
{
Dual_Prime[DP_Size] = Array[i]*Array[j];
if(Dual_Prime[DP_Size] >= DP_Size_Max){
return;
}
++DP_Size;
}
}
}
Then these functions work as follows.
Here's a DEMO of this minimally fixed version.
int main()
{
int prime_numbers[DP_Size_Max];
int size = 0;
for(int j=2; j<DP_Size_Max; ++j)
{
if(Prime_Number(j)){
prime_numbers[size]=j;
++size;
}
}
Multiply_Prime_Numbers(prime_numbers, size);
Bubble_Sort(Dual_Prime, DP_Size);
for(int i=0; i<DP_Size;++i){
std::cout << Dual_Prime[i] << (((i % 10) == 9) ? '\n' : '\t');;
}
std::cout << std::endl;
return 0;
}
The Sieve of Eratosthenes is a known algorithm which speeds up the search of all the primes up to a certain number.
The OP can use it to implement the first steps of their implementation, but they can also adapt it to avoid the sorting step.
Given the list of all primes (up to half the maximum number to examine):
Create an array of bool as big as the range of numbers to be examined.
Multiply each distinct couple of primes, using two nested loops.
If the product is less than 10000 (the maximum) set the corrisponding element of the array to true. Otherwise break out the inner loop.
Once finished, traverse the array and if the value is true, print the corresponding index.
Here there's a proof of concept (implemented without the OP's assignment restrictions).
// Ex10_TwoPrimes.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void Homework_Header(string Title);
void Do_Exercise();
void Sieve_Of_Eratosthenes(int n);
void Generate_Semi_Prime();
bool Semi_Prime(int candidate);
bool prime[5000 + 1];
int main()
{
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
int n = 5000;
Sieve_Of_Eratosthenes(n);
cout << endl;
Generate_Semi_Prime();
}
void Sieve_Of_Eratosthenes(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= n; p++)
{
// If prime[p] is not changed, then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
}
bool Semi_Prime(int candidate)
{
for (int index = 2; index <= candidate / 2; index++)
{
if (prime[index])
{
if (candidate % index == 0)
{
int q = candidate / index;
if (prime[q] && q != index)
return true;
}
}
}
return false;
}
void Generate_Semi_Prime()
{
for (int i = 2; i <= 10000; i++)
if (Semi_Prime(i)) cout << i << "\t";
}

Duplicate numbers in an array [duplicate]

This question already has answers here:
Deleting duplicates in the array
(2 answers)
Closed 8 years ago.
I need to write a program where I have to print the numbers which occur twice or more than twice in the array. To make things simpler, I am working on a sorted array.
Here is my code.
#include <stdio.h>
int main()
{
int n,i;
int a[10]={2,2,2,4,6,6,9,10,10,11};
printf("%d\n",a[10]);
for(i=0;i<10;++i)
{
if(a[i]==a[i+1] && a[i]!=a[i-1])
printf("%d ",a[i]);
else
continue;
}
return 0;
}
The code seems to work fine but I do not like my code because at some point, the loop compares the value of a[0] with a[-1] and a[9] with a[10] and both of these, a[-1] and a[10], are garbage values. I am sure there are better ways to do it but I am unable to think of any.
Also, I need to extend the above program to count the frequency of duplicate numbers.
Help is appreciated. Thanks!
First, you can't access a[10] in your printf line, this is outside your array.
This should work fine.
#include <stdio.h>
int main()
{
int n,i;
int a[10]={2,2,2,4,6,6,9,10,10,11};
for(i=0; i < 9; ++i)
{
if(a[i] == a[i+1])
if(i > 0 && a[i] == a[i-1])
continue;
else
printf("%d ",a[i]);
}
return 0;
}
Edit: Or you can use the shorter yet harder to read:
for(i=0; i < 9; ++i)
{
if(a[i] == a[i+1] && (!i || a[i] != a[i-1]))
printf("%d ",a[i]);
}
See code below for the solution, which will print only the duplicate numbers from the array and how many times they occur.
I added the int c which is used for your count. It is initially set to 1, and increased by 1 for each duplicate number.
#include <stdio.h>
using namespace std;
int main() {
int n,i,c;
int a[10]={2,2,2,4,6,6,9,10,10,11};
c = 1;
for(i=0; i < 9; ++i)
{
if (a[i] == a[i+1]) {
n = a[i];
c += 1;
} else {
if (c > 1) {
printf("Number: %d, Occurences: %d \n",n,c);
c = 1;
}
}
}
return 0;
}
Since the array is already sorted, it'd be easier to do something like this, with another loop inside the for loop.
int duplicateCount = 1; // Must be at least one instance of a value in the array
for(int i = 0; i < 9; ++i) {
int j = i;
while(j != 9 && a[j] == a[j + 1]) {
++j;
++duplicateCount;
}
i = j; // j is now at end of list of duplicates, so put i at the end as well,
// to be incremented to the next unique value at end of for loop iteration
printf("%d: %d\n", a[j], duplicateCount);
duplicateCount = 1; // Reset for next values
}
If you want to count the frequency of all the numbers, you can easily turn duplicateCount into an array of values to count the frequency of each unique value. For a better solution, you could use another data structure, such as a map.
You are really going to need to have two indexes that walk through your array.
Here's a start:
int i = 0;
int j;
while (i < 10) {
for (j = i+1; j < 10; ++j) if (a[i] != a[j]) break;
if (j !+ i+i) printf("%d\n", a[i]);
i = j;
}
You could use a functor, overload operator() and return a set (unique values). Assuming your array is sorted it's just a matter of comparing the previous one with the next and inserting it in the set if they equal. If they are not sorted then you have to go through the whole array for every entry. Below are two examples with output as an explanation.
#include <set>
using namespace std;
Unsorted array:
struct UnsortedArrayDuplicateEntries {
set<int> operator()(int* array, int size) {
set<int> duplicates;
for (int i = 0; i < size - 1; i++)
for (int j = i + 1;j < size; j++)
if (array[i] == array[j])
duplicates.insert(array[j]);
return duplicates;
}
};
Sorted array:
struct SortedArrayDuplicateEntries {
set<int> operator()(int* array, int size) {
set<int> duplicates;
for (int i = 0; i < size - 1; i++)
if (array[i] == array[i+1])
duplicates.insert(array[j]);
return duplicates;
}
};
Test sorted:
SortedArrayDuplicateEntries d;
int sorted[10]={2,2,2,4,6,6,9,10,10,11};
set<int> resultSorted = d(sorted,10);
for (int i : resultSorted) cout << i << endl;
Output sorted:
2
6
10
Test unsorted:
UnsortedArrayDuplicateEntries d;
int unsorted[10]={2,6,4,2,10,2,9,6,10,11};
set<int> resultUnsorted = d(unsorted,10);
for (int i : resultUnsorted) cout << i << endl;
Output unsorted:
2
6
10
I hope it helps!
#include <stdio.h>
int main(){
int i, a[10]={2,2,2,4,6,6,9,10,10,11};
int size = 10;
for(i=0;i<size;++i){
int tmp = a[i];
int c = 1;
while(++i < size && tmp == a[i])
++c;
if(c > 1)
printf("%d times %d\n", tmp, c);
--i;
}
return 0;
}

least frequent common number from a int array

I have to find least common number from an int array , I have written code but it is not working properly ,
Here is my logic,
1. sort the array
2. get min common counter updated
3. get if all are unique
and the code below,
static int min_loc ; //minimum value location
static int min_cnt ;
int all_uniqFlag = true;
void leastCommon(int data[],int n)
{
int rcount = 0; //Repeated number counter
int mcount = n; // minimum repetetion counter;
// The array is already sorted we need to only find the least common value.
for(int i = 0 ; i < n-1 ; i++)
{
//Case A : 1 1 2 2 2 3 3 3 3 4 5 5 5 5 : result should be 4
//Case B : 1 2 3 4 5 6 7 (All unique number and common values so all values should be printed
// and )
//Case C : 1 1 2 2 3 3 4 4 (all numbers have same frequency so need to display all )
cout << "data[i] : " << data[i] << " data[i+1] : " << data[i+1] << "i = " << i << endl;
if(data[i] != data[i+1])
{
//mcount = 0;
//min_loc = i;
//return;
}
if(data[i] == data[i+1])
{
all_uniqFlag = false;
rcount++;
}
else if(rcount < mcount)
{
mcount = rcount;
min_loc = i ;//data[i];
}
}
min_cnt = mcount;
}
As mentioned in the comment only Case B works and Case A and C is not working could you help me fix the issue ?
scan through the list
compare each element in the list with the last element in the out array
If the element matches, then increment its count by 1
If the element doesn't match then add the new element into out
array and increment index by 1
Once the scan is done, the out array will have all the distinct elementsout[][0] and their frequencies out[][1]
Scan through the frequency list (out[][1]) to find the lowest frequency
Finally do another scan through the element list out[][0] and print elements whose frequency matches with the lowest frequency
.
#include<stdio.h>
#include<stdlib.h>
#define N 8
int main()
{
//int data[N]={1,2,3,4,5,6,7};
int data[N]={1,1,2,2,3,3,4,4};
//int data[N]={1,1,2,2,2,3,3,3,3,4,5,5,5,5};
int out[N][2];
int i=0,index=0;
for(i=0;i<N;i++)
{
out[i][0]=0;
out[i][1]=0;
}
out[0][0] = data[0];
out[0][1]=1;
for(i=1;i<N;i++)
{
if(data[i] != out[index][0])
{
index++;
out[index][0] = data[i];
out[index][1] = 1;
}
else
{
out[index][1]++;
}
}
int min=65536;
for(i=0;i<N;i++)
{
if(out[i][1] == 0)
{
break;
}
if(out[i][1] < min)
{
min = out[i][1];
}
}
for(i=0;i<N;i++)
{
if(out[i][1] == min)
{
printf("%d\t",out[i][0]);
}
}
printf("\n");
}
You can use a map for this:
#include <string>
#include <map>
#include <iostream>
typedef std::map<int, int> Counter;
void leastCommon(int data[],int n) {
Counter counter;
int min = n;
for (int i = 0; i < n; i++)
counter[data[i]]++;
for (Counter::iterator it = counter.begin(); it != counter.end(); it++) {
if (min > it->second) min = it->second;
}
for (int i = 0; i < n; i++) {
if (counter[data[i]] == min) {
std::cout << data[i] << std::endl;
counter[data[i]]++;
}
}
}
int main() {
int data[] = {1, 1,3,4,4,2,4,3,2};
leastCommon(data, 9);
return 0;
}
Approach is-
select 1st element from the sorted array, and while consecutive elements to it are same, store them in output[] until the loop breaks
store the frequency of element in leastFrequency
select next element, check with its consecutive ones and store them in same output[] until the loop breaks
check frequency of this with the leastFrequency
if same, do nothing (let these be added in the output[])
if less, clear output[] and store the element same no. of times
if more, change the effective output[] length to previous length before iterating for this element
similarly iterate for all distinct elements and finally get the result from output[] from 0 to effective length
void leastCommon(int data[], int len) {
if ( len > 0) {
int output[] = new int[len];
int outlen = 0; // stores the size of useful-output array
int leastFrequency = len; // stores the lowest frequency of elements
int i=0;
int now = data[i];
while (i < len) {
int num = now;
int count = 0;
do {
output[outlen] = now;
outlen++;
count++;
if((++i == len)){
break;
}
now = data[i];
} while (num == now); // while now and next are same it adds them to output[]
if (i - count == 0) { // avoids copy of same values to output[] for 1st iteration
leastFrequency = count;
} else if (count < leastFrequency) { // if count for the element is less than the current minimum then re-creates the output[]
leastFrequency = count;
output = new int[len];
outlen = 0;
for (; outlen < leastFrequency; outlen++) {
output[outlen] = num; // populates the output[] with lower frequent element, to its count
}
} else if (count > leastFrequency) {
outlen -= count; // marks outlen to its same frequent numbers, i.e., discarding higher frequency values from output[]
}
}
//for(int j = 0; j < outlen; j++) {
// print output[] to console
//}
}
}
Plz suggest for improvements.

c++ inserting and sorting "empty" array at the same time

I am still learning C++, so please if this is a duplicate point me to correct topic as I couldn't find any good and useful explanation.
I try to create a function in my ascending_ordered_array class which will insert elements into "empty" array sorting them in the same time.
Below is my code so far, but unfortunately it doesn't work 100% correctly as it adds two largest numbers as a last for positions in array.
void ascOrderedArray::push(Datatype p_item, Datatype* p_array, int p_size)
{
int i, j = 0;
int temp, num;
if (p_array[j] < 0)
p_array[j] = p_item;
for (i = 0; i < (p_size - 1); i++)
{
num = p_size;
for (j = (p_size - 1); j >= i; j--)
{
if (p_array[num]> p_array[j])
num = j;
}
temp = p_array[num];
p_array[num] = p_item;
p_array[i] = temp;
}
}
Here is part of main which call function above trying place random numbers into it
for (i = 0; i < size; i++)
{
num = (i + 1)* (rand() % 100);
arr.push(num, arr, size);
}
any hints what I am missing out?
This is code I wrote and its work as long as it is no resize neccessary
void ascOrderedArray::push(Datatype p_item)
{
//check if array is big enough and resize it if necessary
if (m_numElements >= m_size)
resize();
//checking if array contains some elements and if not set its first to pased item
if (m_numElements == 0)
{
m_array[0] = p_item;
m_numElements++;
return;
}
else
{
int i = m_numElements;
while (i >= 0 && i <= m_numElements)
{
//shifting array elements
m_array[i] = m_array[i - 1];
if (p_item > m_array[i - 1])
{
m_array[i] = p_item;
break;
}
--i;
}
m_numElements++;
}
}