C++ how to check if elements in an array are equal? - c++

I am trying to write a program which checks if all the values in an array are equal using a for loop but I cannot figure out a way for the if statement to check if each value in the array are equal other than constantly repeating "if a[i] == a[1] && a[i] == a[0]" and so on. I do not want to do that as i want it to work for any array of any size. Any help is much appreciated!
for (unsigned i = 0; i < val; i++){
if (a[i] == a[0])
return true;
else
return false;
}

for (unsigned i = 0; i < val; i++) {
if (a[i] != a[0]) {
return false;
}
}
return true;
That ought to do it.
In this case, the code will instantly fail on a non-matching value. However, on a matching value it simply continues checking (as we know we need to test EVERY element of the array no matter what). Once that's done, it knows everything went well (since we didn't return early) and returns true.

#include <algorithm>
#include <vector>
#include <iostream>
int main(int argc, char** argv)
{
std::vector<int> eq{ 1, 1, 1, 1 };
std::vector<int> nq{ 1, 2, 1, 1 };
bool eq_res = std::all_of(std::begin(eq), std::end(eq),
[&eq](int c) -> bool
{
return eq[0] == c;
});
bool nq_res = std::all_of(std::begin(nq), std::end(nq),
[&nq](int c) -> bool
{
return nq[0] == c;
});
std::cout << "eq: " << eq_res << std::endl;
std::cout << "nq: " << nq_res << std::endl;
}
Compiled with
g++ --std=c++11 main.cpp

Just for fun, using lambda expression
#include <algorithm>
using namespace std;
template<size_t N>
bool func(int (&arr)[N])
{
int* pOddValue = std::find_if(begin(arr), end(arr),
[&] (int val){ return val != arr[0];});
return pOddValue != end(arr);
}

Using divide and conquer approach, we can reduce the no of comparison to n-1 if n = 2^k like this:
bool divide(int arr[],int size)
{
if( size == 2 ) return arr[0] == arr[1];
if( divide(arr,size/2) && divide(arr+size/2,size/2) )
return arr[0] == arr[size/2];
return false;
}
Another similar way to do it:
for (unsigned i = 1; i < val; i++) {
if (a[i] != a[i-1]) {
return false;
}
}
return true;

It seems that you don't need to handle val = 0.
You can do it in 1 line.
#include <functional>
#include <algorithm>
using namespace std;
return all_of(
a+1, a+val,
bind(equal_to<remove_pointer<decltype(a)>::type>(), a[0], placeholders::_1));

Related

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.

Checking if characters length in string is same or not

I am trying to write a program that checks if characters of created word are in different length.
for example word:
PAABBBMMMM
it should print Yes, because P was printed 1 time, A was printed 2 times, B was printed 3 Times, m was printed 4 times.
If the word was for e.g PAABB it should print no, because AA and BB is same length.
What I am doing wrong?
#include <iostream>
using namespace std;
bool checkChars(string s)
{
int n = s.length();
for (int i = 1; i < n; i++)
if (s[i] != s[0])
return false;
return true;
}
// Driver code
int main()
{
string s = "PAABBBMMMM";
if (checkChars(s))
cout << "Yes";
else
cout << "No";
return 0;
}
With the condition if (s[i] != s[0]), you're just checking if each character is equal to the first character, which makes no sense.
You can use a std::map to count the frequency of each character, then use std::set to check the uniqueness of each frequency:
#include <iostream>
#include <string>
#include <map>
#include <set>
bool checkChars(std::string s)
{
int n = s.length(); std::map<int, char> freq;
for (int i = 0; i < n; i++)
freq[s[i]]++;
std::set<int> Unique;
for (auto it = freq.begin(); it!=freq.end(); it++)
Unique.insert(it->second);
if (Unique.size() != freq.size()) {return false;}
return true;
}
// Driver code
int main()
{
std::string s = "PAABBBMMMM";
if (checkChars(s))
std::cout << "Yes";
else
std::cout << "No";
return 0;
}
Result: Yes
Other example:
"AABB" -> No
"MABAAB" -> Yes
Also see Why is "using namespace std;" considered bad practice?

