what is the recursive form of this code? - c++

I was trying to locate vector a in vector b. So it's like if vector a is in vector b then return true else false. And vector a should be like {1,2,3} and b should like {4,1,2,3,5,5,7}. The output of this code is coming like true 1 and false 0. So my problem is I don't want 1 and 0 to show up in the output.
Also I want to write this code in recursive form so could anyone help me with this problem?
bool x(vector<int>& a, vector<int> b)
{
vector<int> index ( b.size(),0 );
int counter = 0;
if ( a.size() <= b.size() ) {
for ( int i = 0; i < a.size(); i++ ) {
for ( int j = 0; j < b.size(); j++ ) {
if ( a[i]== b[j]) {
index[j] = 1;
}
}
}
for ( int i = 0; i < index.size(); i++ ) {
if ( index[i] == 1 ) {
for ( int j = i; j < index.size(); j++ ) {
if ( index[j] == 1 ) {
counter++;
}
}
if(counter == a.size()){
cout<<"true"<<endl;
return true;
break;
}
else{
counter = 0;
cout<<"false"<<endl;
return false;
// continue;
}
}
}
}
return 0;
}

if you just don't like the output: true 1 and false 0. the simplest way to solve it is:
if(x(a, b)){
cout<<"true"<<endl;
} else {
cout<<"false"<<endl;
}
BUT, before you try to convert you algorithm to a recursive one, I afraid that your algorithm is wrong. try this:
vector<int> a;
vector<int> b;
a.push_back(1);
a.push_back(2);
a.push_back(3);
b.push_back(1);
b.push_back(1);
b.push_back(1);
cout<<x(a,b)<<endl;
you will get true ,and the correct answer is false.
check your algorithm !

The reason you're seeing "true 1" and "false 0" is probably because while you print "true" and "false" as strings in your function, you return a bool, which if you print outside the function will be default print as "1" and "0". To overcome that, you can use std::boolalpha as discussed here: Converting bool to text in C++
As for converting your algorithm to a recursive one, I'm afraid that's off topic for Stack Overflow until you try it yourself.

Like John said, you're printing the cout (standard out) Strings, not integers (1/0). Also agree with the off-topic, you need to suggest a solution and ask for help/recommendations/feedback. There's a heap of tutorials on the net about how to it.
But if you want to recurse, you should create an array3 whose length is the same size array1, whereas you'll recurse over array2 to check if any elements of array2 exist (either as objects or as values) in array1. You'll need a function that produces an array and takes in arrays (why are you using vectors?) and then iterates over the 2nd array, passing array1, array3 and current index value as arguments.
Fibonacci recursive problem is taught in just about every programming course in Uni (or at least it should be), so it's a good starting point to look at.

