removing double elements in an array - c++

I am trying to remove double elements in an array. I developed a simple code, but it is still not working. Is it possible to hint for some input maybe I haven't tried. I tried corner and test cases. The following is the problem statement:
A sequence of numbers given. Remove element’s doubles, leaving first copy.
Input: Contains a natural n (n ≤ 100000) – the n quantity numbers in a sequence, then n non-negative numbers – elements of the sequence which module is not greater than 999.
output: changed sequence.
It seems I can't get what might be the problem
#include <iostream>
//#include <cmath>
//#include <climits>
#define SIZE 100000
using namespace std;
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, p;
bool tag; tag = false;
cin >> n;
long long int *a = new long long int[n];
long long int b[SIZE];
for (int i = 0; i < n; i++) { cin >> a[i]; }
for (int i = 0; i < n; i++) { k = 0;
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j]) { b[k] = j-k; k++; tag = true; }
}
if (tag) {
for (int i = 0; i < k; i++) {
p = b[i];
for (int i = p; i < n; i++) { a[i] = a[i + 1]; }
n--;
}
tag = false;
}
}
for (int i = 0; i < n; i++) { cout << a[i] << " "; }
return 0;
}
Input: 6 1 2 2 4 3 4 Output: 1 2 4 3

You can use unordered_set and vector
int n; cin >> n;
long long int x;
unordered_set<long long int>myset;
vector<long long int>v1;
for (int i = 0; i < n; i++)
{
cin>>x;
if(myset.find(x)==myset.end())
{
myset.insert(x);
v1.push_back(x);
}
}
for(int i=0;i<v1.size();i++)
{
cout<<v1[i]<<" ";
}

You could use in you advantage the fact that input values are in the range from 0 to 999.
A simple bool used[1000]{} could be used to flag if the current value has been used already before pushing it to cout, thus ensuring both O(n) complexity and limited memory usage (1000 bytes for the bool[]}.
Here's a sample solution around this idea:
#include<iostream>
#define MAX_VALUE 999
using namespace std;
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
bool used[MAX_VALUE + 1]{};
size_t n;
cin >> n;
for (size_t num, i = 0; i < n; ++i) {
cin >> num;
if (!used[num]) {
cout << num << " ";
used[num] = true;
}
}
return 0;
}

You could try creating a second array of unique numbers as you go. I will demonstrate with a vector for the sake of simplicity.
std::vector<int> v;
for (int i = 0; i < n; i++) {
if (std::find(v.begin(), v.end(), arr[i]) == v.end()) {
v.push_back(arr[i]);
}
}
Then, you just write the contents of the vector to the output file.

Here is my version of O(n) complexity. Your solution may exceed time-limit ( if it is low )
bool check[2000];
for (int i = 0; i < 2000; i++) check[i] = 0;
for (int i = 0; i < n; i++) {
cin >> a[i];
// +999 to avoid negative numbers
check[a[i] + 999] = 1;
}
bool isPrint = false;
for (int i = 0; i < n; i++) {
if (check[a[i] + 999]) {
// mark false if already printed
check[a[i] + 999] = 0;
if (isPrint) printf(" ");
printf("%d", a[i]);
isPrint = true;
}
}

Related

A number K and an Array of size N is given, check whether we can get the sum of any two elements of array equal to K

