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];
}
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 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.
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
I have to do an exercise for University that asks me to check ( for k times ) if a matrix has positive rows ( i mean a row with all positive elements ) , i think there's something wrong with the indices of for loops but i cannot find the mistakes.
i tried to debug with a cout statement apply to the counter an it gives me "101" , so it seems like compiler assign "1" to the positive rows and "0" to the negative
This is the code i wrote:
#include <iostream>
using namespace std;
const int N = 3;
bool positive(int a[N][N], int row[N], int x) {
bool condition = false;
for(int i = 0; i < N; i++) {
row[i] = a[x][i];
}
int j = 0;
while(j < N) {
if(row[j] >= 0) {
condition = true;
} else {
condition = false;
}
j++;
}
return condition;
}
bool function (int a[N][N], int z, int j, int k) {
int b[N];
int c[N];
int count = 0;
if(positive(a, b, z) && positive(a, c, j)) {
count++;
}
if(count == k) {
return true;
} else {
return false;
}
}
int main() {
int a[N][N] = {
{
2, 8, 6
}, {
-1, - 3, - 5
}, {
6, 10, 9
}
};
int k = 2;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
if(function (a, i, j, k)) {
cout << "OK";
} else {
cout << "NO";
}
}
}
return 0;
}
You should probably take another look at this problem and restart with a different solution. The objective is pretty easy but your code is surprisingly complex and some of it doesn't really make sense.
For example, if you had a matrix like this:
1 2 4 --> matrix A
-1 8 -6
3 9 2
You have N=3 rows and columns. The only thing you have to to based on what you said is take the matrix, cycle through the N rows, and for each row, check it's N columns to see if anything is < 0.
Doing this K times, as you put it, makes no sense. The matrix will be the same every time you compare it since you're not changing it, why would you do it more than once? I think you should reread the assignment brief there.
As for the logic of finding which rows are positive or negative, just do something simple like this.
//Create array so we have one marker for each row to hold results.
bool rowPositiveFlags[N] = { true, true, true };
//Cycle through each row.
for (int row = 0; row < N; ++row)
//Cycle through every column in the current row.
for (int col = 0; col < N; ++col)
//If the column is negative, set the result for this row to false and break
//the column for loop as we don't need to check any more columns for this row.
if (A[row][col] < 0) {
rowPositiveFlags[row] = false;
break;
}
You should always name things so that you can read your code like a book. Your i's, j's, and k's just make something simple confusing. As for the problem, just plan out your solution.
Solve the problem by hand on paper, write the steps in comments in your code, and then write code below the comments so what you do definitely makes sense and isn't overkill.
And this is a great site, but next time, post a smaller piece of code that shows your problem. People shouldn't ever give you a full solution here for homework so don't look for one. Just find the spot where your indices are broken and paste that set of 5 lines or whatever else is wrong. People appreciate that and you'll get faster, better answers for showing the effort :)
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>())