Program to check any number exist in 2D array

I know how to check if number exist in the array, but not in a 2D array.
Please help me in 2D.
#include<iostream>
using namespace std;
int main()
{
int a[3] = { 4,5,6 };
int b, c;
int x = 1, fact = 1;
cout << "enter no ";
cin >> b;
for (int i = 0; i < 3; i++)
{
if (b == a[i]) {
c = a[i];
break;
}
}
cout << "no entered is present" << endl;
}
I know how to check if number exist in the array, but not in 2D array!
It is like you did for the one-dimensional array, instead of one, you need to now iterate through the rows and column. In another word, you need one more iteration.
#include<iostream>
int main()
{
int a[2][3]{ { 1,2,3 }, { 4,5,6 } };
int userInput = 5;
bool found = false;
for (int row = 0; !found && row < 2; ++row) // if not found and row size < 2
{
for (int col = 0; col < 3; ++col) // if column size < 3
{
if (userInput == a[row][col]) // access the element like this
{
// other codes
std::cout << "No entered is present\n";
found = true;
break;
}
}
}
}
However, using the row size and column size like this, I will not recommend so. You should be using better std::array(if you know the size at compile time), or std::vector(if the sizes are known at run time).
For example, using std::array you could have the following code(example code). Using the range based for-loop, and a simple function makes the code more readable and less error-prone. Also, you need to know the sizes known at compile time. (See live demo)
#include <iostream>
#include <array> // std::array
bool isIn2DArray(const std::array<std::array<int, 3>, 2>& arr, int val) /* noexcept */
{
// range based for-loop instead of index based looping
for (const std::array<int, 3> & row : arr)
for (const int element : row)
if (element == val)
return true; // if found in the array, just return the boolean!
return false; // if not found!
}
int main()
{
std::array<std::array<int, 3>, 2> a{ { { 1,2,3 }, { 4,5,6 } } };
int userInput = 5;
if (isIn2DArray(a, userInput)) // you call the function like this!
{
std::cout << "Found in the array!\n";
}
else
{
std::cout << "Didn't find!\n";
}
}
In case of wondering, how to provide isIn2DArray for any arbitrary array, do it by providing the sizes as non-template parameters as below. (See live demo)
#include <array> // std::array
template<std::size_t Row, std::size_t Col>
bool isIn2DArray(const std::array<std::array<int, Col>, Row>& arr, int val)/* noexcept */
{
// range based for-loop instead of index based looping
for (const std::array<int, 3> & row : arr)
for (const int element : row)
if (element == val)
return true; // if found in the array, just return the boolean!
return false; // if not found!
}
If the array is an actual 2D array, if you know how to check if a number exists in a 1D array, you can use the exact same code to determine if a value exists in a regular 2D array.
The trick is to write the code using pointers to the start and ending elements of the array. The reason why is that a 2D array stores its data in contiguous memory, no different than a 1D array.
Here is an example of the same search function working for both 1-dimensional and 2-dimensional arrays:
#include<iostream>
bool exists(int *start, int *end, int value)
{
while (start != end)
{
if ( value == *start )
return true;
++start;
}
return false;
}
int main()
{
int a[3] = {4,5,6};
bool found = exists(a, a + 3, 5);
if ( found )
std::cout << "The number 5 was found\n";
else
std::cout << "The number 5 was not found\n";
// now a 2d array
int a2[3][4] = {{1,2,3,4},{7,8,9,10},{2,43,2,0}};
found = exists(&a2[0], &a2[2][4], 43);
if ( found )
std::cout << "The number 43 was found\n";
else
std::cout << "The number 43 was not found\n";
found = exists(&a2[0][0], &a2[2][4], 11);
if ( found )
std::cout << "The number 11 was found\n";
else
std::cout << "The number 11 was not found\n";
// Let's try a 3D array for fun
int a3[2][3][4] = {{{1,2,3,4},{7,8,9,10},{2,43,2,0}},
{{6,9,1,56},{4,8,2,10},{2,43,2,87}}};
found = exists(&a3[0][0][0], &a3[1][2][4], 56);
if ( found )
std::cout << "The number 56 was found\n";
else
std::cout << "The number 56 was not found\n";
}
Output:
The number 5 was found
The number 43 was found
The number 11 was not found
The number 56 was found
Surprisingly, the same function worked for 1-dimensional, 2-dimensional arrays, and even 3 dimensional arrays, all due to the data being stored in contiguous memory.
The address of the starting element, and the address of one past the ending element in the array are provided to the function, thus the function knows where to start and where to end the search.
bool check2dArray(vector<vector<int>> mat, int n){
int rows = mat.size();
if (rows==0) return false;
int cols = mat[0].size();
for (int i=0; i<rows; i++){
for (int j=0; j<cols; j++){
if (n == mat[i][j]) return true;
}
}
return false;
}
template <class Matrix, class CheckValue>
bool CheckExists(const Matrix& M, const CheckValue& Value) {
for (const auto& m : M)
for (const auto& v : m)
if (v == Value)
return true;
return false;
}
int main(int, char**)
{
int cArray[10][100]; auto exists = CheckExists(cArray, 10);
std::vector<std::vector<int>> vec; exists = CheckExists(vec, 0);
std::array<std::array<int, 10>, 100> arr; exists = CheckExists(arr, 0);
return 0;
}

