I am making a program to identify whether a 5 card ( user input ) array is a certain hand value. Pair, two pair, three of a kind, straight, full house, four of a kind ( all card values are ranked 2-9, no face cards, no suit ). I am trying to do this without sorting the array. I am currently using this to look through the array and identify if two elements are equal to each other
bool pair(const int array[])
{
for (int i = 0; i < array; i++)
{
if (array[i]==aray[i+1])
{
return true;
}
else
return false;
}
Does this section of code only evaluate whether the first two elements are the same, or will it return true if any two elements are the same? I.E if the hand entered were 2,3,2,4,5 would this return false, where 2,2,3,4,5 would return true? If so, how do I see if any two elements are equal, regardless of order, without sorting the array?
edit: please forgive the typos, I'm leaving the original post intact, so as not to create confusion.
I was not trying to compile the code, for the record.
It will do neither:
i < array will not work, array is an array not an int. You need something like int arraySize as a second argument to the function.
Even if you fix that then this; array[i]==aray[i+1] will cause undefined behaviour because you will access 1 past the end of the array. Use the for loop condition i < arraySize - 1.
If you fix both of those things then what you are checking is if 2 consecutive cards are equal which will only work if the array is sorted.
If you really cant sort the array (which would be so easy with std::sort) then you can do this:
const int NumCards = 9; // If this is a constant, this definition should occur somewhere.
bool hasPair(const int array[], const int arraySize) {
int possibleCards[NumCards] = {0}; // Initialize an array to represent the cards. Set
// the array elements to 0.
// Iterate over all of the cards in your hand.
for (int i = 0; i < arraySize; i++) {
int myCurrentCard = array[i]; // Get the current card number.
// Increment it in the array.
possibleCards[myCurrentCard] = possibleCards[myCurrentCard] + 1;
// Or the equivalent to the above in a single line.
possibleCards[array[i]]++; // Increment the card so that you
// count how many of each card is in your hand.
}
for (int i = 0; i < NumCards; ++i) {
// If you want to check for a pair or above.
if (possibleCards[i] >= 2) { return true; }
// If you want to check for exactly a pair.
if (possibleCards[i] == 2) { return true; }
}
return false;
}
This algorithm is actually called the Bucket Sort and is really still sorting the array, its just not doing it in place.
do you know the meaning of return keyword? return means reaching the end of function, so in your code if two adjacent values are equal it immediately exits the function; if you want to continue checking for other equality possibilities then don't use return but you can store indexes of equal values in an array
#include <iostream>
using namespace std;
int* CheckForPairs(int[], int, int&);
int main()
{
int array[ ]= {2, 5, 5, 7, 7};
int nPairsFound = 0;
int* ptrPairs = CheckForPairs(array, 5, nPairsFound);
for(int i(0); i < nPairsFound; i++)
{
cout << ptrPairs[i] << endl;
}
if(ptrPairs)
{
delete[] ptrPairs;
ptrPairs = NULL;
}
return 0;
}
int* CheckForPairs(int array[] , int size, int& nPairsFound)
{
int *temp = NULL;
nPairsFound = 0;
int j = 0;
for(int i(0); i < size; i++)
{
if(array[i] == array[i + 1])
nPairsFound++;
}
temp = new int[nPairsFound];
for(int i(0); i < size; i++)
{
if(array[i] == array[i + 1])
{
temp[j] = i;
j++;
}
}
return temp;
}
You could use a std::unordered_set for a O(n) solution:
#include <unordered_set>
using namespace std;
bool hasMatchingElements(const int array[], int arraySize) {
unordered_set<int> seen;
for (int i = 0; i < arraySize; i++) {
int t = array[i];
if (seen.count(t)) {
return true;
} else {
seen.insert(t);
}
}
return false;
}
for (int i = 0; i < array; i++)
{
if (array[i]==aray[i+1])
{
return true;
}
else
return false;
This loop will only compare two adjacent values so the loop will return false for array[] = {2,3,2,4,5}.
You need a nested for loop:
#include <stdio.h>
#include <stdbool.h>
int main()
{
int unsortedArray[] = {2,3,2,4,5};
int size = 5;
for(int i=0;i<size-1;i++)
{ for(int j=i+1;j<size;j++)
{ if(unsortedArray[i]==unsortedArray[j])
{ printf("matching cards found\n");
return 0;
}
}
}
printf("matching cards not found\n");
return 0;
}
----EDIT------
Like Ben said, I should mention the function above will only find the first instance of 2 matching cards but it can't count how many cards match or if there are different cards matching. You could do something like below to count all the number of matching cards in the unsortedArray and save those values into a separate array. It's messier than the implementation above:
#include <iostream>
#include <stdio.h>
#include <stdbool.h>
#defin NUM_CARDS 52;
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int N,i,j;
cin>>N;
int unsortedArray[N];
for(int i=0;i<N;i++)
cin>>unsortedArray[i];
int count[NUM_CARDS]={0};
int cnt = 0;
for( i=0;i<N-1;i++)
{
for( j=i+1;j<N;j++)
{ if(unsortedArray[i]==-1)
break;
if(unsortedArray[i]==unsortedArray[j])
{
unsortedArray[j]=-1;
cnt++;
}
}
if(unsortedArray[i]!=-1)
{
count[unsortedArray[i]]=cnt; //in case you need to store the number of each cards to
// determine the poker hand.
if(cnt==1)
cout<<" 2 matching cards of "<<unsortedArray[i]<<" was found"<<endl;
else if(cnt>=2)
cout<<" more than 2 matching cards of "<<unsortedArray[i]<<" was found"<<endl;
else
cout<<" no matching cards of "<<unsortedArray[i]<<" was found"<<endl;
cnt = 0;
}
}
Related
Question: Smallest Positive missing number
What is wrong with this code?
class Solution
{
public:
//Function to find the smallest positive number missing from the array.
int missingNumber(int arr[], int n)
{
// Your code here
sort(arr,arr+n);
int index=1;
int a;
for(int i=0;i<n;i++){
if(arr[i]>0){
if(arr[i]!=index){
a=index;
break;
}
else{
index++;
}
}
}
return index;
}
};
In every iteration your i is increasing, so this condition which you have written in your for loop:
arr[i]!=index
Here, let's say if the input array has duplicate elements, then for 2 consecutive values of i you will get the same value in arr[i]. In the first comparison, this condition will hold false, so you go to the else part and increment the index value. In the next iteration, your condition arr[i]!=index is always going to be true, as arr[i] is still the same but the index is increased. Thus your program will break from the for loop and the index value is getting returned. That is where it's failing.
So, it will always fail whenever you have duplicate positive elements in your input array. Except for the case when the largest item in the array is the only duplicate in input.
Here's one hint:
for(int i=0;i<n;i++){
if(arr[i]>0){
if(arr[i]!=index){
a=index;
break;
}
else{
index++;
}
}
}
imagine your sorted array is [-10, -5, 0, 1, 2, 3, 4, 5]
When i==3. arr[3] is equal 1, which is the first number you want to evaluate against index. But index will be equal to 3, not 1 as you might have intended.
And as others have pointed out - duplicate numbers in the array are not handled either.
Second hint:
What if I told you... that there was a way to solve this problem without having to sort the input array at all? What if you had an allocated an array of bools of length N to work with....
You should only increase index if arr[i] == index or else you'll get the wrong result for arrays with duplicates, like {1,2,3,4,5,5,6,7}.
int missingNumber(int arr[], int n) {
std::sort(arr,arr + n);
int index=1;
int a;
for(int i=0; i < n; i++) {
if(arr[i] > 0) {
if(arr[i] == index) { // equal, step
++index;
} else if(arr[i] > index) { // greater, we found the missing one
a=index;
break;
} // else, arr[i] == index - 1, don't step
}
}
return index;
}
You are missing a great opportunity to use the sorted array though. Since you're only interested in positive numbers, you can use std::upper_bound to find the first positive number. This search is done very efficiently and it also means that you don't have to check if(arr[i] > 0) in every iteration of your loop.
Example:
int missingNumber(int arr[], int n) {
int* end = arr + n;
std::sort(arr, end);
int* it = std::upper_bound(arr, end, 0); // find the first number greater than 0
int expected = 1;
while(it != end && *it <= expected) {
if(*it == expected) ++expected;
++it;
}
return expected;
}
Alternatively, std::partition the array to put the positve numbers first in the array even before you sort it. That means that you'll not waste time sorting non-positive numbers.
int missingNumber(int arr[], int n) {
int* end = arr + n;
end = std::partition(arr, end, [](int x){ return x > 0; });
std::sort(arr, end);
int expected = 1;
for(int* it = arr; it != end && *it <= expected; ++it) {
if(*it == expected) ++expected;
}
return expected;
}
You can try using a counting array and then walk the array until you come to an empty space.
int main() {
int N;
cin >> N;
int num; // set to zero b/c zero is out lowest possible number
vector<int> numbers;
while (cin >> num) {
numbers.push_back(num);
}
//create a counting array to add a 1 to all the positions that exist
int * cA = new int[10000] {0};
for (int i = 0; i < N; i++) {
if (numbers[i] >= 0) {
cA[numbers[i]]++;
}
}
for (int i = 1; i < 10000; i++) {
if (cA[i] == 0) {
num = i;
break;
}
}
cout << num;
delete []cA;
return 0;
}
How Code Works : first get element count and add all items into Vector by Loop,with second loop going to 1000 i check from 1 to 1000 if any of 1,2,3,4,... is not in the vector i print missing,i do this with bool variable res,if any of loop counter starting from 1 to 1000 is in the vector res variable is set to True otherwise False.be careful in each run of For Loop from 1 to 1000 you should set res=False
#include <iostream>
#include <vector>
using namespace std;
//Programmer : Salar Ashgi
int main()
{
vector<int> v;
int k=0;
cout<<"Enter array count ?\n";
cin>>k;
int n;
for(int i=0;i<k;i++)
{
cout<<"Enter num "<<i+1<<" : ";
cin>>n;
v.push_back(n);
}
bool res=false;
for(int i=1;i<=1000;i++)
{
res=false;
for(int j=0;j<k;j++)
{
if(v[j]==i)
{
res=true;
break;
}
}
if(!res)
{
cout<<i<<" is missing !";
break;
}
}
}
I am implementing bfs (Breadth First Search ) for the graph , but I am getting an error while I pass the starting value of the vector to an integer, for the dfs function to perform, as in the dfs function I have passed the source of the vector, i.e the first element of the vector.
error is on the line where start is declared to v[i]
Here is the complete code
#include <iostream>
#include <vector>
#include <queue>
#include <stdio.h>
using namespace std;
vector<int> v[10];
bool visited[10];
int level[10];
int a = 0;
int arr[10];
void dfs(int s) //function should run only one time
{
queue<int> q;
q.push(s);
visited[s] = true;
level[s] = 0;
while (!q.empty())
{
int p = q.front();
arr[a] = p;
a++;
q.pop();
for (int i = 0; i < v[p].size(); i++)
{
if (visited[v[p][i]] == false) {
level[v[p][i]] = level[p] + 1;
q.push(v[p][i]);
visited[v[p][i]] = true;
}
}
}
}
int main()
{
char c;
int start; // starting element of the vector
int i = 0; // for keeping track of the parent
int countt = 0; // keep track of the no of parents
bool check;
printf("Child or Parent ?");
scanf("%c", &c);
while (countt <= 10) {
if (c == 'c') {
check = true;
int j = 0;
while (check) {
// to keep the track of the child;
scanf("%d", &v[i][j]);
j++;
}
}
if (c == 'p')
{
scanf("%d", &v[i]);
if (i == 0)
{
start = v[i];
}
i++;
countt++;
}
}
printf(" Vector input completed");
dfs(start);
printf("DFS completed, printing the dfs now ");
for (int g = 0; g <= 10; g++)
{
printf("%d", &arr[g]);
}
}
In your current code, v is an array of size 10 containing vector's. However, start is an int, so there is nothing strange in getting an error when trying to assign one to another.
I believe that you wanted v to be either an array of ints or vector of ints. In such a case you just have to declare v properly: int v[10] or vector<int> v(10).
This is general syntax: if you want to declare a vector with known size then you have to put it in (), not in []. Note that you can also fill the vector with some initial values (say zeroes) by writing vector<int> v(10, 0).
In case got you wrong and you wanted to store a graph as vector of vectors, then you can write vector<vector<int>> v(10).
I'm trying to delete all elements of an array that match a particular case.
for example..
if(ar[i]==0)
delete all elements which are 0 in the array
print out the number of elements of the remaining array after deletion
what i tried:
if (ar[i]==0)
{
x++;
}
b=N-x;
cout<<b<<endl;
this works only if i want to delete a single element every time and i can't figure out how to delete in my required case.
Im assuming that i need to traverse the array and select All instances of the element found and delete All instances of occurrences.
Instead of incrementing the 'x' variable only once for one occurence, is it possible to increment it a certain number of times for a certain number of occurrences?
edit(someone requested that i paste all of my code):
int N;
cin>>N;
int ar[N];
int i=0;
while (i<N) {
cin>>ar[i];
i++;
}//array was created and we looped through the array, inputting each element.
int a=0;
int b=N;
cout<<b; //this is for the first case (no element is deleted)
int x=0;
i=0; //now we need to subtract every other element from the array from this selected element.
while (i<N) {
if (a>ar[i]) { //we selected the smallest element.
a=ar[i];
}
i=0;
while (i<N) {
ar[i]=ar[i]-a;
i++;
//this is applied to every single element.
}
if (ar[i]==0) //in this particular case, we need to delete the ith element. fix this step.
{
x++;
}
b=N-x;
cout<<b<<endl;
i++;
}
return 0; }
the entire question is found here:
Cut-the-sticks
You could use the std::remove function.
I was going to write out an example to go with the link, but the example form the link is pretty much verbatim what I was going to post, so here's the example from the link:
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ' ' << *p;
std::cout << '\n';
return 0;
}
Strictly speaking, the posted example code could be optimized to not need the pointers (especially if you're using any standard container types like a std::vector), and there's also the std::remove_if function which allows for additional parameters to be passed for more complex predicate logic.
To that however, you made mention of the Cut the sticks challenge, which I don't believe you actually need to make use of any remove functions (beyond normal container/array remove functionality). Instead, you could use something like the following code to 'cut' and 'remove' according to the conditions set in the challenge (i.e. cut X from stick, then remove if < 0 and print how many cuts made on each pass):
#include <iostream>
#include <vector>
int main () {
// this is just here to push some numbers on the vector (non-C++11)
int arr[] = {10,20,30,30,20,10,10,20}; // 8 entries
int arsz = sizeof(arr) / sizeof(int);
std::vector<int> vals;
for (int i = 0; i < arsz; ++i) { vals.push_back(arr[i]); }
std::vector<int>::iterator beg = vals.begin();
unsigned int cut_len = 2;
unsigned int cut = 0;
std::cout << cut_len << std::endl;
while (vals.size() > 0) {
cut = 0;
beg = vals.begin();
while (beg != vals.end()) {
*beg -= cut_len;
if (*beg <= 0) {
vals.erase(beg--);
++cut;
}
++beg;
}
std::cout << cut << std::endl;
}
return 0;
}
Hope that can help.
If you have no space bound try something like that,
lets array is A and number is number.
create a new array B
traverse full A and add element A[i] to B[j] only if A[i] != number
assign B to A
Now A have no number element and valid size is j.
Check this:
#define N 5
int main()
{
int ar[N] = {0,1,2,1,0};
int tar[N];
int keyEle = 0;
int newN = 0;
for(int i=0;i<N;i++){
if (ar[i] != keyEle) {
tar[newN] = ar[i];
newN++;
}
}
cout<<"Elements after deleteing key element 0: ";
for(int i=0;i<newN;i++){
ar[i] = tar[i];
cout << ar[i]<<"\t" ;
}
}
Unless there is a need to use ordinary int arrays, I'd suggest using either a std::vector or std::array, then using std::remove_if. See similar.
untested example (with c++11 lambda):
#include <algorithm>
#include <vector>
// ...
std::vector<int> arr;
// populate array somehow
arr.erase(
std::remove_if(arr.begin(), arr.end()
,[](int x){ return (x == 0); } )
, arr.end());
Solution to Cut the sticks problem:
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
// Cuts the sticks by size of stick with minimum length.
void cut(vector<int> &arr) {
// Calculate length of smallest stick.
int min_length = INT_MAX;
for (size_t i = 0; i < arr.size(); i++)
{
if (min_length > arr[i])
min_length = arr[i];
}
// source_i: Index of stick in existing vector.
// target_i: Index of same stick in new vector.
size_t target_i = 0;
for (size_t source_i = 0; source_i < arr.size(); source_i++)
{
arr[source_i] -= min_length;
if (arr[source_i] > 0)
arr[target_i++] = arr[source_i];
}
// Remove superfluous elements from the vector.
arr.resize(target_i);
}
int main() {
// Read the input.
int n;
cin >> n;
vector<int> arr(n);
for (int arr_i = 0; arr_i < n; arr_i++) {
cin >> arr[arr_i];
}
// Loop until vector is non-empty.
do {
cout << arr.size() << endl;
cut(arr);
} while (!arr.empty());
return 0;
}
With a single loop:
if(condition)
{
for(loop through array)
{
if(array[i] == 0)
{
array[i] = array[i+1]; // Check if array[i+1] is not 0
print (array[i]);
}
else
{
print (array[i]);
}
}
}
I am trying to write a program that takes an input of of n integers, and finds out the one that occurs the maximum number of times in the given input. I am trying to run the program for t cases.
For this, I have implemented a counting sort like algorithm (perhaps a bit naiive), that counts the number of occurrences of each number in the input. In case there are multiple numbers with the same maximum occurrence, I need to return the smaller among those. For this, I implemented sorting.
The issue I am facing is, that every time I run the program on Visual C++, I am getting an error that tells "vector subscript out of range". Under Netbeans, it is generating a return value of 1 and exiting. Please help me find the problem
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int findmax(vector<int> a, int n)
{
int i,ret;
ret = 0;
for ( i = 0; i <n; i++)
{
if (a[i] > ret) {
ret = a[i];
}
}
return ret;
}
int main() {
int i = 0, j = 0, k = 0, n,m,r1,r2;
vector<int> a;
int t;
vector<int> buff;
cin>>t;
while(t--) {
cin>>n;
a.clear();
buff.clear();
for ( i = 0; i < n; i++) {
cin>>a[i];
}
sort(a.begin(),a.end());
m = findmax(a,n);
for ( j = 0; j < m+1; j++) {
buff[a[j]] = buff[a[j]] + 1;
}
k = findmax(buff,m+1);
for ( i = 0; i < m+1; i++) {
if (buff[i] == k) {
r1 = i;
r2 = buff[i];
break;
}
}
cout<<r1<<" "<<r2<<endl;
}
return 0;
}
After a.clear() the vector doesn't have any members, and its size is 0.
Add a call to a.resize(n) to make it the proper size. You also need to resize buff to whatever size it needs to be.
this line it's the culprit:
cin>>a[i];
you must use push_back:
cin >> temp;
a.push_back(temp);
or resize(n) before:
cin>>n;
a.resize(n);
for ( i = 0; i < n; i++) {
cin>>a[i];
}
then you should pass you vector by reference to findmax
int findmax(vector<int> &a, int n)
...
This isn't how you populate an array.
cin>>a[i];
You need to use the push_back() method or pre-allocate the appropriate size.
The problem is that you're illegally using indexes of your vector that don't exist (you never add any items to the vector). Since you know the size, you can resize it after you clear it:
a.clear();
a.resize(n);
buff.clear();
buff.resize(n);
for ( i = 0; i < n; i++) {
cin>>a[i];
}
will be out of range. The vector, as you construct it, has zero size.
When I populate the array(doska) all is ok, but when I try to print element(cout<< I get error
#include <iostream>
using namespace std;
struct doskas{
int number;
char ch;
};
int main(){
auto doska= new doskas[8][8];
auto ss="0abcdefgh";
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
doska[i][j].ch=ss[i];
doska[i][j].number=j;
}
}
for(int i=1;i<=8;i++)
for(int j=1;j<=8;j++){
cout<<doska[i][j].ch;//ERROR
cout<<doska[i][j].number;
}
system("pause");
return 0;
}
Try from 0 and strictly less than 8, not from one to eight.
Array indices must always start with 0 and end with N-1 where N is the size of the array. Please change your index variables in all the for loops accordingly. Like this:
for(int i=0;i<8;i++)
{
//etc
}
You just have to enumerate array indices in the half-open range [0, N), and all is well:
for (int i = 0; i < 8; ++i)
{
for (int j = 0; j < 8; ++j)
{
doska[i][j].ch = ss[i];
doska[i][j].number = j;
}
}
See Dijkstra's famous argument on why this is the sanest way to think about ranges.