I tried to solve the problem but my code still contains some bugs. Why isn't it running?
Here is the link of the question website: https://www.hackerearth.com/practice/data-structures/hash-tables/basics-of-hash-tables/practice-problems/algorithm/pair-sums/?
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int n = 1e7 + 10;
int hsh[n];
int main()
{
int n, k;
cin >> n >> k;
int A[n];
for (int i = 0; i < n; i++)
{
cin >> A[i];
}
for (int i = 0; i < n; i++)
{
hsh[A[i]] = k - A[i];
}
int t = 0;
for (int i = 0; i < n; i++)
{
if (hsh[A[i]] == k - hsh[hsh[A[i]]])
{
cout << "YES";
t = 1;
break;
}
}
if (t == 0)
{
cout << "NO";
}
return 0;
}
The problem is that while hsh[A[i]] is always valid, hsh[hsh[A[i]] is not.
Consider the following input:
1 1
10000
This does the following:
A[0] = 10000;
...
hsh[10000] = 1 - 10000; // = -99999
...
if (hsh[10000] == 1 - hsh[-99999]) {...}
So your code is reading out of bounds of the array hsh[]. Make sure you check first if hsh[A[i]] >= 0.
Note that your code is more complicated than necessary; you can do a single loop over the input to check if there is a matching pair:
#include <iostream>
static constexpr int max_k = 2e6;
static bool seen[max_k + 1];
int main()
{
int n, k;
std::cin >> n >> k;
for (int i = 0; i < n; ++i)
{
int A;
std::cin >> A;
if (A <= k && seen[k - A]) {
std::cout << "YES\n";
return 0;
}
seen[A] = true;
}
std::cout << "NO\n";
}

Why the output is not showing?

My program is to find the smallest positive number missing from an array. With the following input I expect an output of 2.
6
0
-9
1
3
-4
5
My problem is that it does not give any output. Can anyone explain this please?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int array[n];
for (int i = 0; i < n; i++)
{
cin >> array[n];
}
int const N = 1e4+2;
bool indexarray[N];
for (int i = 0; i < N; i++)
{
indexarray[i] = false;
}
for (int i = 0; i < n; i++)
{
if (array[i] > 0)
{
indexarray[array[i]] = true;
}
}
int ans = -1;
for (int i = 1; i < N; i++)
{
if (indexarray[i] == false)
{
ans = i;
}
}
cout << ans << endl;
return 0;
}
I think because int array[n]; makes an array called array with n elements in it, with the first one starting at array[0].
cin >> array[n]; needs to modify array[n], but because the first element is array[0], the last element is array[n-1], and array[n] does not exist. Your code gave an error and exited.
Try changing
for (int i = 0; i < n; i++)
{
cin >> array[n];
}
to
for (int i = 0; i < n; i++)
{
cin >> array[i];
}
Also, I think variable length arrays are non-standard, so maybe try changing that. Replace it with std::vector<int> array(n) should work.

print duplicate elements in array

I want to find duplicate elements in a dynamic array. In most cases it works, but how can it work for this case. I'm finding duplicate elements in a given array. But there is one problem that my duplicate elements can repeat too. How can I solve that part.
#include <iostream>
int main() {
unsigned n;
std::cin >> n;
int count = 0;
int* dynArr = new int[n];
for (int i = 0; i < n; i++) {
std::cin >> dynArr[i];
}
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
if(dynArr[j] == dynArr[i]){
std::cout<<dynArr[j]<<" ";
break;
}
}
}
}
I have a problem with this part. When I'm inputting a my array length 6, and elements {1,1,2,1,2,2}.
I got (1,1,2,2).
But I need to get only 1,2.
input 6
1 1 2 1 2 2
output 1 1 2 2
but must be
output 1 2
Here's a simple and fast solution.
std::map<int,size_t> element_count;
for(int i = 0; i < n; i++){
if ( ++element_count[dynArr[i]] == 2 ){
// Only report on the second occurrance
std::cout<<dynArr[j]<<" ";
}
}
const int listSize = 5;
int list1[listSize] = {0,0,1,1,3};
bool dupList[listSize] = {false};
for (int index = 0; index < listSize; index++) {
int val = list1[index];
for (int i = 0; i < listSize; i++) {
if (i != index) {
if (list1[i] == val) {
dupList[index] = true;
}
}
}
}
int printList[listSize];
int addNum = 0;
for (int index = 0; index < listSize; index++) {
if (dupList[index] == true) {
bool run = true;
int print = list1[index];
for (int i = 0; i < listSize; i++) {
if (printList[i] == print) {
run = false;
}
}
if (run == true) {
std::cout << print << " ";
printList[addNum] = print;
addNum++;
}
}
}
Note this code will NOT run quickly at all only use it if the operation does not need to get run very many times but it will only display the single numbers that are duplicates. It will defernatly need to get optimised more
You can simply get it done using two std::set<int>s.
#include <set>
#include <iostream>
int main() {
unsigned n;
std::cin >> n;
int count = 0;
std::set<int> all;
std::set<int> redundant;
for (int i = 0; i < n; i++) {
int input = 0;
std::cin >> input;
// You cant enter the entry because its present. This will return a std::pair<,> with the second value false.
if (!all.insert(input).second)
redundant.insert(input); // We store this in another set so we dont duplicate the redundant entries.
}
for (auto itr = redundant.begin(); itr != redundant.end(); itr++)
std::cout << *itr << " ";
}