Compare vector<string> and print yes or no using c++

I have two string vectors a and b with a[0]="hello",a[1]="world",b[0]="heyyy"and b[1]="namaste" and i have to decide whether the following a[0] and b[0] has anything matching and a[1] and b[1] has anything matching. If a[0] and b[0] has one or more characters matching then print "YES", else print "NO". Similarly if a[1] and b[1] has one or more characters matching then print "YES", else print "NO". For example from the above information, a[0] and b[0] have 'h' and 'e' as matching and a[1] and b[1] has no character matching. At the end, the expected output is
"YES"
"NO"
Based on the above information, being a beginner in C++ i developed a C++ program which is not even partially correct. It would be great if someone solve this. Thanks in advance.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
std::vector<string>a,b;
a={"hello", "world"};
b={"heyyy", "namaste"};
const char* acstr;
const char* bcstr;
acstr = a[0].c_str();
bcstr = b[0].c_str();
for(int i=0;i<sizeof(acstr);i++)
{
for(int j=0;j<sizeof(bcstr);j++)
{
if(acstr[i]==bcstr[j])
{
cout << "YES";
}
else{
continue;
}
}
}
return 0;
}
There is no need to convert an object of the type std::string to pointer like
acstr = a[0].c_str();
Also in this loop
for(int i=0;i<sizeof(acstr);i++)
the expression sizeof(acstr) does not give the length of the pointed string. It gives the size of the pointer itself that depending on the used system can be equal to 4 or 8 bytes independent on the length of the pointed string.
In general the vectors can have different number of elements. So you need to use the size of the smallest vector in a loop.
To determine whether a character is present in a string you can use method find of the class std::string.
Here is a demonstrative program.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::string> v1 = { "hello", "world" };
std::vector<std::string> v2 = { "heyyy", "namaste" };
std::vector<std::string>::size_type n = std::min( v1.size(), v2.size() );
for ( std::vector<std::string>::size_type i = 0; i < n; i++ )
{
std::string::size_type j = 0;
while ( j < v1[i].size() && v2[i].find( v1[i][j] ) == std::string::npos )
{
++j;
}
std::cout << ( j == v1[i].size() ? "NO" : "YES" ) << '\n';
}
return 0;
}
Its output is
YES
NO
Maybe you want like:
#include <bits/stdc++.h> // do not use this header
using namespace std;
int main()
{
std::vector<string>a, b;
a = { "hello", "world" };
b = { "heyyy", "namaste" };
for (int i = 0; i < (int)a.size(); i++)
{
bool bFound = false;
for (int j = 0; j < min(a[i].length(), b[i].length()); j++)
{
if (a[i][j] == b[i][j])
{
bFound = true;
}
}
cout << (bFound ? "YES" : "NO") << endl;
}
return 0;
}
Some advices:
You don't have to use c_str() to do character comparison.
sizeof(const char*) doesn't give you length of string. use strlen(const char*) if you want.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int flag = 0;
std::vector<string>a,b;
a={"hello", "world"};
b={"heyyy", "namaste"};
for(int k=0;k<2;k++){ //You can find and put the length of a or b, instead of using 2
for(int i=0;i<a[k].length();i++)
{
for(int j=0;j<b[k].length();j++)
{
if(a[k][i]==b[k][j])
{
flag = 1;
}
}
}
if(flag == 1){
cout << "YES\n";
}else{
cout << "NO\n";
}
flag = 0;
}
return 0;
}

