Comparing elements in the array by use of pointers (C++) - c++

I am creating the function, compare_arrays to check if elements inside the pre-defined arrays are similar. I want to use pointer and pass the arrays by reference into the function. This is the function I coded so far but pylint is giving me an error for my second if loop stating that *arry1 and *arry2 are not defined. Can someone help me understand this error better.
Also, how do I call the function and pass in arr_one, arr_two, etc.....
#include <iostream>
using namespace std;
int size1 = 3, size2 = 3;
int arr_one[] = {1, 2, 3};
int arr_two[] = {1, 2, 3};
int main(){
bool compare_arrays( int *arry1, int size1, int *arry2, int size2);{
if (size1 != size2){
return false;
}
for(int i=0; i < size1; i++);{
if (*arry1 != *arry2);{
return false;
}
}
*arry1++;
*arry2++;
return true;
}
}

The biggest and main problem in your code is the inclusion of the ; at the end of compare_arrays. What you're actually doing is declaring a function, compare_arrays, then creating a separate scope, which is why arry1 is not defined. If you remove this semi-colon, your error will start to make more sense:
bool compare_arrays( int *arry1, int size1, int *arry2, int size2) {
Now the compiler will tell you you cannot define an function within a function, which is easy to solve. Move compare_arrays outside of main:
bool compare_arrays( int *arry1, int size1, int *arry2, int size2){
if (size1 != size2){
return false;
}
for(int i=0; i < size1; i++);{
if (*arry1 != *arry2);{
return false;
}
}
*arry1++;
*arry2++;
return true;
}
int main() {
}
This will now compile, but probably not run as you expect, because you have an extra erroneous semi-colon at the end of your second if statement. What this means is the semi-colon is treated as the expression from the if, then you'll always return false;. Fix this by removing the semi-colon:
for (int i = 0; i < size1; i++) {
And now you can simply call your code in main like so:
int main() {
if (compare_arrays(arr_one, size1, arr_two, size2)) {
std::cout << "arrays are equal\n";
}
}
However, you can trivialise the whole thing by using std::vector:
#include <vector>
#include <iostream>
int main() {
std::vector<int> v1 = { 1, 2, 3 };
std::vector<int> v2 = { 1, 2, 3 };
if (v1 == v2)
std::cout << "arrays are equal\n";
}

You put compare_arrays function body inside the main function. remove the body of the function out the main and just call it from inside the main function. Also, you put the semi-colon after if statement and function header and that's wrong. your code should be like this
#include <iostream>
using namespace std;
int size1 = 3, size2 = 3;
int arr_one[] = { 1, 2, 3 };
int arr_two[] = { 1, 2, 3 };
bool compare_arrays(int *arry1, int size1, int *arry2, int size2) {
if (size1 != size2) {
return false;
}
for (int i = 0; i < size1; i++) {
if (*arry1 != *arry2) {
return false;
}
}
*arry1++;
*arry2++;
return true;
}
int main() {
cout << compare_arrays(arr_one, size1, arr_two, size2) << endl;
}

Related

Class that uses dynamically generated array

Trying to make a class that can change the contents of a specific element in a dynamically created 2 dimensional array of strings.
So I have a program that creates a 2d array dynamically and later on I want to have a class that takes that array as its argument, along with 2 integers that will be the indexes of a specific element. Later on I'll have it swap the content of that element and scan other elements of the array that it wants to swap it with. For now I'm struggling with even having the class take that array as its argument. I know I'll have to do this by reference and not by value, since the array will be dynamically created, but it seems I am doing it wrong.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Example {
int x, y;
string** chart;
public:
Example(int i, int j,string **arr);
void print() const { cout << x << y << chart[x][y] << endl; }
};
Example::Example(int i, int j,string **arr) {
x = i;
y = j;
**chart = **arr;
}
int main() {
string chart[7][7]; //to make the experiment simpler I haven't
//made the array dynamically generated yet
//but it will be later
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
if (chart[i][j] == "")
chart[i][j].insert(0, 3, ' ');
}
}
chart[6][5] = "EXA";
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
cout << '[' << chart[i][j] << ']';
}
cout << endl;
}
Example Exa1(6, 5, &chart);
Exa1.print();
return 0;
}
The problem is that the type of &chart is std::string (*)[7][7] which cannot be implicitly converted to a string** and so the constructor Example::Example(int i, int j,string **) cannot be used. This is exactly what the mentioned error says:
error: no matching function for call to 'Example::Example(int, int, std::string (*)[7][7])'
45 | Example Exa1(6, 5, &chart);
To solve this make sure that &chart has the same type as the 3 parameter of your constructor.
Also it would be better to use std::vector.
class Example {
int x, y;
std::vector<std::vector<string>> chart;
public:
Example(int i, int j,const std::vector<std::vector<std::string>> &arr);
};
Example::Example(int i, int j,const std::vector<std::vector<std::string>> &arr)
:x(i),y(j),chart(arr) {
}
int main() {
std::vector<std::vector<std::string>> chart(7, std::vector<std::string>(7));
//pass chart instead of &chart
Example Exa1(6, 5, chart);
}
Working demo
Or you can also use std::array
class Example {
int x, y;
std::array<std::array<std::string, 7>, 7> chart;
public:
Example(int i, int j,const std::array<std::array<std::string, 7>, 7> &arr);
};
Example::Example(int i, int j,const std::array<std::array<std::string, 7>, 7> &arr)
:x(i),y(j),chart(arr) {
}
int main() {
std::array<std::array<std::string, 7>, 7> chart;
//pass chart instead of &chart
Example Exa1(6, 5, chart);
}

