I'm trying to create a function to remove duplicates from an unsorted int array. I have a solution that works for more examples, but it's failing with the following input:
#include<iostream>
using namespace std;
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(int j=0;j<=i;j++){
if(arr[i]==arr[j]){
n--;
for (int k=i; k<n; k++){
arr[k]=arr[k+1];
}
}
}
}
return n;
}
// Driver code
int main()
{
int arr[] = {0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1};
int n = sizeof(arr) / sizeof(arr[0]);
n = removeDuplicates(arr, n);
for (int i=0; i<n; i++)
cout << arr[i] << " ";
return 0;
}
The output for this arr example is 0 0 1 0 0 and should be 0 1.
Do you see where is the problem? Thank you
Consider using std::set<int> to record numbers you've already seen, and using a STL algorithm to perform the removal:
#include<iostream>
#include<algorithm>
#include<functional>
#include<set>
// Driver code
int main()
{
int arr[] = {0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1};
std::set<int> duplicates;
auto it = std::remove_if(std::begin(arr), std::end(arr), [&duplicates](int i) {
return !duplicates.insert(i).second;
});
size_t n = std::distance(std::begin(arr), it);
for (size_t i = 0; i < n; i++)
std::cout << arr[i] << " ";
return 0;
}
The effect of this code is that all duplicates are moved to the end of the array, and the iterator returned by std::remove_if indicates the end of the new list. So iterating between the beginning and that iterator gives you the array without the duplicates.
look over inner loop you forgot to decrement i
#include<iostream>
using namespace std;
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(int j=0;j<i;j++){
if(arr[i]==arr[j]){
n--;
for (int k=i; k<n; k++){
arr[k]=arr[k+1];
}
i--; // you forgot to decrement i
}
}
}
return n;
}
// Driver code
int main()
{
int arr[] = {0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1};
int n = sizeof(arr) / sizeof(arr[0]);
n = removeDuplicates(arr, n);
for (int i=0; i<n; i++)
cout << arr[i] << " ";
return 0;
}
In your function
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(j=i+1;j<n;)
{
if(a[i]==a[j])
{
for(int k=j;k<n-1;++k)
arr[k]=arr[k+1];
--n;
}
else
++j;
}
}
return n;
}
Increment j only when the two values do not match. Or else it will skip few values
UPDATE
A possible solution that is O(n log n) in time and requires O(m) extra space, where m is the number of unique elements in the input array:
template <typename RAIter>
size_t remove_duplicates(RAIter first, RAIter last) {
using value_type = typename std::iterator_traits<RAIter>::value_type;
std::map<value_type, size_t> map;
size_t n = 0;
for (auto it = first; it != last; ++it) {
auto & temp = map[*it];
if (temp == 0) temp = ++n;
}
for (auto & e : map)
*(first + e.second - 1) = e.first;
return n;
}
Note also that the contents of the original array is destroyed here, but this is in your attempt as well.
Possible usage:
int main() {
static constexpr size_t n = 26;
std::array<int, n> a = { 0, 0, 1, 0, 3, 2, 1, 1, 0, 1, 0, 0, 2, 2, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1 };
size_t m = remove_duplicates(std::begin(a), std::end(a));
for (size_t i = 0; i < m; i++)
std::cout << a[i] << " ";
std::cout << std::endl;
}
Which prints out 0 1 3 2.
I compared my solution with yours (corrected by #Onk_r). For an input array of 500,000 elements having random values from [0,100). My O(n log n) solution took 19 milliseconds, while your O(n3) solution took 54 seconds! Nice demonstration of how much complexity matters :).
It works, but you have to start with j=1, not 0
wrong:
for (int i=0; i < n; i++){
for(int j=0;j<=i;j++)
solution:
for (int i=0; i < n; i++){
for(int j=1;j<=i;j++){
int arr1[] = {3, 1, 5, 4, 5, 1, 9, 3, 9, 7};
int size = sizeof(arr1) / sizeof(arr1[0]);
int i, j, k = 0;
int arr2[size];
for(i = 0; i < size; i++)
{
for(j = 0; j < k; j++)
{
if(arr1[i] == arr2[j])
{
break;
}
}
if(j == k)
{
arr2[k++] = arr1[i];
}
}
Use a set instead since all elements in a set must be unique. http://www.cplusplus.com/reference/set/set/
Related
I wrote the below code for merge sort but it's not working, And I am unable to find out problem!
Every time the output becomes same as input, I think that problem may occur due to vector reference.
I think mergeSort is not creating a new vector for sub array. But I am still confused.
input vector: 5, 4, 3, 2, 1
output: 5, 4, 3, 2, 1
Req output: 1, 2, 3, 4, 5
#include <iostream>
#include <vector>
using namespace std;
void merge(vector<int> &la, vector<int> &ra, vector<int> &A) {
int i = 0, j = 0, k = 0;
// overwriting A using its solved sub arrays i.e la, ra
while (i < la.size() && j < ra.size()) {
if (la[i] <= ra[j]) {
A[k] = la[i];
i++;
k++;
} else {
A[k] = ra[j];
j++;
k++;
}
}
// if any subarray left then
while (i < la.size()) {
A[k] = la[i];
k++;
i++;
}
while (j < ra.size()) {
A[k] = ra[j];
k++;
j++;
}
}
mergeSort function:
void mergeSort(vector<int> &A) {
if (A.size() < 2)
return;
int len = A.size();
vector<int> la, ra;
for (int i = 0; i < len / 2; i++)
la.push_back(A[i]);
for (int i = len / 2; i < len; i++)
ra.push_back(A[i]);
// dividing the proble into subproblem
mergeSort(la);
mergeSort(ra);
// merging the solved subproblem
merge(la, ra, A);
}
Driver function:
int main(void) {
int arr[] = { 5, 4, 3, 2, 1 };
vector<int> A(arr, arr + 5);
for (int i = 0; i < A.size(); i++)
cout << A[i] << " ";
cout << endl;
mergeSort(A);
for (int i = 0; i < A.size(); i++)
cout << A[i] << " ";
return 0;
}
The code posted does not seem to have a problem.
Executing it produces the expected output: 1 2 3 4 5, so there is something else going on that could cause your observations: you might be running an executable produced by a previous or at least different version of the code.
I am working on a matrix inverter and I have it almost done but for some reason the function that is supposed to raise the matrix to a certain value is not working, I have isolated the function on its own and it has worked just fine. But for some reason is not working in this program
Isolated
#include <iomanip>
#include <stdio.h>
using namespace std;
void printano(double a[3][3])
{
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
cout << fixed << setprecision(2) << setw(12) << a[i][j] << " ";
cout << endl;
}
}
void powernator(double r[][3],double B[][3], int p)
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
int main()
{
double B[3][3] = { {1, 2, 3} , {4, 5, 6} , {7, 8, 9} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
powernator(r,B,3);
printano(r);
}
The actual code
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdio.h>
using namespace std;
void multiplinator(double x[][3], double y[][3], double z[][3]) //At the end I double check to make sure the value is correct as it needs to equal the identity matrix
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 3; k++)
{
z[i][j] += x[i][k] * y[k][j];
}
}
}
}
void printinator(double a[3][3]) //prints a matrix
{
for(int i=0; i<=2; i++)
{
for(int j=0; j<=2; j++)
cout << fixed << setprecision(4) << setw(12) << a[i][j] << " ";
cout << endl;
}
cout << endl;
}
void sub(double as[3][3], double in[][3], double B[][3]) //Matrix subtraction
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
B[i][j] = in[i][j] - as[i][j];
}
void powernator(double r[][3],double B[][3], int p) //Array which is supposed to raise a matrix to a certain power
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
void gettem(double r[][3], double in[][3], double inm[][3]) //Supposed to return the final value, aka, the inverse matrix, as a^-1 = I + B^1 +B^2...
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
inm[i][j] = in[i][j] + r[i][j];
}
}
int main()
{
double a[3][3] = { {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double as[3][3] ={ {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double in[3][3] = { {1, 0, 0} , {0, 1, 0} , {0, 0, 1} };
double B[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double inm[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double z[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
cout << "\n\t\t Original : " << endl;
printinator(a);
sub(as,in,B);
printinator(B);
powernator(r,B,2);
printinator(r); //testing the power function, not working
/*for(int n = 0; n < 20; n++) //Final part of the code commented out for debug, this loop is meant to add up B^n where n is from 1 - 20
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
r[i][j] += B[i][j];
}
gettem(r,in,inm);
cout << "\n\t\t Inverse: " << endl;
printinator(inm);
multiplinator(as,a,z);
cout << "\n\t\t multi: " << endl;
printinator(z);
*/
}
Isolated Code
powernator(r,B,3);
Actual Code.
powernator(r,B,2);
parameter p is differ..
I have 2 arrays:
arr1 = [0, 1, 2, 3, 4, 5, 6]
arr2 = [0, 1, 3, 3, 4, 6]
I'm trying to write a function to compare the two arrays and make a new array with the missing numbers.
I tried this for loop but it didn't print out anything. What other ways can I compare 2 arrays of different sizes?
int n = 0;
int *newArr = new int[];
for (int i = 0; i<=6; i++) {
if (arr1[i] != arr2[i]) {
newArr[n] = arr1[i]
n++;
}
}
for (int j = 0; j<n; j++) {
cout << arr[j] << endl;
}
I'm trying to write a function to compare the two arrays and make a
new array with the missing numbers.
You can use a range-based for loop and std::find to check both arrays for the missing numbers
And then store the result in a std::set
Example
int main()
{
int a[] { 0, 1, 2, 3, 4, 5, 6 };
int b[] { 0, 1, 3, 3, 4, 6 };
std::set<int> c;
for (auto const& i : a)
if (std::find(std::begin(b), std::end(b), i) == std::end(b))
c.insert(i);
for (auto const& i : b)
if (std::find(std::begin(a), std::end(a), i) == std::end(a))
c.insert(i);
}
or using a regular for loop
for (auto it = std::begin(a); it != std::end(a); ++it)
if (std::find(std::begin(b), std::end(b), *it) == std::end(b))
c.insert(*it);
Try something like this:
int arr1[] = {0, 1, 2, 3, 4, 5, 6};
int size_arr1 = 7;
int arr2[] = {0, 1, 3, 3, 4, 6};
int size_arr2 = 6;
int *newArr = new int[size_arr1 + size_arr2];
int n = 0;
for (int i = 0; i < size_arr1; i++) {
newArr[n++] = arr1[i];
}
for (int i = 0; i < size_arr2; i++) {
bool found = false;
for (int j = 0; j < n; j++) {
if (arr2[i] == newArr2[j]) {
found = true;
break;
}
}
if (!found)
newArr[n++] = arr1[i];
}
for (int i = 0; i < n; i++) {
cout << newArr[i] << endl;
}
delete[] newArr;
Another way to collect unique numbers from both arrays is to use a std::set or std::unsorted_set instead, eg:
#include <unordered_set>
int arr1[] = {0, 1, 2, 3, 4, 5, 6};
int arr2[] = {0, 1, 3, 3, 4, 6};
set::unsorted_set newArr;
for(int num : arr1) {
newArr.insert(num);
}
for(int num : arr2) {
newArr.insert(num);
}
for (int num : newArr) {
std:: cout << num << endl;
}
You've declared the arrays dynamically in your code (i.e. on the heap) and initializing them with numbers isn't as straight forward. You are also allocating an array of 0 size. If you declare your arrays on the stack then you can achieve what you want to do with a nested for loop.
Take note though that for large datasets this would be inefficient. If you're curious research binary search algorithms.
#include <iostream>
int main()
{
int arr1Size = 6;
int arr2Size = 8;
int arr1[] = { 2, 5, 7, 12, 45, 65 };
int arr2[] = { 2, 5, 6, 10, 32, 65, 98, 123 };
for (int i = 0; i < arr1Size; i++)
{
for (int j = 0; j < arr2Size; j++)
{
if (arr1[i] == arr2[j])
{
std::cout << arr1[i] << std::endl;
}
}
}
}
char ToByte(bool b[8])
{
char c = 0;
int j = 0;
for (int i = 7; i >= 0; i--) {
if (b[j]) {
c |= 1 << i;
}
j++;
}
return c;
}
This function converts from bool to char
int main() {
int number = 979899101;
bitset<32> byte4= number;
cout << byte4 << endl;;
bitset<8> byte;
char op[4];
for (int i = 3; i >= 0; i--) {
for (int j = 0; j < 8; ++j)
byte[j] = byte4[i * 8 + j];
cout << byte;
bool var[8];
for (int j = 0; j < 7; ++j)
var[j] = byte[j];
op[i]=ToByte(var);
}
cout << op;
}
I'm trying to get convertion from integer to char array but I'm getting bad result. like ╗I↨]╠╠╠╠╠╠╠╠Ţ I don't know what I'm doing wrong.
Your function that converts bool array to char works correctly.
Try this:
bool a[] = {0, 1, 1, 0, 0, 0, 0, 1}; //97
bool b[] = {0, 1, 1, 0, 0, 0, 1, 0}; //98
bool c[] = {0, 1, 1, 0, 0, 0, 1, 1}; //99
bool d[] = {0, 1, 1, 0, 0, 1, 0, 0}; //100
cout << ToByte(a) << ToByte(b) << ToByte(c) << ToByte(d) << endl;
So you need to decide, how to split big number (979899101) into pieces (bitset<8> byte), because your code in main() do is not what you expect.
It splits the long number 00111010011010000001001011011101 into 58(00111010), 104(01101000), 18(00010010) and 221(11011101)
off topic: sorry for my broken English, this isn't my native language.
For any given n, I need to create a vector of vectors of length n std::vector<std::vector<int>>, containing all possible combinations of -1 and +1. For example, for n=3 I need
std::vector<std::vector<int>> v = {
{ 1, 1, 1},
{ 1, 1, -1},
{ 1, -1, 1},
{ 1, -1, -1},
{-1, 1, 1},
{-1, 1, -1},
{-1, -1, 1},
{-1, -1, -1}
};
Any hints?
Simple solution using the binary representation, and testing the bit value. I used std::bitset although you can also use the simple C-Style bit manipulations.
#include <bitset>
int main(){
int n=3;
int to = pow(2,n);
std::vector<std::vector<int>> result;
for (int i=0; i < to; i++){
std::bitset<32> b(i);
std::vector<int> vec1;
for (int j=0; j < n; j++){
int value = b.test(j) ? 1 : -1;
vec1.push_back(value);
}
result.push_back(vec1);
}
// Printing out result
for (auto& vec : result){
for (auto val : vec){
cout << val;
}
cout << endl;
}
}
Test Example
For larger values of (n), you might want to improve the efficiency:
std::vector<std::vector<int>> v;
v.reserve(1 << n);
for (unsigned int i = 0; i < (1 << n); i++)
{
std::vector<int> vi (n, 0);
for (unsigned int j = 0; j < n; j++)
vi[n - 1 - j] = (i & (1 << j)) ? (-1) : (+1);
v.push_back(vi);
}
I'm sure someone can come up with a template meta-program that can construct (v) at compile-time for a constant (n).
Following #sascha's suggestion, here's a method that appends +-1 to a given set of lists.
#include <vector>
#include <iostream>
std::vector<std::vector<int>>
append_plus_minus(const std::vector<std::vector<int>> & in)
{
auto out = in;
out.insert(out.end(), in.begin(), in.end());
for (std::size_t i=0; i < in.size(); i++) {
out[i].push_back(+1);
out[i+in.size()].push_back(-1);
}
return out;
}
int main() {
const int n = 5;
std::vector<std::vector<int>> b_combinations = {{}};
for (std::size_t i=0; i < n; i++) {
b_combinations = append_plus_minus(b_combinations);
}
for (std::size_t i=0; i < b_combinations.size(); i++) {
for (std::size_t j=0; j < b_combinations[i].size(); j++) {
std::cout << b_combinations[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}