C++ Array comparison and printing difference - c++

The thing i want to do is compare two arrays, A and B, and post numbers from array B that doesn't appear in array A.
http://pastebin.com/u44DKsWf My full code.
Problem starts at line 42 i think.
int writingPosition = 1;
for (int c = 1; c<=firstArrayLength; c++)
{
for(int z = 1; z>secondArrayLength; z++)
{
if (firstArray[c] != secondArray[z])
{
thirdArray[writingPosition] = secondArray[z];
writingPosition++;
}
if (firstArray[c] == secondArray[z])
{
thirdArray[c] == '0'; // NEED FIXING I GUESS
}
}
}
The idea is that i mark numbers that dont fit my task as '0', so later on i can print array while ignoring 0.
Thank you!

You could use binary_search from algorithm module from C++ Standard Library.
Note this works with std::vector aswell.
Live demo
#include <array>
#include <iostream>
#include <algorithm>
int main()
{
std::array<int, 3> firstArray { 1, 3, 5 }; // stack based array like int[3]
std::array<int, 3> secondArray { 2, 3, 4 };
// Sort first array to be able to perform binary_search on it
std::sort(firstArray.begin(), firstArray.end());
for (const auto secondArrayItem : secondArray)
{
// Binary search is a very efficient way of searching an element in a sorted container of values
if (std::binary_search(firstArray.begin(), firstArray.end(), secondArrayItem) == false)
{
std::cout << "Item " << secondArrayItem << " does not exist in firstArray" << std::endl;
}
}
return 0;
}

Correction to your code should be somewhat like :
int writingPosition = 1;
for (int c = 1; c<=firstArrayLength; c++)
{
for(int z = 1; z<=secondArrayLength; z++)
{
if (firstArray[c] != secondArray[z])
{
thirdArray[writingPosition] = secondArray[z];
writingPosition++;
}
if (firstArray[c] == secondArray[z])
continue;
}
}
On a side note : Prefer using 0 as the base index for arrays.

There are many things wrong with your code.
Arrays of size s always range from 0 to s-1, so in your case you should use
for(int g = 0; g<50; g++)
i.s.o.
for(int g = 0; g<=50; g++)
and similar for the other arrays
Secondly, you fill the third array with char elements, and then compare them to int
thirdArray[c] == '0';
and later
if(thirdArray[g] != 0)
Either use '0' or 0 both times, but don't mix them up.
But the general algorithm doesn't make much sense either, you're overriding third array both based on index c as index z.
Also the range on z makes little sense.
(I assume this is homework or at least you're trying to study, so won't simply give a solution)

why don't you store the numbers that doesn't exist in a string and then you print the string from cout? this is how you can do this:
string output = "";
bool isFound = false;
for (int c = 1; c<=secondArrayLength; c++)
{
isFound = false;
for(int z = 1; z>firstArrayLength; z++)
{
if (secondArray[c] == firstArray[z])
{
isFound = true;
}
}
if(!isFound)
output+=(secondArray[c].str()+" ");
}
cout<<output;
try this it must work fine

Related

How to compare values of two vectors

Is anybody there who has a code on how to compare values of two arrays ?
I have two vectors and I am looking for the biggest and equal value of the both list.
Here is the code:
void fractionInLowestTerm(int fNumerator, int fDenominator)
{
//let's get the dividers of fNumerator and fDenominator
std::vector<int> dividerOfNumerator;
std::vector<int> dividerOfDenominator;
for (int i = 1; i <= fNumerator; i++) {
if (fNumerator % i == 0) {
dividerOfNumerator.push_back(i);
}
}
for (int j = 1; fDenominator <= j; j++) {
if (fDenominator % j == 0) {
dividerOfDenominator.push_back(j);
}
}
// let's get the greatest common divider of a and b;
int pgcd = 1;
// I do not know how to compare the values of dividers to get the greatest common value on a and b there is the code I started writing to get that
for (int m = 0; m <= dividerOfNumerator.size() && m <= dividerOfDenominator.size(); m++) {
}
}
If I understand the problem correctly, you want to compare the elements in two arrays for each index and save the greater one into a third array. In this case, just use your favourite max function for each index. For example:
void compare(int* array1, int* array2, int* array3, int size)
{
for (int member = 0; member < size; ++member) {
array3[member] = std::max(array1[member], array2[member]);
}
}
or if you want to compare lists and write into third array that which array has bigger value in that index you can use following code
void compare(int* array1, int* array2, int* array3, int size)
{
for (int member = 0; member < size; ++member) {
if (array1[member] > array2[member]) {
array3[member] = 1;
}
else if (array1[member] < array2[member]) {
array3[member] = 2;
}
else if (array1[member] == array2[member]) {
array3[member] = 0;
}
}
}
Since the vectors containing the divisors are already sorted, you can use the std::set_intersection algorithm like this:
std::vector<int> commonDivisors;
std::set_intersection(dividerOfNumerator.begin(), dividerOfNumerator.end(),
dividerOfDenominator.begin(), dividerOfDenominator.end(),
std::back_inserter(commonDivisors));
int pgcd = commonDivisors.back(); // guaranteed to be non-empty since 1 is always a divisor
Here's a demo.
Hello as you can see on the function name I wanted to write a function which put a function on the lowest term. I wanted to go through the gcd but I saw that it would consumes too much memory so here is what I've done. If it can help any member of the forum.
void fractionInLowestTerm(int fNumerator, int fDenominator){
//let's get on the divider of the number
for (int i = 1; i < fNumerator and i <fDenominator; i++) {
if (fNumerator%i == 0 and fDenominator%i == 0) {
fNumerator /= i;
fDenominator /= i;
i = 1;
}
}
}