Recursion function of this :
// it will return true if vector is present
// i is pointer for a
// j is pointer for b
bool subVector(vector<int>& a, vector<int> b,i,j)
{
if( i<a.size() && j<b.size()
{
if(a[i]==b[i])
{
return subVector(a,b,i+1,j+1)
}
else
{
return subVector(a,b,0,j+1)
}
}
else
{
if(i>a.size())
{
return true;
}
else{
return false;
}
}
}
// Calling
subVector(a,b,0,0);
Note : Not Compiled.

Related

Is there a test case where this code can break?

This is the problem I am trying to solve.
Given two arrays a and b, check whether they are similar.
Two arrays are called similar if one can be obtained from another by swapping at most one pair of elements in one of the arrays.
I wrote the following code to solve the problem. I tried to make some optimizations but it fails on a hidden test. Can anyone help me find where the code could break?
bool is_similar(vector<int> a, vector<int> b, int start){
return memcmp(a.data() + start, b.data() + start, (a.size() - start) * sizeof(int)) == 0;
}
bool solution(vector<int> a, vector<int> b) {
int sizea = a.size(), sizeb = b.size();
if(sizea != sizeb) return false;
for(int i = 0; i < sizea; i++){
if(a[i] != b[i]){
auto it = find(b.begin() + i + 1, b.end(), a[i]);
if(it != b.end()){
swap(b[i], *it);
return is_similar(a, b, i + 1);
}
return false;
}
}
return true;
}
I started from scratch again and came up with a much better solution. Thank you all for your input. I'm loving this platform
The main problem was assuming the inputs were unique. This is the general flow of the initial code. A good test case to demonstrate the fault is when a = [0,1,1,3,4], b = [0,4,1,3,1]
Loop for the length of one of the arrays (they are of equal length)
Do nothing if the values are equal at the same index
If the values are not equal (now we are at index 1), search for 1 in array b and swap it with the current index. b becomes [0,1,4,3,1]
Now if we go on and call is_similar(a,b), it returns false.
Clearly if we swapped the contents at index 1 and 4, in array b, the arrays would be similar. That is why it fails.
A better approach is to collect the values at the indices where the values are different and determine if one swap is enough to make the two arrays similar. This is the code snippet.
bool solution(vector<int> a, vector<int> b) {
int sizea = a.size(), sizeb = b.size();
if(sizea != sizeb) return false;
int i= 0;
vector<int> a1;
vector<int> b1;
for(i = 0; i < sizea; i++){
if(a[i] != b[i]){
a1.emplace_back(a[i]);
b1.emplace_back(b[i]);
}
}
if(a1.size() == 0) return true;
if(a1.size() == 2) return a1[0] == b1[1] && a1[1] == b1[0];
return false;
}

Error when applying a function multiple times

I wrote a function to find all combinations of integers between two bounds. To do this, I wrote a function with the same name that finds all combinations of integers between two bounds of a certain size.
In main, I set up a loop to call this function multiple times. When it is ran more than once with bounds that are sufficiently far apart, it causes an error, that is, the code reaches the logic error in the first function.
I do not know why multiple passes in the while-loop causes a problem because the variables should be reset each time.
#include <vector>
#include <stdexcept>
#define VAR1 3
#define VAR2 8
bool nextCombination(std::vector<int> &combo, int numItems, \
int lowerBound, int upperBound) {
if (combo.empty()) { //This is the first take.
for (int i = 0; i < numItems; ++i) {
combo.push_back(lowerBound + i);
}
return true;
} else if (combo[0] >= upperBound - numItems) { //This cleans up.
combo.clear();
return false;
} else {
for (int i = 0; i < numItems; ++i) {
if (i >= numItems || combo[i]+1 != combo[i+1]) {
++combo[i]; //This extends the front of the stack.
return true;
} else { //This pushes the first part of the stack back.
combo[i] = lowerBound + i;
}
}
}
throw std::logic_error("There is an error with nextCombination.");
}
bool nextCombination(std::vector<int> &combo, int lowerBound, int upperBound) {
int numItems = combo.size();
if (numItems >= upperBound - lowerBound) {
combo.clear();
return false;
} else if (numItems == 0) {
combo.push_back(0);
return true;
} else {
if (nextCombination(combo, numItems, lowerBound, upperBound)) {
return true;
} else {
combo.clear(); //This line shouldn't be needed.
return (nextCombination(combo, numItems+1, lowerBound, upperBound));
}
}
}
int main() {
for (int i = 0; i < VAR1; ++i) {
std::vector<int> combo;
while (nextCombination(combo, 0, VAR2)) ;
}
return 0;
}
I don't understand the algorithm, but the problems are clear enough.
Step one, reduce the size of the problem I chose
#define VAR1 1
#define VAR2 2
Run the code, crash in operator[] here,
if (i >= numItems || combo[i]+1 != combo[i+1])
Values of variables
combo = vector of size 1
numItems = 1
i = 0
combo[i+1] is a subscript out of bounds error.
It doesn't take long to step through the code to get to this point. It happens immediately on the second iteration of the inner loop in main. Since I don't understand what your code is trying to do I can't suggest a fix. But hopefully the error is clearer to you now.
Since it seems you were unaware of this subscripting issue, you should change to using at instead of [] that way you get defined behaviour even on a subscript error.

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])

conditionally testing for equality of vector's elements

