I have been working on a project for school to develop a poker game. I have the code that randomly generates the cards, but I am having problems using functions to sort them. I believe the algorithm itself works, but I am not sure about how to properly access the variables in an array. Visual Studio gives me the errors argument of type "int (*)[5] is incompatible with parameter of type int *(*)[5] and 'void sortPokerHand(int *[][5])': cannot convert argument 1 from 'int [2][5]' to 'int *[][5]'.
The declaration of pokerHand within main()
int pokerHand[2][5];
My functions
//swap the two values
void swap(int* pokerHand, int* x, int* y)
{
int tempVal = pokerHand[0][x];
int tempSuit = pokerHand[1][x];
pokerHand[0][x] = pokerHand[0][y];
pokerHand[1][x] = pokerHand[1][y];
pokerHand[0][y] = tempVal;
pokerHand[1][y] = tempSuit;
}
void sortPokerHand(int* pokerHand[2][5])
{
//bubble sort poker hand
bool swapped;
for (int i = 0; i < 4; i++)
{
swapped = false;
for (int j = 0; j < (5 - i - 1); j++)
{
if (pokerHand[0][j] > pokerHand[0][j + 1])
{
swap(pokerHand[2][5], pokerHand[0][j], pokerHand[0][j + 1]);
swapped = true;
}
}
// If no two elements were swapped by inner loop, then break
if (swapped == false)
break;
}
}
How I am attempting to use the function
sortPokerHand(pokerHand);
Thanks for any help
You're making this much, much harder than it should be. Consider the following pre-conditions:
A "hand" is a sequence of five int values
Only cards in a single hand are sorted relative to each other.
Given that, your swap routine is completely wrong. It should take two int by address (so, pointers to int), and use those to swap contents:
void swapInt(int *left, int *right)
{
int tmp = *left;
*left = *right;
*right = tmp;
}
Next, when sorting, we're sorting a single hand. That means a single sequence of five int. Therefore, there is no need to pass arrays of arrays, pointers to arrays, arrays of pointers, or any of that. Just do this, clean and basic:
// assumption: a hand has five cards
void sortPokerHand(int hand[])
{
// bubble sort sequence of int
size_t len = 5;
bool swapped = true;
while (swapped && len-- > 0)
{
swapped = false;
for (size_t i = 0; i < len; ++i)
{
if (hand[i] > hand[i + 1])
{
swapInt(hand + i, hand + i + 1); // note: uses our new swap function
swapped = true;
}
}
}
}
Finally, we need somehands, both needing sorting. For the sake of this example I'm declaring them in main() as inline array of arrays, then making two calls to actually sort them, one at a time. First, however, we need a print function:
void printHand(const int hand[])
{
fputc('{', stdout);
for (size_t i = 0; i < 5; ++i)
printf("%d ", hand[i]);
puts("}");
}
Simple enough. Now main()
int main()
{
int hands[2][5] =
{
{ 5,10,7,4,1 },
{ 3,6,8,2,9 }
};
for (size_t i = 0; i < 2; ++i)
{
sortPokerHand(hands[i]);
printHand(hands[i]);
}
return EXIT_SUCCESS;
}
The output of this program is:
{1 4 5 7 10 }
{2 3 6 8 9 }
Exactly as we expect.
That's it. In more general solutions we would have an arbitrary hand-size an have to ripple that through the sort and print functions to ensure complete and proper activity. Knowing it is statically size five makes that a little easier.
Also note that you can completely change the definition of hands to use pointers-to-arrays rather than arrays of arrays, or even pointers to pointers, and it will still work, so long as the thing going to sortHand and/or printHand is int* pointing to five int values.
The real question would be how you're ending up with something like int *pokerHand[2][5] in the first place.
One of the strengths of C++ is a fairly rich type system. If I were doing this, I'd probably start by defining a type for a card:
class card {
enum { clubs, diamonds, spades, hearts } suit;
int value; // 1-13 = Ace - King
public:
bool operator<(card const &other) {
if (suit < other.suit)
return true;
if (other.suit < suit)
return false;
return value < other. value;
}
};
So, that operator< sorts first by suit, then by value within the suit, so all the cards in the same suit will get sorted together.
From there, a poker hand is typically going to be five cards, so we just have:
std::vector<card> poker_hand;
Sorting the hand is something like:
std::sort(poker_hand.begin(), poker_hand.end());
If you want to write your own sort routine you obviously can, but it still ends up pretty trivial--a single-dimension vector of cards, which you just compare directly, such as:
if (secondCard < firstCard)
swap(secondCard, firstCard);
Change int* pokerHand[2][5] to int** pokerHand.
Related
I have a 2d array houses[5][2] = {{1,1},{1,1},{1,1},{1,1},{1,1}}
What is the fastest way to check if all the elements inside that array are equal?
Here is what I have tried so far:
```
for(int j=0;j<5;j++){
for(int k=0;k<6;k++){
if(houses[j][k] == houses[j+1][k+1] && j+1 != 5 && k + 1 != 6)
equal = true;
else{
equal = false;
break;
}
}
}
This won't compare all the elements tho, I know how to compare all of them, but it seems to be a very long loop .. is there a faster way to do that?
Your current code will fail because break will only take you out of one loop. You must exit both, which requires a second check, like so:
auto the_value = houses[0][0];
bool equal = true;
for(int j=0;j<5;j++){
for(int k=0;k<6;k++){
if(houses[j][k]!=the_value){
equal = false;
goto done;
}
}
if(!equal)
break
}
(Storing the first element in a variable and then looping over all of the elements to check to see if they are equal to that variable obviates the mess you invoke by checking adjacent elements.)
Breaking out of both loops simultaneously requires the Dark Arts (goto), but may be more readable/maintainable if you are disciplined and may be slightly faster, depending on your compiler:
auto the_value = houses[0][0];
bool equal = true;
for(int j=0;j<5;j++)
for(int k=0;k<6;k++)
if(houses[j][k]!=the_value){
equal = false;
goto done; //Danger, Will Robinson!
}
done:
//More stuff
You may find a flat array to be faster:
auto the_value = houses[0][0];
bool equal = true;
for(int i=0;i<5*6;i++)
if(houses[i]!=the_value){
equal = false;
break;
}
The 2D array is stored as a 1D contiguous array in memory. Using flat array addressing accesses the same memory locations, but explicitly avoids forcing the internal arithmetic. For highly performant code you may wish to consider using flat arrays by default.
Since you might use a function such as this a number of times or have it embedded in otherwise complex code, perhaps you'd like to abstract it:
template<class T>
bool AllEqual(const T& arr, size_t N){
T the_value = arr[0];
for(int i=0;i<N;i++)
if(arr[i]!=the_value)
return false;
return true;
}
AllEqual(houses, 5*6);
Since you're coding in C++, you probably don't want to be using raw arrays anyway. Let's rewrite your code using the STL, assuming flat arrays:
template<class T>
bool AllEqual(const std::vector<T>& arr){
return std::all_of(arr.begin(), arr.end(), [&](const T& x){ return x==arr[0]; });
}
std::vector<int> houses = {}; //Replace with appropriate initialization
if(AllEqual(houses))
//Do stuff
(Also: as another answerer mentioned, the way you are adding data to your array seems to imply that it should be 2x6/6x2 array instead of 5x6/6x5.)
First, do you understand what your array looks like? You have 6 times of two ones, but you used houses[5][6]. That's it 5 rows and 6 columns. You should have gotten an error for that:
main.cpp:5:55: error: excess elements in array initializer
int houses[5][6] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1}};
^~~~~
What you really wanted was 6 rows and 2 columns.
As for the way of checking whether all elements of a 2D array are equal, I would follow a simple approach; store the first element of your array to a variable, e.g. named v, and check that value versus all the other elements. If it is not equal to just one element, then it is enough to take a decision and say that not all elements are equal, like in the following example:
#include <iostream>
bool allEqual(int arr[][2], int rows)
{
int v = arr[0][0];
for(int i = 0; i < rows; ++i)
for(int j = 0; j < 2; ++j)
if(v != arr[i][j])
return false;
return true;
}
int main(void)
{
int houses[6][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1}};
allEqual(houses, 6) ? std::cout << "All " : std::cout << "Not all ";
std::cout << "elements are equal\n";
return 0;
}
If I emulate a 2D array with an 1D, will it be faster?
I doubt it. They idea is that the memory locations will be contiguous, but this is what happens pretty most in the 2D case, given that the rows are more than the columns.
Here is my experiment:
Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall -std=c++0x -O3 -o 2d 2d.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./2d
2D array took 1.48e-10 seconds.
Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall -std=c++0x -O3 -o 1d 1d.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./1d
Emulating 2D array with 1D array took 1.5e-10 seconds.
and my code, based on my Time measurements (C++):
#include <iostream>
#define ROWS 10000
#define COLS 20
#define REPEAT 1000
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
bool allEqual(int* arr, const int size)
{
int v = arr[0];
for(int i = 0; i < size; ++i)
if(v != arr[i])
return false;
return true;
}
void fill(int* arr, const int size)
{
for(int i = 0; i < size; ++i)
arr[i] = 1;
}
int main(void)
{
const int size = ROWS * COLS;
int houses[size];
fill(houses, size);
bool equal;
using namespace std::chrono;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for(int i = 0; i < REPEAT; ++i)
equal = allEqual(houses, size);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
std::cout << "Emulating 2D array with 1D array took " << time_span.count()/(double)REPEAT << " seconds.\n";
return 0;
}
where the 2d.cpp is the straightforward way.
Using the equal method provided in this answer for a 2D array, the timings reported are similar.
Moreover, there is std::equal, which is comparable in terms of performance to my code above, reporting a time of:
std::equal with 2D array took 1.63e-10 seconds.
It's complexity is: "Up to linear in the distance between first1 and last1: Compares elements until a mismatch is found."
Summary:
std::equal does OK, and requires the less effort from the programmer, thus use it.
Multiple things:
First, as others have pointed out, the line:
int houses[5][6] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1}};
Is wrong, the left hand side declares an array with 5 rows and 6 columns, but the right hand side constitutes an array of 6 rows and 2 columns.
On the general case comparing all elements of a 2d array (or even a 1d array) is in O(n) since for every element you must check all other elements. You can optimize it a little bit but it will still be an O(n) algorithm. On the most general case:
A[n][m] is an array of n rows and m columns
for(int i=0; i<n*m; i++)
{
if(A[0][0] != A[i/n][i%n])
return false;
}
return true;
This may seem a little bit confusing so let me explain:
a 2d array has n*m elements, so an easy way to see all of them in a single loop is doing [i/n] (if i < n, then it's the first row, if n < i < 2n then it's the second row...) and doing [i%n] gives you the remainder. This way we can iterate the entire array in a single loop.
Since we want all elements to be the same, if the first element is equal to all others then they are ll the same, if at least on is different then they are not all the same.
The fastest way:
int houses[6][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,2}};
int equals()
{
int *p = (int *)houses;
int *end = p + 6*2;
int v = *p++;
for(; p < end; p++)
if (*p != v)
return 0;
return 1;
}
I wrote it for fun, don't use that in production.
Instead, iterate through them all:
int equals() {
int v = houses[0][0];
for(int j=0;j<5;j++)
for(int k=0;k<6;k++)
if (houses[i][j] != v)
return false;
return true;
}
We can simply way to check if all the elements inside that array are equal
or not. just assign the first row & column element in a variable. Then compare each element. If not equal then return false.
Code Snippet :
bool Equal(int **arr, int row, int col)
{
int v = arr[0][0];
for(int i=0; i<row; i++)
{
for(int k=0; k<col; k++)
{
if(arr[i][k]!=v) return false;
}
}
return true;
}
I was having trouble with my code. I pass in an array of strings (names) and I want to do a quick sort and sort them alphabetically. Then, what I would like to do is with my array of years and ages, is swap those values respectively with the values swapped in my names array. However, I'm having trouble trying to implement that.
In the main function, I pass in:
quicksort(names, names[0], names[names.size() - 1]);
And in that code contains
void quicksort(vector<string> &names, string min, string max){
cout << "\n\tSorting names...\n";
int temp = 0,
i = 0;
string lowMin = max,
lowMax = min,
highMin = max,
highMax = min,
pivot;
vector<string> below,
above;
if (min != max){
pivot = (max[i] + min[i]) / 2;
while (temp < names.size()){
if (names[temp] <= pivot){
if (lowMax.compare(names[temp]) < 0){
lowMax = names[temp];
}
if (lowMin.compare(names[temp]) > 0){
lowMin = names[temp];
}
below.push_back(names[temp]);
}
else {
if (highMax.compare(names[temp]) < 0){
highMax = names[temp];
}
if (highMin.compare(names[temp]) > 0){
highMin = names[temp];
}
above.push_back(names[temp]);
}
temp++;
}
if ((below.size() > 1) && (names.size() != below.size())){
quicksort(below, lowMin, lowMax);
}
if ((above.size() > 1) && (names.size() != above.size())){
quicksort(above, highMin, highMax);
}
for (size_t i = 0; i < below.size(); i++){
names[i] = below[i];
}
for (size_t i = below.size(); i < names.size(); i++){
names[i] = above[i - below.size()];
}
}
} // // End quicksort()
In this case, would it be better to make a swap function and send in two integers so I can swap values in my other vector arrays? For example, I was thinking swapValue(int i, int j){ /* do something */}
Also, can someone explain to me the difference between foobar[i].swap(foobar[j]) and swap(foobar[i], foobar[j])? Are these methods more efficient than say creating a temp variable and swapping values?
Don't implement quicksort if you do it only because you need some sorting algorithm to use.
You seem to have three std::vector for name, age and year, where elements at the same position are related. Why not combine everything?
struct Person //or some name
{
std::string name;
int age;
int year;
int operator<(const Person &other) //comparison
{
return name.compare(other.name);
}
};
Of course, you could make a full class with the Big5 etc. too, if you want.
Now, with a vector<Person> v;, you can use std::sort:
std::sort(v.begin(), v.end());
That's all.
...If you still want to have a quicksort function, take eg. this, and change the lines with the swaps so that swaps are made on all three vectors.
About your other question:
The swap of std::string and the independent function swap with string paramters do the same thing (technically they don't have to, they are completely independent, but they do).
And why swap(a,b) is better than c=a;a=b;b=c;:
In the second code, values are copied three times. For std::string, this means three times allocating new memory and copying the whole content. Swap can do it without any content copy (it can access the internal pointers etc. and exchange only these).
Currently I have two functions:
One takes the number of primes to generate.
The second takes the upper limit of primes to generate.
They are coded (In C++) as such:
prime_list erato_sieve(ul_it upper_limit)
{
prime_list primes;
if (upper_limit < 2)
return primes;
primes.push_back(2); // Initialize Array, and add 2 since its unique.
for (uit i = 3; i <= upper_limit; i += 2) // Only count odd numbers
{
flag is_prime = true;
for (uit j = 0; j < primes.size(); ++j)
{
if ((i % primes[j]) == 0)
{
is_prime = false;
break;
}
}
if (is_prime)
{
primes.push_back(i);
}
}
return primes;
}
And:
prime_list erato_sieve_num(ul_it MAX)
{
prime_list primes;
if (MAX == 0)
return primes;
primes.push_back(2); // Initialize Array, and add 2 since its unique.
uit i = 3;
while (primes.size() < MAX) // Only count odd numbers
{
flag is_prime = true;
for (uit j = 0; j < primes.size(); ++j)
{
if ((i % primes[j]) == 0)
{
is_prime = false;
break;
}
}
if (is_prime)
{
primes.push_back(i);
}
++i;
}
return primes;
}
Where the following types are defined:
typedef bool flag;
typedef unsigned int uit;
typedef unsigned long int ul_it;
typedef unsigned long long int ull_it;
typedef long long int ll_it;
typedef long double ld;
typedef std::vector<ull_it> prime_list;
(Feel free to use them if you like, or not. A find-replace will take care of that. I use them to make the code read more how I think)
I am trying to make these into one "function" that is overloaded, but they two have similar arguments. I'm worried that the choice between them will come down to type alone, which will lead to hard-to-debug problems.
My second option would be to create a class, but I'm quite embarrassed to say.., I've never used classes before. At all. So I have no idea how to do it, and the documentation is a little... sparse?
Anyway, if someone would mind helping me out a little bit, it would be greatly appreciated. Documentation is always helpful, and any pointers are welcome as well.
EDIT
As I said, my section option is a class. I'm just entirely sure how to make a class to combine these two.
Never give the same name to functions with different semantics. Overloading is not purposed for that. And these two both take an integer number, if you could overload them how would you tell which function is called at erato_sieve(5)?
Give them different names, e.g. erato_sieve_up_to and erato_sieve_count.
Well, if you still want to make things worse (please don't), you can overload them (please don't), just make them expect different types of arguments. For example, wrap an integer into a class and pass that class, something like
class CountWrapper {
public:
CountWrapper(int n) { n_ = n; }
operator int() { return n_; }
private:
int n_;
};
prime_list erato_sieve(const CountWrapper& MAX) {
// function's body stays the same
And call it like
my_list = erato_sieve(CountWrapper(5));
But once again: please don't!
To group the functions, you can define them as static methods of a class:
class PrimeGenerator {
public:
static prime_list EratoSieveUpTo(ul_it upper_limit) {
// body
}
static prime_list EratoSieveAmount(ul_it MAX) {
// body
}
};
and call the functions like
list1 = PrimeGenerator::EratoSieveUpTo(5);
list2 = PrimeGenerator::EratoSieveAmount(10);
If you want to create overloaded functions, you need a different argument list for each function definition. In the case the actual used arguments are of same type, the following trick can be used:
typedef struct {} flag_type_1;
typedef struct {} flag_type_2;
...
typedef struct {} flag_type_n;
prime_list erato_sieve(ul_it boundary, flag_type_1) { ... }
prime_list erato_sieve(ul_it boundary, flag_type_2) { ... }
...
prime_list erato_sieve(ul_it boundary, flag_type_n) { ... }
The idea is that each typedef-ed structure is of different type signature. This creates completely unrelated argument list for each function overload. Also, as the types are dummy holder, you don't care about the content. That's why you only need to include type in the argument list of the function definition.
I picked this up a while back from Channel 9. Pretty neat trick.
This isn't a direct answer to your question, but it will help answer your question.
You appear to be attempting to implement the Sieve of Eratosthenes. The basic algorithm for that sieve is below:
1) Create a list of numbers from 2 to N (N is the maximum value you are looking for)
2) Start at 2, and eliminate all other even numbers (they are non-prime) less than or equal to N
3) Move to the next non-eliminated number.
4) Eliminate all multiples of that number less than or equal to N.
5) Repeat steps 3 and 4 until you reach the square root of N.
Translating that into C++ code, it would look something like this (not optimized):
std::vector<unsigned int> sieve_of_eratosthenes(unsigned int maximum)
{
std::vector<unsigned int> results; // this is your result set
std::vector<bool> tests(maximum + 1); // this will be your "number list"
// initialize the tests vector
for (unsigned int i = 0; i <= maximum; ++i)
{
if (i == 0 || i == 1)
tests[i] = false;
else
tests[i] = true;
}
// eliminate all even numbers but 2
for (unsigned int i = 4; i <= maximum; i += 2)
{
tests[i] = false;
}
// start with 3 and go to root of maximum
unsigned int i = 3;
while (i * i <= maximum)
{
for (unsigned int j = i + i; j <= maximum; j += i)
{
tests[j] = false;
}
// find the next non-eliminated value
unsigned int k = i + 1;
while (!tests[k])
{
k++;
}
i = k;
}
// create your results list
for (unsigned int j = 0; j <= maximum; ++j)
{
if (tests[j])
{
results.push_back(j);
}
}
return results;
}
Example
Since the sieve requires a maximum value, you do not want to provide a number of primes for this algorithm. There are other prime generating algorithms that do that, but the Sieve of Eratosthenes does not.
I'm trying to write a code to actually sort my array in an ascending order, so what happen is that say this is what I have.
char myListArray[10][40];
myListArray = "Yeah?",
"Tomorrow",
"Again",
"I will see you";
So what happen is that it should be sort in the order by ASCII value.
Again
I will see you
Tomorrow
Yeah?
I've create something like this...
char temp[40];
temp[0] = '\0';
int i, j, pos = 10, flag = 1;
for(i = 1; (i <= pos) && flag; i++)
{
flag = 0;
for (j=0; j < (pos -1); j++)
{
if (phrase[i][j+1] > phrase[i][j])
{
strcpy(temp, phrase[i]);
strcpy(phrase[i], phrase[i+1]);
strcpy(phrase[i+1], temp);
flag = 1;
}
}
}
Now I don't know I have a problem with my logic, and I wish to know if there is a function to sort easy way? or bubble sort is the easiest ?
UPDATE:
I will accept one of the answer below, but I have found my solution of how to sort my array in the easiest way.
while(pos < 9){
if(phrase[pos][i] > phrase[pos+1][i]){
strcpy(temp, phrase[pos]);
strcpy(phrase[pos], phrase[pos+1]);
strcpy(phrase[pos+1], temp);
flag = 1;
if(flag = 1){
pos = 0;
}
}
pos++;
}
Using std::array, std::string, and std::sort...
std::array<std::string, 4> arr = { "Yeah?", "Tomorrow", "Again", "I will see you" };
std::sort(arr.begin(), arr.end());
This can also be trivially adapted to use C arrays or std::vectors if you don't have access to std::array.
I wish to know if there is a function to sort easy way?
Try to use C++ constructs such as string, vector and sort. Your job becomes much easier then.
However, if you want to use C, you can look up qsort. You will need to provide a custom comparator function though.
bubble sort is the easiest ?
The choice of a sorting algorithm depends on factors such as worst-case performance, number of elements etc. Think about the number of elements that you need to sort. Think what sort of performance will be acceptable. IMO, implementing bubble-sort is about as easy as insertion-sort or Shell-sort. Merge sort/quick sort/radix sort OTOH, are perhaps slightly more involved.
If you want it to use plain C, like you seem to, then you are missing out on strcmp and qsort. Note that your code has nothing to do with C++, it's a classic C code and the question is mistagged. If you want it done in C++, see other answers that actually use C++ containers. There's no point to using C++ if you don't actually, you know, use the part that makes it C++, not merely C!
Below is a self contained working example. Note that there is an example both for your 2D array and for an array of pointers to strings. Your 2D array declaration had a superfluous 1st array size. It's unnecessary, the compiler knows how many strings are there.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sort1(void)
{
// 2D array
char strings[][40] = {
"Yeah?",
"Tomorrow",
"Again",
"I will see you"
};
const int el_size = sizeof(strings[0]);
const int el_count = sizeof(strings)/el_size;
int i;
printf("\n%s\n", __FUNCTION__);
qsort(strings, el_count, el_size, strcmp);
for (i = 0; i < el_count; ++i) {
printf("%s\n", strings[i]);
}
}
int strcmp_ptr(const char ** a, const char ** b)
{
return strcmp(*a, *b);
}
void sort2(void)
{
// Array of pointers to string constants
const char * strings[] = {
"Yeah?",
"Tomorrow",
"Again",
"I will see you"
};
const int el_size = sizeof(strings[0]);
const int el_count = sizeof(strings)/el_size;
int i;
printf("\n%s\n", __FUNCTION__);
qsort(strings, el_count, el_size, strcmp_ptr);
for (i = 0; i < el_count; ++i) {
printf("%s\n", strings[i]);
}
}
int main(void)
{
sort1();
sort2();
return 0;
}
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.