Vector Subscript out of Range. Comparing Elements of Vectors

So I have a vector like this
All_Pos={0,10,15,24,30,33,66}
And three smaller vectors that contain the numbers from the previous vector, let's say
Vec_Lin={0,15}
Vec_Circ={24,33,66}
Vec_Arc={10,30}
I want to make something like this:
All_Pos[0]=Vec_Lin[0]? YES -> Do something
All_Pos[1]=Vec_Lin[1]?No
All_Pos[1]=Vec_Circ[0]?No
All_Pos[1]=Vec_Arc[0]?Yes -> Do Something
Ans so on, until i finish my All_Pos. The problem is that i get vector out of range and i don't know how to fix that.
int counter_linie=0;
int counter_cerc=0;
int counter_arc=0;
for (int p = 0; p < All_pos.size(); p++)
{
if(All_pos[p] == Vec_Lin[counter_linie])
{
//Do something
counter_linie++;
}
if (All_pos[p] == Vec_circ[counter_cerc])
{
//Do something
counter_cerc++;
}
if (All_pos[p] == Vec_Arc[counter_arc])
{
/Do something
counter_arc++;
}
}
You should check for out of range. [] operator works ,when indexing is in limits from '0' to vector.size().
void process_vector(void)
{
std::vector<int> All_Pos = { 0,10,15,24,30,33,66 };
std::vector<int> Vec_Lin = { 0,15 };
std::vector<int> Vec_Circ = { 24,33,66 };
std::vector<int> Vec_Arc = { 10,30 };
int counter_linie = 0;
int counter_cerc = 0;
int counter_arc = 0;
for (int p = 0; p < All_Pos.size(); p++) {
if (counter_linie< Vec_Lin .size() && All_Pos[p] == Vec_Lin[counter_linie])
{
//Do something
counter_linie++;
}
if (counter_cerc < Vec_Circ.size() && All_Pos[p] == Vec_Circ[counter_cerc])
{
//Do something
counter_cerc++;
}
if (counter_arc < Vec_Arc.size() && All_Pos[p] == Vec_Arc[counter_arc])
{
// Do something
counter_arc++;
}
}
std::cout << counter_linie << " " << counter_cerc << " " << counter_arc << std::endl;
}
You are trying to access elements that don't exist in your smaller vectors.
Vec_circ can only be accessed with indices 0, 1 and 2, but after three successful checks for Vec_circ in your loop counter_cerc will be 3.
Trying to access Vec_circ[3] then leads to the error.
You need a mechanism that prevents this case.
You should step through your code with a debugger to see the problem.
Initially the values are:
int counter_linie=0;
int counter_cerc=0;
int counter_arc=0;
After the first iteration the values are:
counter_linie=1;
counter_cerc=0;
counter_arc=0;
After the second iteration the values are:
counter_linie=1;
counter_cerc=0;
counter_arc=1;
After the third iteration the values are:
counter_linie=2;
counter_cerc=0;
counter_arc=1;
And now you try to read
Vec_Lin[2]
in
if(All_pos[p] == Vec_Lin[counter_linie])
That's your problem. Add a check into the if conditions.
if(counter_linie < Vec_Lin.size() && All_pos[p] == Vec_Lin[counter_linie])

Problems with vectors, how to remove the arrays in my vectors?