Although it seems pretty simple, I'm not sure of the most efficient way of doing this.
I have two vectors:
std::vector<bool> a;
std::vector<int> b;
a.size() necessarily equals b.size().
each bool in a corresponds to an int in b. I want to create a function:
bool test(std::vector<bool> a, std::vector<int> b);
This function returns true if the values in a are equal. However, it only considers values in a that correspond to true values in b.
I could do this:
bool test(std::vector<int> a, std::vector<bool> b){
int x;
unsigned int i;
for(i = 0; i < a.size(); ++i){
if(b.at(i) == true){
x = a.at(i);
break;
}
}
for(i = 0; i < a.size(); ++i){
if(b.at(i) == true){
if(a.at(i) != x){
return false;
}
}
}
return true;
}
But then I have to create two loops. Although the first loop will stop at the first true value, is there a better way?
Your solution looks good enough to me:
Each loop does a different thing anyway (so you shouldn't worry about duplication)
You don't use extranious variables or flags that complicate the code.
The only problems I see are:
You start the second loop at 0 instead of where you left off.
Doing if(condition == true) is very ugly. Just do if(condition) instead.
bool test(std::vector<int> a, std::vector<bool> b){
int x;
unsigned i;
for(i = 0; i < a.size(); i++){
if(b.at(i)){
x = a.at(i);
break;
}
}
for(i++; i < a.size(); i++){
if(b.at(i)){
if(a.at(i) != x){
return false;
}
}
return true;
}
You can do it in one loop if you remember if you have seen the first true element in b or not. Also, you should take the a and b parameters by reference to avoid unnecessary copying. And finally, if you know that the indices into a vector are always within valid range (i.e. between 0 and vector.size() - 1, inclusive), you can use operator[] instead of at, and achieve better peformance (at does a range check, while operator[] does not). Heres a modified version of your test function considering all the above points:
bool test(std::vector<int> const& a, std::vector<bool> const& b){
int x;
bool first = true;
for(unsigned i = 0, n = a.size(); i != n; ++i){
if( b[i] ){
if( first ) {
x = a[i];
first = false;
}
else if( x != a[i] ) {
return false;
}
}
}
return true;
}
Provided you know a.size() == b.size() just create a single loop that compares an 'a' element to a 'b' element at the same time at each iteration. Once you see that a[i] != b[i] then you know the containers don't match and you can break out.
I am not 100% certain I know what you want to do but a straight compare once you know you have equal size
std::equal(a.begin(), a.end(), b.begin(), std::equal_to<bool>())

array loop not working correctly? c++

Trying to count how many elements within the array are not equal to 0, is something set up wrong?
I'd like to check all values in the array (it's a sudoku board) and then when all elements are "full" I need to return true.
Is something off?
bool boardFull(const Square board[BOARD_SIZE][BOARD_SIZE])
{
int totalCount=0;
for (int index1 = 0; index1 < BOARD_SIZE; index1++)
for (int index2 = 0; index2 < BOARD_SIZE; index2++){
if(board[index1][index2].number!=0)
totalCount++;
}
if(totalCount=81)
return true;
else
return false;
You have = rather than ==
if (totalCount == 81)
is the correct line.
Doing this with a single "=" actually assigns the value 81 to totalCount, so your test is essentialy:
if (81)
And since in C++ anything nonzero is true, this is always true
You have a = that should be a ==. That's all I'll say, since it's homework.
Also, why do you have a constant for BOARD_SIZE, then check against 81 at the end? Wouldn't checking against BOARD_SIZE * BOARD_SIZE be better?
Is the If(totalCount=81) a typo in this post or your code? Looks like you've assigned the value there.
You can leave the function as soon as you find the first 0, and it's possible to solve this with a single loop:
bool boardFull(const Square board[BOARD_SIZE][BOARD_SIZE])
{
const Square* p = board[0];
for (int n = BOARD_SIZE * BOARD_SIZE; n; --n, ++p)
{
if (p->number == 0) return false;
}
return true;
}
But I prefer algorithms to hand-written loops:
struct Square
{
int number;
bool is_zero() const
{
return number == 0;
}
};
#include <algorithm>
#include <functional>
bool boardFull(const Square board[BOARD_SIZE][BOARD_SIZE])
{
return std::find_if(
board[0],
board[BOARD_SIZE],
std::mem_fun_ref(&Square::is_zero)
)== board[BOARD_SIZE];
}