How to check if a number is in a vector, and if not, then to return -1?

This is pretty easy if I can import <algorithm> or any other things at the top, but I just started using C++ and my professor asked us to use only loops and conditionals for this problem.
The problem itself is to give a vector v and an int seek to a function. A loop runs through the vector to find the index of the first location of the number. If it can be found, then return the index of where the number is, if not then return -1.
I got the first part down, but now I am having an issue with the second part.
#include <iostream>
#include "vectorutils.h"
#include <vector>
using namespace std;
//endl = new line
int main() {
cout << find({1, 2, 3, 4, 5, 6, 7, 8}, 28) << endl;
}
int find(const std::vector<int>& v, int seek) {
int ind = 1;
for (int i = 0; i < v.size(); i++) {
if (seek == v[i]) {
return i;
}
else {
return -1;
}
}
You have the return -1; statement in the wrong place. It needs to be after the loop exits, not inside the loop. For example:
int find(const std::vector<int>& v, int seek) {
for (int i = 0; i < v.size(); i++) {
if (seek == v[i]) {
return i;
}
// else {
// return -1;
// }
}
return -1; // <-- moved down here!
}
In your original code (if it could compile, which it doesn't), the logic is wrong. If the vector is empty then you return nothing at all (which is undefined behavior), and if the 1st element does not match the number then you return -1 immediately without checking the remaining elements at all.
The above change fixes both of those issues.

Trouble with index

Write the find function, which takes a fixed integer vector reference and a single value integer and returns the index of the first occurrence of this value in the vector or the length of the vector if no value in it. The function should be adapted for use in the sample program
below. The function uses only the vector header file.
This is what I've done so far:
#include <vector>
#include <iostream>
using namespace std;
int find(const vector<int> &r ,int number)
{
int i=0;
int x;
for(i;i<r.size();++i)
{
if(r[i]==number)
{
break;
}
}
return 0;
}
int main()
{
int result = find(vector<int> {3, -1, 7, 12, -5, 7, 10}, 7);
cout << result << endl;
}
And, I'm stuck, I don't know how to return the index.
You should add return i; instead of breaking out of the loop
and maybe return -1 instead of 0 if the number is not found.
Return index i when found otherwise return 0 after the loop like this:
int find( const std::vector<int>& r, const int number )
{
for ( int i = 0; i < r.size(); ++i )
{
if ( r[i] == number )
{
return i;
}
}
return 0;
}
The x is unused in find function.
You should return i from your function

Copying one int array to another C++

Was trying to write a program which converts the value`s from one assigned array to another unassigned one. The code i wrote:
#include "stdafx.h";
#include <iostream>;
using namespace std;
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int j[10];
int copy_array(int *p1, int n);
int *p2, *p2;
int main() {
for (int l = 0; l < 10; l++) {
cout << a[l] << endl;
}
copy_array(a, 10);
for (int i = 0; i < 10; i++) {
j[i] = &p2;
cout << j[i] << endl;
}
system("PAUSE");
return 0;
}
int copy_array(int *p1, int n) {
while (n-- > 0) {
*p1 = *p2;
*p1++;
*p2++;
}
}
Im using the Microsoft visual studio platform and the error i got was "There is no context in which this conversion is possible". Why i cant use this int convert path? how can i fix and connect the 2 arrays using int type conversion(if its possible)?
What i tried was manipulating the local function copy_array so it makes the conversion using the addresses of the j[10] array integers, but this gave me another error. Any support and advice would be appreciated.
These are some notes on your code:
you have redundant p2 declaration:int *p2, *p2;. Also you need to initialize it. so make it: int *p2 = j; (in fact, you don't actually need to use this global variable - you can achieve the same effect by passing j as necessary).
Inside your copy function, your assignment should be in reverse:
*p2 = *p1; not *p1 = *p2; - the right-hand side is assigned to the left hand side.
When printing j, you do not need j[i] = &p2; which alters j's contents.
It is better to define the arrays inside the function not in the general scope.
Correct them and your code should work fine.
However, You do not need pointers to do this at all.
Consider the following code and compare it to yours:
#include <iostream>
using namespace std;
void copy_array(int [], int [], int);
void print_array(int [], int);
int main() {
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int j[10];
print_array(a,10);
copy_array(a, j, 10);
print_array(j,10);
return 0;
}
void copy_array(int s[], int d[], int n) {
for (int i = 0; i < n; i++)
d[i] = s[i];
} // s for source & d for destination
void print_array(int arr[], int n) {
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << "\n\n";
}
You don't need p2 to be global.
Just add parameter to copy_array.
like this:
void copy_array(int *p1, int *p2, int n) {
while (n-- > 0) {
*p1 = *p2;
p1++;
p2++;
}
}
and call like this:
copy_array(j, a, 10);
Also: to print the copy you just do:
for (int i = 0; i < 10; i++) {
cout << j[i] << endl;
}
I want to build on #Shadi's answer, which you should upvote, and make the code more C++-idiomatic.
In C++, we don't need to explicitly return 0; from main; it is implied, if you haven't returned anything else.
It's better to use names in a similar scheme for similar variables. Specifically, i and j are common variable names for integer scalars, e.g. counters - not arrays. I'd suggest you use a and b for the arrays, or values and copy_of_values etc.
The C++ standard library has an array-like container class named std::vector. It's not exactly the same as an array; for example, it uses dynamically-allocated memory, and can grow or shrink in size. The reason you might want to use it is that it allows you to perform plain assignment, and use other standard library facilities with it.
Thus Shadi's program becomes:
#include <iostream>
#include <vector>
void print_vector(const std::vector<int>& vec);
int main() {
std::vector<int> a { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> b;
print_vector(a);
b = a;
print_vector(b);
}
void print_vector(const std::vector<int>& vec) {
// this next line uses syntax from the 2011 version of
// the C++ language standard ("C++11").
for(int x : vec) {
std::cout << x << " ";
}
std::cout << "\n\n";
}
You can also avoid the loop in print_vector entirely, using std::for_each or std::for_each_n, but that would require some knowledge of iterators and lambda functions, which may be a bit advanced for a beginner, so I won't go into that. But better yet, you could define a out-streaming operator for std::vector's, as seen here, with which you could write std::cout << a; and have that work.

Equal elements in an unsorted array

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;
}
}