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;
}
}
}
Related
I am having an issue trying to determine if my arrays contain any duplicate integers. For my Lo Shu Magic Square project, we are to create three different 1-dimensional arrays along with different functions to determine if the input is magic square numbers. I was able to make all other functions work but I cant seem to figure out how to check if the combined array inputs are all unique. Can anyone help? Here is my source code for bool checkUnique.
bool checkUnique(int arrayRow1[], int arrayRow2[], int arrayRow3[], int TOTAL_NUM)
{
int combinedArray[] = { arrayRow1[0], arrayRow1[1], arrayRow1[2],
arrayRow2[0], arrayRow2[1], arrayRow3[2],
arrayRow3[0], arrayRow3[1], arrayRow3[2] };
for (int counter = 0; counter < TOTAL_NUM; counter++)
{
for (int j = counter; j < TOTAL_NUM; j++)
{
if (j != counter) {
if (combinedArray[counter] == combinedArray[j])
{
return true;
}
}
return false;
}
}
}
I added all elements(TOTAL_NUM = 9) from three different arrays into a new array called combinedArray. When I ran my code and entered 1 2 3 4 5 6 7 8 9, result is still showing that there are duplicates. I tried different methods I found online but still cant get this function to work. Any help would be greatly appreciated
You're quite close to a correct solution, which might look like this:
bool checkUnique(int arrayRow1[], int arrayRow2[], int arrayRow3[], int TOTAL_NUM)
{
int combinedArray[] = { arrayRow1[0], arrayRow1[1], arrayRow1[2],
arrayRow2[0], arrayRow2[1], arrayRow3[2],
arrayRow3[0], arrayRow3[1], arrayRow3[2] };
for (int counter = 0; counter < TOTAL_NUM; counter++)
{
for (int j = counter; j < TOTAL_NUM; j++)
{
if (j != counter) {
if (combinedArray[counter] == combinedArray[j])
{
return true;
}
}
}
}
return false;
}
The only change relative to your code is that I moved return false; behind the loops. Why? Because you need to check all pairs before you can assert that there are no duplicates.
This solution might be further improved by changing the starting index of the inner loop:
bool checkUnique(int arrayRow1[], int arrayRow2[], int arrayRow3[], int TOTAL_NUM)
{
int combinedArray[] = { arrayRow1[0], arrayRow1[1], arrayRow1[2],
arrayRow2[0], arrayRow2[1], arrayRow3[2],
arrayRow3[0], arrayRow3[1], arrayRow3[2] };
for (int counter = 0; counter < TOTAL_NUM; counter++)
{
for (int j = counter + 1; j < TOTAL_NUM; j++)
{
if (combinedArray[counter] == combinedArray[j])
return true;
}
}
return false;
}
Here I changed the initializer of the inner loop into int j = counter + 1 so that I'm sure that j will never be equal to counter.
In this solution you need to make up to 36 comparisons. Alternative approaches:
sort combinedArray and check via std::unique whether it contains duplicates.
insert the elements into std::set and check if its size is 9
Since your array is small, these more universal solutions may be not optimal, you'd need to make tests.
Finally a side remark: try to use consistent names to your variables. counter looks very different from j, which suggests that there's a fundamental difference between the two loop control variables. But there's none: they're very similar to each other. So give them similar names. In the same spirit, please use more useful function names. For example, I'd prefer allUnique that would return true if and only if all input umbers are unique. Compare if (checkUnique(a, b, c, 9)) with if (allUnique(a, b, c, 9)). Of course this, in fact, should be called if allUnique(a, b, c, 3), because the information about array lengths is more fundamental than about the effective buffer length.
EDIT
Actually, you have not defined precisely what the expected output of your function is. If you assume that checkUnique should return true if all numbers are different, then rename it to something more significant and swap all true and false:
bool allUnique(int arrayRow1[], int arrayRow2[], int arrayRow3[], int TOTAL_NUM)
{
int combinedArray[] = { arrayRow1[0], arrayRow1[1], arrayRow1[2],
arrayRow2[0], arrayRow2[1], arrayRow3[2],
arrayRow3[0], arrayRow3[1], arrayRow3[2] };
for (int counter = 0; counter < TOTAL_NUM; counter++)
{
for (int j = counter + 1; j < TOTAL_NUM; j++)
{
if (combinedArray[counter] == combinedArray[j])
return false;
}
}
return true;
}
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).
I am trying to create a function that will find the intersection of two dynamically allocated arrays comparing array 1 to array 2. For any values in array 1 that are not in array 2, those values should be deleted in array 1 so that array 1 now only holds the common values of both arrays (no repeats). I cannot use vectors, hashes, or any other thing outside of my current functions in my class:
here is my code so far:
bool IntSet::contains(int val) const
{
for (int i = 0; i < numValues; i++)
{
if (set[i] == val)
return true;
}
return false;
}
this function compares an integer parameter to values currently stored in the array...if a value is in the array it returns true and if else false;
this next function takes in a value and removes that value from the array:
void IntSet::remove(int val)
{
for (int i = 0; i < numValues; i++)
{
if (set[i] == val)
for (int j = 0; j < numValues; j++)
set[j] = set[j + 1];
}
numValues--;
}
here's where I've been having problems, this next function is supposed to iterate through one array and compare those values with the values in the other array...if one value from one array is in the other, it should just skip it, but if a value is not in the array calling the function, it should delete that value from the calling array:
void IntSet::removeDifferent(const IntSet &set2)
{
for (int i = 0; i < set2.size(); i++)
{
if (!set2.contains(set[i]))
{
remove(set[i]);
}
}
}
ive tried about 50 different variations on the removeDifferent() function and I just can't seem to figure this one out. Could someone point me in the right direction?
You're iterating i through the indexes of set2, but then you're testing set[i]. Try this:
void IntSet::removeDifferent(const IntSet &set2)
{
for (int i = 0; i < numValues; ) {
if (!set2.contains(set[i])) {
remove(set[i]);
} else {
i++;
}
}
Note that I also removed i++ from the for loop header. This is because when you remove an element, all the following elements are shifted down, so the next element takes its place in the array. If you incremented i, it would skip that element.
You also need to fix remove. It should start its inner loop from i, so it only shifts down the elements after the one being removed, and it should stop at numValues-1, so it doesn't try to access outside the array when it copies set[j+1]. And as an optimization, it can break out of the outer loop once it has found a match (I assume IntSet doesn't allow duplicates, since you only decrement numValues by 1).
void IntSet::remove(int val)
{
for (int i = 0; i < numValues; i++)
{
if (set[i] == val) {
for (int j = i; j < numValues - 1; j++) {
set[j] = set[j + 1];
}
break;
}
}
numValues--;
}
Your problem is in your remove() function:
void IntSet::remove(int val)
{
for (int i = 0; i < numValues; i++)
{
if (set[i] == val)
for (int j = 0; j < numValues; j++)
set[j] = set[j + 1];
}
numValues--;
}
You can figure out yourself why this is wrong by using a paper and pencil here. Start with a typical example: let's say you found the value you're looking for in the third element of a five-element array:
if (set[i] == val)
In this example, i would be set to 2, and numValues would be set to five. It doesn't matter what val is. Whatever it is, you found it when i is 2, and numValues is five: you found it in the third element of a five element array. Keep that in mind.
Now, you know that you are now supposed to remove the third element in this five element array. But what do you think will happen next:
for (int j = 0; j < numValues; j++)
set[j] = set[j + 1];
Well, using the aforementioned paper and pencil, if you work it out, the following will happen:
set[1] will be copied to set[0]
set[2] will be copied to set[1]
set[3] will be copied to set[2]
set[4] will be copied to set[3]
set[5] will be copied to set[4]
There are two problems here:
A) There is no set[5]. Recall that this is a five-element array, si you only have set[0] through set[4]
B) You're not supposed to copy everything in array down to one element. You have to copy only the elements after the element you want to remove.
Fix these two problems, and you will probably find that everything will work correctly.
I'm trying to do a method where I have to delete a number from a vector of integers, and that number is passed as a parameter. The problem that I'm having right now is that when I try to delete the same number in consecutive positions, only one of them is deleted.
For example:
vector = (1, 2, 2, 3, 4, 5) and I want to remove the number "2", the result will be:
vector = (1, 2, 3, 4, 5)
But if the number is not in consecutive positions, the method works fine:
vector = (1, 2, 3, 2, 4, 5) ---> remove "2"
vector = (1, 3, 4, 5)
The code that I have is this:
void deleteNumber(int n, vector<int> &numbers)
{
bool hasEntered = false;
int counter = 0;
vector<int> deletedNumbers;
for(unsigned i = 0; i < numbers.size(); i++)
{
if(numbers[i] != n)
{
counter++;
}
else
{
counter = 0;
int counter2 = 0;
bool deleted = false;
for(unsigned j = 0; j < deletedNumbers.size() && deleted == false; j++) // Check if a number has been deleted before
{
if(deletedNumbers[j] != n)
{
counter2++;
}
else
{
deleted = true;
counter2 = 0;
}
}
if(counter2 == (int) deletedNumbers.size()) // Remove the number if it hasn't been removed
{
deletedNumbers.push_back(n);
for(unsigned k = 0; k<numbers.size(); k++)
{
if(numbers[k] == n)
numbers.erase(numbers.begin()+k);
}
counter2 = 0;
hasEntered = true;
}
}
}
}
I think that the error could be in the condition of the last for, where I finally remove the number.
The counters are used in order to determine if an element has been found or not. And also the method has to check if the item has been removed before.
If you don't understand something, please ask me.
Thanks in advance :)
you could try something like this:
void deleteNumber(int n, vector<int> &numbers)
{
vector<int>numbers_without_n;
for(unsigned i = 0; i < numbers.size(); i++)
if(numbers[i] != n)
numbers_without_n.push_back(numbers[i]);
numbers = numbers_without_n;
}
Your code looks like too complicated, thus it can contain many bugs.
This would delete all instances of n; O(numbers.size()):
void deleteNumber(int n, vector<int> &numbers) {
int i = 0;
for (int j = 0; j < numbers.size(); ++j) {
if (numbers[j] != n) numbers[i++] = numbers[j];
}
numbers.resize(i);
}
This would delete the first instance of n in each run; O(numbers.size()):
void deleteNumber(int n, vector<int> &numbers) {
int i = 0;
for (int j = 0; j < numbers.size();) {
if (numbers[j] == n) {
for (++j; j < numbers.size() && numbers[j] == n; ++j) {
numbers[i++] = numbers[j];
}
} else {
numbers[i++] = numbers[j++];
}
}
numbers.resize(i);
}
This would delete the first instance of n; O(numbers.size()):
void deleteNumber(int n, vector<int> &numbers) {
int i = 0;
for (int j = 0; j < numbers.size(); ++j) {
if (numbers[j] == n) {
for (++j; j < numbers.size(); ++j) {
numbers[i++] = numbers[j];
}
break;
}
numbers[i++] = numbers[j];
}
numbers.resize(i);
}
Pick whichever you need.
Please note that other answers, such as luk32's answer contain simpler code (using more STL) for deleting the first instance of n.
If you want to find and fix the bug in your code, I recommend that you try to find a very short input vector for which it fails, and then single-step through it in a debugger.
You don't need to have a loop inside the loop. The easiest way to handle the delete is to delete one item at a time and realize that this will mean you don't want to increment i when you have deleted an item. The easiest way to cancel the increment of i in the for loop is to decrement it first using --i. So you loop becomes
Check if the item matches the number
If so, delete the item and decrement i
Use std::remove and vector::erase
#include <algorithm>
void deleteNumber(int n, vector<int>& numbers)
{
numbers.erase(std::remove(numbers.begin(), numbers.end(), n), numbers.end());
}
First, I'm not sure what counter and counter2 are used for - if they're just being used to determine if you've iterated to the end of the vector without finding an element, you don't need them.
For the purpose of 'check if a number has been deleted', you just need a single boolean variable at the very top of the method, i.e. not inside the scope of the for loop.
I believe the following:
if(counter2 == (int) deletedNumbers.size()) // Remove the numbers if it hasn't been removed
can be replaced with if (!deleted).
So, here's a 'fixed' version while trying to stay as close to your existing logic as possible based on your code comments. This may not be the most efficient/elegant implementation however, I believe I have seen some other answers that use algorithms from the STL library to achieve the same thing.
void deleteNumber(int n, vector<int> &numbers)
{
bool deleted = false;
for(unsigned i = 0; i < numbers.size(); i++)
{
if (numbers[i] == n) // If we've found an instance of the number we're trying to delete
{
if (!deleted) // Check if an instance has already been deleted
{
numbers.erase(numbers.begin() + i); // Remove the number
deleted = true; // Flag that we have deleted an instance of the number
}
}
}
}
Alternately, instead of using a flag for 'deleted' to prevent deleting numbers after the first instance, you could optimize by just returning after you delete the first instance - that will prevent the rest of the loop from executing.
Ok, since apparently std::vector::erase does exists I would use standard c++ features:
void deleteNumber(int n, vector<int> &numbers) {
auto it = find(std::begin(numbers), std::end(numbers), n);
if(it != numbers.end()) numbers.erase(it);
}
EDIT: Forgot that end() is not a valid argument for erase.
I have a probably very simple question but I can't see the solution.
First, I have a struct named Seed with the following code:
struct Seed
{
int x, y;
int i, j;
int Type;
};
I then create a 2D array and a queue, respectively, like so:
Seed Grid[ROW][COL];
std::queue<Seed> SeedsToUpdate;
I populate the grid with a loop:
void CApp::LoopSeeds(int function, int Type)
{
for(int i = 0;i < ROW;i++)
{
for(int j = 0;j < COL;j++)
{
switch (function)
{
case SET:
SetSeed(i, j, Type);
break;
case DRAW:
DrawSeed(i,j);
break;
case GROW:
GrowSeed(i,j,Type);
}
}
}
}
Then, I set individual seeds in the array to other types, such as GREEN. I then fill the queue by going through the array and filling it with all array elements that have the GREEN type:
void CApp::BuildQueue()
{
for(int i = 0;i < ROW;i++)
{
for(int j = 0;j < COL;j++)
{
if (Grid[i][j].Type != SEED_EMPTY)
{
SeedsToUpdate.push(Grid[i][j]);
}
}
}
}
At this point, everything is good (I think). However, what I want to do is the following: for each seed in the queue, edit the neighbouring cells in the array, something like Grid[i+1][j].Type = GREEN;
And here is my problem: how do I do that, given the above code?
Thanks for your patience.
In C++11
for(const Seed& seed: SeedsToUpdate){
if (seed.i + 1 < ROW){
Grid[seed.i+1][seed.j].type = seed.type
}
}
C++03 with Boost
BOOST_FOREACH(const Seed& seed, SeedsToUpdate){
if (seed.i + 1 < ROW){
Grid[seed.i+1][seed.j].type = seed.type
}
}
In C++03 (without Boost)
for(std::queue<Seed>::const_iter it = SeedsToUpdate.begin(); it != SeedsToUpdate.end(); ++it) {
const Seed& seed = *it;
if (seed.i + 1 < ROW){
Grid[seed.i+1][seed.j].type = seed.type
}
}
Also you should be using std::array/boost::array instead of raw arrays.
its pretty straight forward actually. Inside your inner loop, do something line
if (i+1 < ROW) {
Grid[i+1][j].Type = GREEN;
SeedsToUpdate.push(Grid[i+1][j]);
}