How do I find the number with the most divisors in an array?

I have to input numbers into an array and at the end get the number that has the most divisors, or if there are more numbers with the same amount, print out the first one.
Example: 4 numbers, 6 12 48 108. 108 has the most divisors, so this one needs to show up. if there were numbers after 108 with the same amount of divisors, 108 would have still been the only one to show up.
#include <iostream>
using namespace std;
int main()
{
int n = 0, d, largestCnt = 0;
int cntA=0, cntB=0;
cout << "How many elements?\n";
cin >> n;
int* v = new int[n];
for(int i=0; i<n; i++)
cin >> v[i];
for(int i=0; i<n; i++){
for(d=2; d<v[i]/2; d++)
if(v[i]%d==0)
cntA++;
for(d=2; d<v[i+1]/2; d++)
if(v[i+1]%d==0)
cntB++;
if(cntA > largestCnt)
largestCnt = cntA;
if(cntB > largestCnt)
largestCnt = cntB;
}
cout << largestCnt;
return 0;
}
this is the most I've done the past 2 hours, and I can't get past it
EDIT:
#include <iostream>
using namespace std;
int main()
{
int n = 0, d;
int mostDivisors=0, number_with_most_divisors=0;
int currentDivisors = 0;
cout << "How many elements?\n";
cin >> n;
int* v = new int[n];
for(int i=0; i<n; i++)
cin >> v[i];
number_with_most_divisors = v[0];
for(d=2; d<=v[0]/2; d++){
if(v[0]%d == 0)
mostDivisors++;
}
for(int i=1; i<n; i++){
for(d=2; d<=v[i]/2; d++)
if(v[i]%d == 0)
currentDivisors++;
if(currentDivisors > mostDivisors){
mostDivisors = currentDivisors;
number_with_most_divisors = v[i];
}
}
cout << number_with_most_divisors;
return 0;
}
Here is the algorithm of what you have to do:
Count the number of divisors of the first element in array. Save this value in mostDivisors. Set number_with_most_divisors as the first element in the array.
Start from the second element in array (position 1) and for each element, count how many divisors it has, save it in currentDivisors. If currentDivisors > mostDivisors then set mostDivisors to be equal to currentDivisors and update number_with_most_divisors to be the current element in the array.
The result is number_with_most_divisors at the end of the loop.
UPDATE
You are forgetting to initialize currentDivisors for each element after the first loop:
for(int i=1; i<n; i++){
currentDivisors = 0; // You forgot to put this line!
for(d=2; d<=v[i]/2; d++)
if(v[i]%d == 0)
currentDivisors++;
if(currentDivisors > mostDivisors){
mostDivisors = currentDivisors;
number_with_most_divisors = v[i];
}
// function to count the divisors
int countDivisors(int n)
{
int cnt = 0;
for (int i = 1; i <= sqrt(n); i++) {
if (n % i == 0) {
// If divisors are equal,
// count only one
if (n / i == i)
cnt++;
else // Otherwise count both
cnt = cnt + 2;
}
}
return cnt;
}
You can loop to enter the numbers into an array
#include <iostream>
int main() {
int n = 0, max_divs = 0, count = 0, max_divs_index = 0;
std::cin >> n;
int *v = new int[n];
for (int i = 0; i < n; ++i) std::cin >> v[i];
for (int i = 0; i < n; ++i) {
count = 0; // resetting count to 0 in each iteration
for (int j = 2; j < v[i]/2; ++j)
if (v[i] % j == 0) count++; // checking if the number is divisible by numbers between 1 and number itself/2 (1 and num/2 exclusive)
if (count > max_divs) { // checking if current count is greater than the maximum divisors
max_divs = count; // updating maximum divisors
max_divs_index = i; // updating the index of array element with maximum divisors
}
}
std::cout << v[max_divs_index];
delete[] v;
return 0;
}

Google Code Jam Minimum Scalar Product

I was solving a problem from Google Code Jam and I am not able to solve the problem: http://code.google.com/codejam/contest/32016/dashboard#s=p0 (Minimum Scalar Product, Problem A 2008)
The strategy I used was:
Accept v1 and v2 from the user
Sort both v1 and v2
Reverse v2 i.e. sort v2 in descending order
Multiply straight-out corresponding v1[i] * v2[i] and store the result in product
Sum up all such products and print the answer
I did some research and indeed it appears that's the only permutation that's possible to obtain. However, my code does not produce the correct output:
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
int T;
int cases;
FILE *fin = fopen ("A-small-practice.in", "r"); // open input file
FILE *fout = fopen ("output.out", "w");
fscanf(fin, "%d", &T);
for(cases = 1; cases <= T; cases++)
{
int v1[1000], v2[1000];
int i,j; int n;
int product =0;
fscanf(fin, "%d", &n);
for(i=0; i < n; i++)
{
fscanf(fin, "%d",&v1[i]);
fscanf(fin, "%d", &v2[i]);
}
sort(v1,v1+n);
sort(v2,v2+n);
reverse(v1, v1+n);
int k;
for(k = 0; k < n; k++)
{
product += v1[k] * v2[k];
}
fprintf(fout, "Case #%d: %d\n", cases, product);
}
return 0;
}
You should use long long.
This worked for me:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
long long T,n,v1[1000],v2[1000];
cin >> T;
for (int t = 1; t <= T; t++) {
cin >> n;
for (int i = 0; i < n; i++)
cin >> v1[i];
for (int i = 0; i < n; i++)
cin >> v2[i];
sort(v1,v1+n);
sort(v2,v2+n);
long long p = 0;
for (int i = 0; i < n; i++)
p += v1[i]*v2[n-i-1];
cout << "Case #" << t << ": " << p << endl;
}
return 0;
}
After hours of troubleshooting, I found that the problem was in the way input was taken, as I had used only one loop for both v1 & v2:
for(i=0; i < n; i++)
{
fscanf(fin, "%d",&v1[i]);
fscanf(fin, "%d", &v2[i]);
}
And it should have been done this way:
for(i=0; i<n; i++)
fscanf(fin, "%d",&v1[i]);
for(i=0; i<n; i++)
fscanf(fin, "%d", &v2[i]);
Thank you lukas1994 and pkacprzak
This worked for me:
#include <algorithm>
#include <iostream>
#include <vector>
#include <numeric>
using std::vector;
long long min_dot_product(size_t n, vector<int> a, vector<int> b) {
long long result = 0;
if (n != 0)
{
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
std::reverse(a.begin(), a.end());
/*for (size_t i = 0; i < n; i++) {
result += a[i] * b[n - 1 - i];
}*/
result = std::inner_product(a.begin(), a.end(), b.begin(), 0);
}
return result;
}
int main() {
size_t n;
std::cin >> n;
vector<int> a(n), b(n);
for (size_t i = 0; i < n; i++) {
std::cin >> a[i];
}
for (size_t i = 0; i < n; i++) {
std::cin >> b[i];
}
std::cout << min_dot_product(n, a, b) << std::endl;
}
There is a specific case to be considered.
When one vector is all negative and the other all positive, the algorithm does not produce the minimum result.
if x = [-1,-2] and x = [1,2]
the minimum according to the algorithm output is :
(-1*2) + (-2*1) = -4
However, if you instead use x1y1 + x2y2... xnyn for this case you get:
(-1 * 1) + ( -2*2) = -1-4 = -5