Determine duplicates/pairs in an array in C++ - c++

I have been doing this problem for 2 days now, and I still can't figure out how to do this properly.
In this program, I have to input the number of sticks available (let's say 5). Then, the user will be asked to input the lengths of each stick (space-separated integer). Let's say the lengths of each stick respectively are [4, 4, 3, 3, 4]. Now, I have to determine if there are pairs (2 sticks of same length). In this case, we have 2 (4,4 and 3,3). Since there are 2 pairs, we can create a canvas (a canvas has a total of 2 pairs of sticks as the frame). Now, I don't know exactly how to determine how many "pairs" there are in an array. I would like to ask for your help and guidance. Just note that I am a beginner. I might not understand complex processes. So, if there is a simple (or something that a beginner can understand) way to do it, it would be great. It's just that I don't want to put something in my code that I don't fully comprehend. Thank you!
Attached here is the link to the problem itself.
https://codeforces.com/problemset/problem/127/B
Here is my code (without the process that determines the number of pairs)
#include<iostream>
#include<cmath>
#define MAX 100
int lookForPairs(int numberOfSticks);
int main(void){
int numberOfSticks = 0, maxNumOfFrames = 0;
std::cin >> numberOfSticks;
maxNumOfFrames = lookForPairs(numberOfSticks);
std::cout << maxNumOfFrames << std::endl;
return 0;
}
int lookForPairs(int numberOfSticks){
int lengths[MAX], pairs = 0, count = 0, canvas = 0;
for(int i=0; i<numberOfSticks; i++){
std::cin >> lengths[i];
}
pairs = floor(count/2);
canvas = floor(pairs/2);
return count;
}
I tried doing it like this, but it was flawed. It wouldn't work when there were 3 or more integers of the same number (for ex. [4, 4, 3, 4, 2] or [5. 5. 5. 5. 6]). On the first array, the count would be 6 when it should only be 3 since there are only three 4s.
for(int i=0; i<numberOfSticks; i++){
for (int j=0; j<numberOfSticks; j++){
if (lengths[i] == lengths[j] && i!=j)
count++;
}
}

Instead of storing all the lengths and then comparing them, count how many there are of each length directly.
These values are known to be positive and at most 100, so you can use an int[100] array for this as well:
int counts[MAX] = {}; // Initialize array to all zeros.
for(int i = 0; i < numberOfSticks; i++) {
int length = 0;
std::cin >> length;
counts[length-1] += 1; // Adjust for zero-based indexing.
}
Then count them:
int pairs = 0;
for(int i = 0; i < MAX; i++) {
pairs += counts[i] / 2;
}
and then you have the answer:
return pairs;

Just an extension to molbdnilo's answer: You can even count all pairs in one single iteration:
for(int i = 0; i < numberOfSticks; ++i)
{
if(std::cin >> length) // catch invalid input!
{
pairs += flags[length] == 1; // add a pair if there is already a stick
flags[length] ^= 1; // toggle between 0 and 1...
}
else
{
// some appropriate error handling
}
}
Note that I skipped subtracting 1 from the length – which requires the array being one larger in length (but now it can be of smallest type available, i.e. char), while index 0 just serves as an unused sentinel. This variant would even allow to use bitmaps for storing the flags, though questionable if, with a maximum length that small, all this bit fiddling would be worth it…

You can count the number of occurrences using a map. It seems that you are not allowed to use a standard map. Since the size of a stick is limited to 100, according to the link you provided, you can use an array, m of 101 items (stick's minimum size is 1, maximum size is 100). The element index is the size of the stick. The element value is the number of sticks. That is, m[a[i]] is the number of sticks of size a[i]. Demo.
#define MAX 100
int n = 7;
int a[MAX] = { 1,2,3,4,1,2,3 };
int m[MAX + 1]; // maps stick len to number of sticks
void count()
{
for (int i = 0; i < n; ++i)
m[a[i]]++;
}
int main()
{
count();
for (int i = 1; i < MAX + 1; ++i)
if (m[i])
std::cout << i << "->" << m[i] << std::endl;
}

Your inner loop is counting forward from the very beginning each time, making you overcount the items in your array. Count forward from i , not zero.
for(int i=0; i<numberOfSticks; i++)
{
for (int j=i; j<numberOfSticks; j++) { // count forward from i (not zero)
if (lengths[i] == lengths[j] && i!=j)
{ // enclosing your blocks in curly braces , even if only one line, is easier to read
count++; // you'll want to store this value somewhere along with the 'length'. perhaps a map?
}
}
}

Related

randomly reorder elements in an array without duplication

I have a fixed array of sized nine and I am trying to reorder it randomly without duplication.
this is the following code:
class numbers{
int randomIndexCount;
public:
void randomArray( int numArray[],int size){
randomIndexCount = 0;
for (int i = 0; i < size; i++)
{
int RandomIndex = rand() % size;
randomIndexCount++;
numArray[i] = numArray[RandomIndex];
cout << numArray[i] <<endl;
}
}
int main(){
srand(time(0));
int numArray[9]= {1,2,3,4,5,6,0,0,0};
numbers n;
n.randomArray(numArray,9);
return 0;
}
So far I was able to reorder the array randomly with the given elements however I am unsure how to get rid of duplication. the output should be {1,2,3,4,5,6,0,0,0} but in a random order.
I am unable to use the shuffle function and can only use rand.
I am not sure how to remove duplicate entries
this is what I had in mind
1) with the given index check if that value already exist and if it does then skip this line " numArray[i] = numArray[RandomIndex];". however this approach would not be efficient as im sure this would be too time consuming.
is there a way to remove duplicate values so my output is something like:
{0,1,0,6,2,0,5,3,4}
You should swap elements in this line numArray[i] = numArray[RandomIndex];, not assigning. This will duplicate data! Here's the swap:
int v = numArray[i];
numArray[i] = numArray[RandomIndex];
numArray[RandomIndex] = v;
You are duplicating the elements with the assignement inside the for loop
numArray[i] = numArray[RandomIndex]
Instead asign the element to the position of the array, you need to swap those elements as follow:
class numbers
{
int randomIndexCount;
public:
void randomArray (int numArray[], int size)
{
randomIndexCount = 0;
// Use srand with a time seed value in order to
// have different results in each run of the programm
srand (time (NULL));
for (int i = 0; i < size - 1; i++)
{
int swap = numArray[i];
//take a random index from 0 to i
int j = rand () % (size);
numArray[i] = numArray[j];
numArray[j] = swap;
cout << numArray[i] << endl;
}
}
};
int main ()
{
int numArray[9] = { 1, 2, 3, 4, 5, 6, 0, 0, 0 };
numbers n;
n.randomArray (numArray, 9);
return 0;
}
This will be the output that includes all then numbers in the array:
5
2
0
6
3
0
1
0
This loop scans positions from the end of the array towards its beginning and randomly selects a new item to be put at the current position. Items are chosen from positions not scanned yet.
This way every place is exactly once chosen to be filled with some item, and each item is exactly once placed in its final position (although, before this happens, it may be several times swapped out of places chosen for other elements).
It also guarantees no item disappears (gets overwritten) and no duplicates appear (no item is copied inadvertently) - if you have duplicates in input data, the same duplicates remain in the output (although permuted); if there are no duplicates, there will be no duplicates.
Additionally, if the rand() function has no bias, every item has the same chance to end at any chosen position, hence each possible permutation is equally probable as an output.
for (int i = size; i > 1; -- i)
{
int swapIndex = rand() % i;
int swap = numArray[swapIndex];
numArray[swapIndex] = numArray[i-1];
numArray[i-1] = swap;
}

Did a competitive-like problem right but need help on improving its efficiency

The problem is simple. I'm given N - the number of digits in a number and then N digits of a number. I need to do exactly one digit-switch and get the highest number possible. I did do the problem right (as in gives out the right number) but it will be hitting the 1 second time restriction afaik. How do I improve on the efficiency of my program so it would go under the 1 second time restriction with N <= 10^6. New on Stack overflow so tell me if I did something wrong
with asking the question so I can fix it. Thanks. Here's my solution:
main:
int n;
cin >> n;
int a[n+1];
for(int i=0;i<n;++i)
cin >> a[i];
int maxofarray1;
bool changeHappened=false;
bool thereAreTwoSame=false;
for(int i=0;i<n;++i) //changing the two digits to make the highest number if possible
{
maxofarray1=maxofarray(a,i+1,n);
if(a[i]<maxofarray1)
{
int temp=a[a[n]];
a[a[n]]=a[i];
a[i]=temp;
changeHappened = true;
break;
}
}
for(int i=0;i<n;++i) //need to check if there are two of the same digit so I can change
//those two making the number the same instead of making it lower
for(int j=i+1;j<n;++j)
if(a[i]==a[j])
{
thereAreTwoSame=true;
break;
}
if(!changeHappened) //if the change has not been yet made, either leaving the number as is
//(changing two same numbers) or changing the last two to do as little "damage" to the number
{
if(!thereAreTwoSame)
{
int temp=a[n-1];
a[n-1]=a[n-2];
a[n-2]=temp;
}
}
for(int i=0;i<n;++i)
cout << a[i] << " ";
return 0;
maxofarray:
int maxofarray(int a[], int i,int n) //finding the maximum of the array from i to n
{
int max1=0;
int maxind;
for(int j=i;j<n;++j)
{
if(max1<a[j])
{
max1=a[j];
maxind=j;
}
}
a[n]=maxind; //can't return both the index and maximum (without complicating with structs)
//so I add it as the last element
return max1;
}
The problem in your code is complexity. I didn't fully understand your algorithm, but having nested loops is a red flag. Instead of trying to improve bits and pieces of your code you should rather rethink your overall strategy.
Lets start by assuming the digit 9 does appear in the number. Consider the number is
9...9 c ...9...
where 9...9 are the leading digits that are all 9 (possibly there are none of them). We cannot make the number bigger by swapping one of those.
c is the first digits !=9, ie its the place where we can put a 9 to get a bigger number. 9 is the digit that will make the number maximum when put in this place.
Last, ...9... denotes the last appearance of the digit 9 and digits sourrinding that. After that 9 no other 9 appears. While we increase the number by replacing c, the number will get smaller be replacing that 9, hence we have to choose the very last one.
For the general case only a tiny step more is needed. Here is a rough sketch:
std::array<size_t,10> first_non_appearance;
std::array<size_t,10> last_appearance;
size_t n;
std::cin >> n;
std::vector<int> number(n);
for (size_t i=0;i <n;++i) {
std::cin >> a[i];
for (int d=0;d<10;++d) {
// keep track of first and last appearance of each digit
}
}
size_t first = 0;
size_t second = 0;
for (int d=0;d<10;++d) {
// determine biggest digit that appeared and use that
}
std:swap( a[first],a[last] );
It is not complete, perhaps requires handling of special cases (eg number with only one digit), but I hope it helps.
PS: You are using a variable length array (int a[n+1];), this is not standard C++. In C++ you should rather use a std::vector when you know the size only at runtime (and a std::array when the size is known).
VLA (variable length arrays) are not standard. So instead of using this nonstandard feature, you might want to use a STL data type.
Given N is rather big, you also avoid stack overflow, given that VLA are allocated on the stack. And STL containers with variable length allocate on the heap.
Then, as you pointed out yourself, it makes sense to remember the index of the last occurrence of each digit, avoiding to search over and over again for a swap candidate index.
Your implementation idea is basically, to replace the first digit from the left, which has a bigger replacement to the right of it.
This is how I did it:
static void BigSwap(std::string& digits)
{
int64_t fromRight[10];
size_t ndigitsFound = 0;
for (size_t i = 0; i < 10; i++)
fromRight[i] = -1;
size_t i = digits.size() - 1;
while (ndigitsFound < 10 && i > 0)
{
if (-1 == fromRight[digits[i] - '0'])
{
fromRight[digits[i] - '0'] = static_cast<int64_t>(i);
ndigitsFound++;
}
i--;
}
for (size_t j = 0; j < digits.size(); j++)
{
char d = digits[j] - '0';
for (char k = 9; k > d; k--)
{
if (fromRight[k] != -1 && static_cast<size_t>(fromRight[k]) > j)
{
auto temp = digits[j];
digits[j] = k + '0';
digits[fromRight[k]] = temp;
return;
}
}
}
}

Distinct numbers in array

I have no idea what to do. Please help me with code or tell me what textbook to look up or something; I need code to finish this program and I would love an explanation of what I'm looking at..
#include<iostream>
using namespace std;
int main()
{
short num[100], size, //declare an array of type short that has 100 elements
unique[100], number, // declare a second array to help solve the problem; number counts the number of unique values
k; // loop control variable; may need other variables
cout<<"enter the number of values to store in the array\n";
cin>>size;
cout<<”enter the “<<size<<” values to be used as data for this program\n”;
for(k=0; k<size; k++)
cin>>num[k];
// print the contents of the array
cout<<"\nthere are "<<size<<" values in the array\n";
for(k=0; k<size; k++)
cout<<num[k]<<’ ‘; // there is one space between each number in the display
cout<<endl; // cursor moved to next output line
cout<<"the program will count the number of different (distinct) values found in the array\n";
//************************************************************
//Put the code here that counts the number of unique values stored in the
//array num. The variable number will contain the count.
//************************************************************
cout<<endl<<number<<" unique values were found in the "<<size<<" element array\n";
// pause the program to see the results
system("pause");
//return 0;
}
I have to do one of these two things and I don't know what they mean?
Algorithm – unique array is used to help find the solution, used to avoid counting any value more than one time
Set number to 0 - this represents the number of distinct values in the data set; also used as a subscript in the unique array
Loop from 0 to size by one, proceeding through successive elements of the data (num) array
Store value of current array element in non-array variable (SV)
Set event_flag to 0
Loop from 0 to number by one, proceeding through successive elements of unique array
If SV is equal to current element of unique array
Set event_flag to 1
Break (stop) inner loop
End of inner loop
If event_flag is equal to 0 (value not found in unique array and not previously counted)
Store SV in element number of unique array
Increment the value of number
End of outer loop
Solution – the variable number contains the count of distinct values in the data array
Alternate Algorithm
Algorithm that does not use the event_flag (loop control variable can be used to determine if event occurred)
Algorithm – unique array is used to help find the solution, used to avoid counting any value more than one time
Set number to 0 - this represents the number of distinct values in the data set; also used as a subscript in the unique array
Loop from 0 to size by one, proceeding through successive elements of the data (num) array
Store value of current array element in non-array variable (SV)
Loop from 0 to number by one, proceeding through successive elements of unique array
If SV is equal to current element of unique array
Break (stop) inner loop
End of inner loop
If loop control variable of inner loop is equal to value of number (SV not found in unique array and not previously counted)
Store SV in element number of unique array
Increment the value of number
End of outer loop
Solution – the variable number contains the count of distinct values in the data array
I put this in mine:
//************************************************************
//Put the code here that counts the number of unique values stored in the array num. The variable number will contain the count.
for(k=0; k<size; k++)
num=SV;
event_flag=0;
for(k=1; k<number; k++)
if(SV=unique)
return true;
return false;
//************************************************************
It's not working, obviously.
This is my code, it seems to work
//************************************************************
//Put the code here that counts the number of unique values
//stored in the array num. The variable number will contain the count.
number = 0;
for (k = 0; k < size; ++k)
{
short sv = num[k];
short event_flag = 0;
for (int i = 0; i < number; ++i)
{
if (sv == unique[i])
{
event_flag = 1;
break;
}
}
if (event_flag == 0)
{
unique[number] = sv;
++number;
}
}
For the alternative ,
his is my code, it seems to work
//************************************************************
//Put the code here that counts the number of unique values
//stored in the array num. The variable number will contain the count.
number = 0;
for (k = 0; k < size; ++k)
{
short sv = num[k];
int i;
for (i = 0; i < number; ++i)
if (sv == unique[i])
break;
if (number == i)
{
unique[number] = sv;
++number;
}
}
You are roughly asked to do the following:
#include <iostream>
using namespace std;
int main()
{
// This is the given array.
int given_array[5] = { 1, 1, 2, 2, 3 };
// This is the array where unique values will be stored.
int unique_array[5];
// This index is used to keep track of the size
// (different from capacity) of unique_array.
int unique_index = 0;
// This is used to determine whether we can
// insert an element into unique_array or not.
bool can_insert;
// This loop traverses given_array.
for (int i = 0; i < 5; ++i)
{
// Initially assume that we can insert elements
// into unique_array, unless told otherwise.
can_insert = true;
// This loop traverses unique_array.
for (int j = 0; j < unique_index; ++j)
{
// If the element is already in unique_array,
// then don't insert it again.
if (unique_array[j] == given_array[i])
{
can_insert = false;
break;
}
}
// This is the actual inserting.
if (can_insert)
{
unique_array[unique_index] = given_array[i];
unique_index++;
}
}
// Tell us how many elements are unique.
cout << unique_index;
return 0;
}
Try out this one...
You can insert cout statements wherever required.
#include <iostream>
using namespace std;
int main()
{
int Input[100], Unique[100], InSize, UniLength = 0;
cin >> InSize;
for (int ii = 0 ; ii < InSize ; ii++ )
{
cin >> Input[ii];
}
Unique[0] = Input[0];
UniLength++;
bool IsUnique;
for ( int ii = 1 ; ii < InSize ; ii++ )
{
IsUnique=true;
for (int jj = 0 ; jj < UniLength ; jj++ )
{
if ( Input[ii] == Unique[jj] )
{
IsUnique=false;
break;
}
}
if ( IsUnique )
{
Unique[UniLength] = Input[ii];
UniLength++;
}
}
cout<<"We've "<<UniLength<<" Unique elements and We're printing them"<<endl;
for ( int jj = 0 ; jj < UniLength ; jj++ )
{
cout << Unique[jj] << " ";
}
}
I hope this is what you were looking for.....
Have a nice day.
Here is my approach. Hope so it will helpful.
#include<iostream>
#include<algorithm>
int main(){
int arr[] = {3, 2, 3, 4, 1, 5, 5, 5};
int len = sizeof(arr) / sizeof(*arr); // Finding length of array
std::sort(arr, arr+len);
int unique_elements = std::unique(arr, arr+len) - arr;
std::cout << unique_elements << '\n'; // The output will 5
return 0;
}

Sorting two arrays into a combined array

I haven't done any programming classes for a few years, so please forgive any beginner mistakes/methods of doing something. I'd love suggestions for the future. With the code below, I'm trying to check the values of two arrays (sorted already) and put them into a combined array. My solution, however inefficient/sloppy, is to use a for loop to compare the contents of each array's index at j, then assign the lower value to index i of the combinedArray and the higher value to index i+1. I increment i by 2 to avoid overwriting the previous loop's indexes.
int sortedArray1 [5] = {11, 33, 55, 77, 99};
int sortedArray2 [5] = {22, 44, 66, 88, 00};
combinedSize = 10;
int *combinedArray;
combinedArray = new int[combinedSize];
for(int i = 0; i <= combinedSize; i+=2)
{
for(int j = 0; j <= 5; j++)
{
if(sortedArray1[j] < sortedArray2[j])
{
combinedArray[i] = sortedArray1[j];
combinedArray[i+1] = sortedArray2[j];
}
else if(sortedArray1[j] > sortedArray2[j])
{
combinedArray[i] = sortedArray2[j];
combinedArray[i+1] = sortedArray1[j];
}
else if(sortedArray1[j] = sortedArray2[j])
{
combinedArray[i] = sortedArray1[j];
combinedArray[i+1] = sortedArray2[j];
}
}
}
for(int i = 0; i < combinedSize; i++)
{
cout << combinedArray[i];
cout << " ";
}
And my result is this
Sorted Array 1 contents: 11 33 55 77 99
Sorted Array 2 contents: 0 22 44 66 88
5 77 5 77 5 77 5 77 5 77 Press any key to continue . . .
In my inexperienced mind, the implementation of the sorting looks good, so I'm not sure why I'm getting this bad output. Advice would be fantastic.
what about this:
int i=0,j=0,k=0;
while(i<5 && j<5)
{
if(sortedArray1[i] < sortedArray2[j])
{
combinedArray[k]=sortedArray1[i];
i++;
}
else
{
combinedArray[k]=sortedArray2[j];
j++;
}
k++;
}
while(i<5)
{
combinedArray[k]=sortedArray1[i];
i++;k++;
}
while(j<5)
{
combinedArray[k]=sortedArray2[j];
j++; k++;
}
Firstly, there are some immediate problems with how you use C++:
You use = instead of == for equality check (hence causing undesired value assignments and the if-condition to return true when it shouldn't);
Your outer loops upper boundary is defined as i <= 10, while the correct boundary check would be i < 10;
You have a memory leak at the end of the function because you fail to de-allocate memory. You need a delete [] combinedArray at the end.
Secondly, your outer loop iterates through all values of the destination array, and in each step uses an inner loop to iterate through all values of the source arrays. That is not what you want. What you want is one loop counting from j=0 to j<5 and iterating through the source arrays. The positions in the destination array are then determined as 2*j and 2*j+1, and there is no need for an inner loop.
Thirdly, as explained in the comment, a correct implementation of sorted-list merge needs two independent counters j1 and j2. However, your current input is hardwired into the code, and if you replace 00 with 100, your current algorithm (after the corrections above are made) will actually work for the given input.
Finally, but less importantly, I wonder why your destination array is allocated on the heap using new. As long as you are dealing with small arrays, you may allocate it on the stack just like the source arrays. If, however, you allocate it on the heap, better use a std::unique_ptr<>, possibly combined with std::array<>. You'll get de-allocation for free then without having to think of putting a delete [] statement at the end of the function.
Before even looking at the implementation, check the algorithm and write it down with pen and paper. The first thing that pops is that you are assuming that the first two elements in the result will come one from each source array. That need not be the case, consider two arrays where all elements in one are smaller than all elements in the other and the expected result:
int a[] = { 1, 2, 3 };
int b[] = { 4, 5, 6 };
If you want the result sorted, then the first three elements come all from the first array. With that in mind think on what you really know about the data. In particular, both arrays are sorted, which means that the first elements will be smaller than the rest of the elements in the respective array. The implication of this is that the smaller element is the smaller of the heads. By putting that element into the result you have reduced the problem to a smaller set. You have a' = { 2, 3 }, b = { 4, 5, 6 } and res = { 1 } and a new problem that is finding the second element of res knowing that a' and b are sorted.
Figure out in paper what you need to do, then it should be straight forward to map that to code.
So, I modified your code to make it work. Actually it would be good idea to have two pointer/index for two sorted arrays. So that you can update your corresponding pointer after adding it to your combinedArray. Let me know if you don't understand any part of this code. Thanks.
int sortedArray1 [5] = {11, 33, 55, 77, 99};
int sortedArray2 [5] = {0, 22, 44, 66, 88};
int combinedSize = 10;
int *combinedArray;
combinedArray = new int[combinedSize];
int j = 0;
int k = 0;
for(int i = 0; i < combinedSize; i++)
{
if (j < 5 && k < 5) {
if (sortedArray1[j] < sortedArray2[k]) {
combinedArray[i] = sortedArray1[j];
j++;
} else {
combinedArray[i] = sortedArray2[k];
k++;
}
}
else if (j < 5) {
combinedArray[i] = sortedArray1[j];
j++;
}
else {
combinedArray[i] = sortedArray2[k];
k++;
}
}
for(int i = 0; i < combinedSize; i++)
{
cout << combinedArray[i];
cout << " ";
}
cout<<endl;
The else if(sortedArray1[j] = sortedArray2[j]), did you mean else if(sortedArray1[j] == sortedArray2[j])?
The former one will assign the value of sortedArray2[j] to sortedArray1[j] -- and that's the reason that why you get 5 77 5 77...
But where's the 5 come from? There's no 5 in either sortedArray, yet I find for(int j = 0; j <= 5; j++) must be something wrong. The highest index of a size N array is N-1 rather than N in C/C++(but not in Basic).. so use j<5 as the condition, or you may fall into some situation which is hard to explain or predict..
After all, there's problem in your algorithm itself, every time the outer loop loops, it will at last compare the last elements in the two arrays, which makes the output to repeat two numbers.
So you need to correct your algorithm too, see Merge Sort.
Slightly different approach, which is IMHO a bit cleaner:
//A is the first array, m its length
//B is the second array, n its length
printSortedAndMerged(int A[], int m, int B[], int n){
int c[n+m];
int i=0, j=0;
for(int k=0; k < n+m; k++){
if(i < m && j < n){
if(A[i] < B[j]){
c[k] = A[i];
i++;
}
else{
c[k] = B[j];
j++;
}
continue; //jump to next iteration
}
if(i < m){ // && ~(j < n)
//we already completely traversed B[]
c[k] = A[i];
i++;
continue;
}
if(j < n){ // %% ~(i < m)
//we already completely traversed A[]
c[k] = B[j];
j++;
continue;
}
//we should never reach this
cout << "Wow, something wrong happened!" << endl;
}//for
for(int i=0; i<n+m; i++){
cout << c[i] << endl;
}
}
Hope it helps.

C++ Checking for identical values in 2 arrays

I have 2 arrays called xVal, and yVal.
I'm using these arrays as coords. What I want to do is to make sure that the array doesn't contain 2 identical sets of coords.
Lets say my arrays looks like this:
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
Here I want to find the match between xVal[0] yVal[0] and xVal[1] yVal[1] as 2 identical sets of coords called 1,1.
I have tried some different things with a forLoop, but I cant make it work as intended.
You can write an explicit loop using an O(n^2) approach (see answer from x77aBs) or you can trade in some memory for performance. For example using std::set
bool unique(std::vector<int>& x, std::vector<int>& y)
{
std::set< std::pair<int, int> > seen;
for (int i=0,n=x.size(); i<n; i++)
{
if (seen.insert(std::make_pair(x[i], y[i])).second == false)
return false;
}
return true;
}
You can do it with two for loops:
int MAX=4; //number of elements in array
for (int i=0; i<MAX; i++)
{
for (int j=i+1; j<MAX; j++)
{
if (xVal[i]==xVal[j] && yVal[i]==yVal[j])
{
//DUPLICATE ELEMENT at xVal[j], yVal[j]. Here you implement what
//you want (maybe just set them to -1, or delete them and move everything
//one position back)
}
}
}
Small explanation: first variable i get value 0. Than you loop j over all possible numbers. That way you compare xVal[0] and yVal[0] with all other values. j starts at i+1 because you don't need to compare values before i (they have already been compared).
Edit - you should consider writing small class that will represent a point, or at least structure, and using std::vector instead of arrays (it's easier to delete an element in the middle). That should make your life easier :)
int identicalValueNum = 0;
int identicalIndices[4]; // 4 is the max. possible number of identical values
for (int i = 0; i < 4; i++)
{
if (xVal[i] == yVal[i])
{
identicalIndices[identicalValueNum++] = i;
}
}
for (int i = 0; i < identicalValueNum; i++)
{
printf(
"The %ith value in both arrays is the same and is: %i.\n",
identicalIndices[i], xVal[i]);
}
For
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
the output of printf would be:
The 0th value in both arrays is the same and is: 1.
The 1th value in both arrays is the same and is: 1.
The 3th value in both arrays is the same and is: 4.