I have created a function that creates all the possible solutions for a game that I am creating... Maybe some of you know the bullcow game.
First I created a function that creates a combination of numbers of max four integers and the combination can't have any repeating number in it... like...
'1234' is a solution but not '1223' because the '2' is repeating in the number. In total there is 5040 numbers between '0123' and '9999' that haven't repeating numbers.
Here is my function:
std::vector <std::array<unsigned, 4>> HittaAllaLosningar(){
std::vector <std::array<unsigned, 4>> Losningar;
for (unsigned i = 0; i < 10; i++) {
for (unsigned j = 0; j < 10; j++) {
for (unsigned k = 0; k < 10; k++) {
for (unsigned l = 0; l < 10; l++) {
if (i != j && i != k && i != l && j != k && j != l && k != l) {
Losningar.push_back({i,j,k,l});
}
}
}
}
}
return Losningar;
}
Now let's say I have the number '1234' and that is not the solution I am trying to find, I want to remove the solution '1234' from the array since that isn't a solution... how do I do that? have been trying to find for hours and can't find it. I have tried vector.erase but I get errors about unsigned and stuff... also its worth to mention the guesses are in strings.
What I am trying to do is, to take a string that I get from my program and if it isn't a solution I want to remove it from the vector if it exists in the vector.
Here is the code that creates the guess:
std::string Gissning(){
int random = RandomGen();
int a = 0;
int b = 0;
int c = 0;
int d = 0;
for (unsigned i = random-1; i < random; i++) {
for (unsigned j = 0; j < 4; j++) {
if (j == 0) {
a = v[i][j];
}
if (j == 1) {
b = v[i][j];
}
if (j == 2) {
c = v[i][j];
}
if (j == 3) {
d = v[i][j];
}
}
std::cout << std::endl;
AntalTry++;
}
std::ostringstream test;
test << a << b << c << d;
funka = test.str();
return funka;
}
The randomgen function is just a function so I can get a random number and then I go in the loop so I can take the element of the vector and then I get the integers of the array.
Thank you very much for taking your time to help me, I am very grateful!
You need to find the position of the element to erase.
std::array<unsigned, 4> needle{1, 2, 3, 4};
auto it = std::find(Losningar.begin(), Losningar.end(), needle);
if (it != Losningar.end()) { Losningar.erase(it); }
If you want to remove all the values that match, or you don't like checking against end, you can use std::remove and the two iterator overload of erase. This is known as the "erase-remove" idiom.
std::array<unsigned, 4> needle{1, 2, 3, 4};
Losningar.erase(std::remove(Losningar.begin(), Losningar.end(), needle), Losningar.end());
To erase from a vector you just need to use erase and give it an iterator, like so:
std::vector<std::array<unsigned, 4>> vec;
vec.push_back({1,2,3,4});
vec.push_back({4,3,2,1});
auto it = vec.begin(); //Get an iterator to first elements
it++; //Increment iterator, it now points at second element
it = vec.erase(it); // This erases the {4,3,2,1} array
After you erase the element, it is invalid because the element it was pointing to has been deleted. Ti continue to use the iterator you can take the return value from the erase function, a valid iterator to the next element after the one erased, in this the case end iterator.
It is however not very efficient to remove elements in the middle of a vector, due to how it works internally. If it's not important in what order the different solution are stored, a small trick can simplify and make your code faster. Let's say we have this.
std::vector<std::array<unsigned, 4>> vec;
vec.push_back({1,2,3,4});
vec.push_back({4,3,2,1});
vec.push_back({3,2,1,4});
To remove the middle one we then do
vec[1] = vec.back(); // Replace the value we want to delete
// with the value in the last element of the vector.
vec.pop_back(); //Remove the last element
This is quite simple if you have ready other functions:
using TestNumber = std::array<unsigned, 4>;
struct TestResult {
int bulls;
int cows;
}
// function which is used to calculate bulls and cows for given secred and guess
TestResult TestSecretGuess(const TestNumber& secret,
const TestNumber& guess)
{
// do it your self
… … …
return result;
}
void RemoveNotMatchingSolutions(const TestNumber& guess, TestResult result)
{
auto iter =
std::remove_if(possibleSolutions.begin(),
possibleSolutions.end(),
[&guess, result](const TestNumber& possibility)
{
return result == TestSecretGuess(possibility, guess);
});
possibleSolutions.erase(iter, possibleSolutions.end());
}
Disclaimer: it is possible to improve performance (you do not care about order of elements).

Fastest method to check if all elements of 2d array are equal

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

How to find a char array in another one in c++?

I want to write a code to find a char array in another one and print out place(element) of first occur of first array. I wrote my own code and it works. But it "seems" kind of messy. Does anyone have better idea to rewrite this code?
"only strlen() is allowed. I need to write it by designing loops."
Here's the code
#include <iostream>
#include <string.h>
using namespace std;
const int len = 100;
int main() {
int i, j, k, l;
char a[len]="leonardo" , b[len]="nar";
bool es1 = false, es2=false;
i = 0;
while(i < len && !es1)
{
j = 0;
if(a[i] == b[j])
{
k = i+1;
l = j;
while (k < i+strlen(b) && !es2)
{
j = j+1;
if (a[k] == b[j]) k = k+1;
else es2 = true;
}
if (a[i+strlen(b)-1]==b[l+2] && !es2) es1 = true;
else i = i+1;
}
else i= i+1;
}
cout << endl << "element: " << i;
return 0;
}
By the way this not a real homework. I just make myself ready for a programming exam.
I just find out that the code doesn't work fine if array b[] is shorter than 3 elements. So it seems the code needs major review!
The easy way to do it would be to use std::search:
auto it = std::search(a, a + 8, b, b + 3));
Here, it points to the beginning of the found sequence in a, or to std::end(a) if not found.
This looks like substring search algorithm. You can use any of the recognized algorithms like KMP.
Can you use a string instead of a char array? If so, you can use string::find.
http://www.cplusplus.com/reference/string/string/find/
bool bFound = strA.find(strB)