Remove similar elements from 2 vectors (or list) not using <algorithm>

I want to remove similar elements from 2 vectors (or list) . I found a similar question here, he used <algorimth> to solve the problem. My question is is the any other approaches without using <algorimth>?
Mine is I create a vector to save the indices of the common elements, then delete the elements have the 'tagged' index. Wild idea though, this ain't work.
An example :
Vector A={1,2,3,4,5};
Vector B={2,3,4,6};
Vector result={1,5};
Here is a solution with lists that already takes care to SORT and UNIQUE the input.
//
#include "stdafx.h"
#include <list>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int A_arrey[] = { 1, 2, 4, 5, 7, 8 };
int B_arrey[] = { 1, 2, 3, 5, 6, 8, 9 };
list<int> A_list(A_arrey, A_arrey + 6);
list<int> B_list(B_arrey, B_arrey + 7);
A_list.sort();
A_list.unique();
B_list.sort();
B_list.unique();
for (int i = 0; i < sizeof(A_arrey) / sizeof(A_arrey[0]); i++)
B_list.remove(A_arrey[i]);
for (int i = 0; i < sizeof(B_arrey) / sizeof(B_arrey[0]); i++)
A_list.remove(B_arrey[i]);
A_list.merge(B_list);
cout << "My list contains:";
for (list<int>::iterator it = A_list.begin(); it != A_list.end(); it++)
std::cout << ' ' << *it;
cout << '\n';
}
In a case where all values are unique and sorted, the following would work:
#include <iostream>
#include <vector>
using namespace std;
vector<int> A={1,2,3,4,5};
vector<int> B={2,3,4,6};
vector<int> result;
int main()
{
int a = 0;
int b = 0;
while(a < A.size() && b < B.size())
{
/* Same value - skip to next on both sides */
if (A[a] == B[b])
{
a++;
b++;
}
else
/* Smaller value is unique, so push back that */
if (A[a] < B[b])
{
result.push_back(A[a]);
a++;
}
else
{
result.push_back(B[b]);
b++;
}
}
while (a < A.size())
{
result.push_back(A[a]);
a++;
}
while (b < B.size())
{
result.push_back(B[b]);
b++;
}
for(auto r : result)
{
cout << r << ", ";
}
cout << endl;
return 0;
}
There are a number of other methods. If the values aren't enormous, one could use an array to count up when you encounter the value in A, then count down for B, and then go through the array of counters when finished to give a list of unique values.
Edit: Updated with complete code that "works".
I think you need something like this:
vector<T> v(SIZE);
T tmp=v[0];
// ... Fill your vector here
for(int i=0;i<SIZE;++i)
v[i]==tmp?v.erase(i):tmp=v[i];