I just got this frame for a sudoku solver, but I don't understand the syntax they've used and how I'm supposed to proceed. They call it a bitset, but upon searching for it I found nothing similar.
// This file contains a simple implementation of sets of
// digits between 1 and 9, called fields.
#ifndef __SUDOKU_FIELD_H__
#define __SUDOKU_FIELD_H__
#include <iostream>
#include <cassert>
#include "digit.h"
class Field {
private:
// Use integers for a bitset
unsigned int _digits;
// Number of digits in bitset
unsigned int _size;
public:
// Initialize with all digits between 1 and 9 included
Field(void)
: _digits((1 << 1) | (1 << 2) | (1 << 3) |
(1 << 4) | (1 << 5) | (1 << 6) |
(1 << 7) | (1 << 8) | (1 << 9)), _size(9) {}
// Return size of digit set (number of digits in set)
unsigned int size(void) const {
// FILL IN
}
// Test whether digit set is empty
bool empty(void) const {
// FILL IN
}
// Test whether set is assigned (that is, single digit left)
bool assigned(void) const {
// FILL IN
}
// Test whether digit d is included in set
bool in(digit d) const {
assert((d >= 1) && (d <= 9));
// FILL IN
}
// Return digit to which the set is assigned
digit value(void) const {
assert(assigned());
// FILL IN
}
// Print digits still included
void print(std::ostream& os) const;
// Remove digit d from set (d must be still included)
void prune(digit d) {
assert(in(d));
// FILL IN
}
// Assign field to digit d (d must be still included)
void assign(digit d) {
assert(in(d));
// FILL IN
}
};
// Print field
inline std::ostream&
operator<<(std::ostream& os, const Field& f) {
f.print(os); return os;
}
#endif
Obviously the //FILL IN's are for me to write, and the meaning of the bitset is 9 bits where all of them initially are set to 1. The question is how I manipulate or use them.
Oh, by the way, this is a digit:
#ifndef __SUDOKU_DIGIT_H__
#define __SUDOKU_DIGIT_H__
typedef unsigned char digit;
#endif
This initialization sets the bits 1 - 9 of _digits
to 1. The expression (1 << n)
means 1 shifted n bits to the left. The expression a | b
a | b
means a bit-wise or of a
and b
.
So, in detail, all of the expressions (1 << n)
result in a bit-pattern with all zeroes and a 1 at the n th position, for 0 < n < 10. All of these are or
'd together, to yield a bit-pattern bits 1 through 9 set to 1:
(1 << 1) 0010 |
(1 << 2) 0100 |
(1 << 3) 1000
======================
1110
(unused bits not shown)
A "bitfield" is just an interpretation of a integer in memory as if it was a list of bits. You will be setting, testing and resetting bits in this integer individually, and the comments in the code tell you exactly what to do in each function.
You can use '&' and '|' for bitwise AND and OR, and '<<' and '>>' for shifting all bits to the left and right. This article can be very helpful to you: http://en.wikipedia.org/wiki/Bitwise_operation
4 bits:
0000
1 in binary is:
0001
Shifting is used to choose a single bit:
0001 << 0 = 0001 // first bit
0001 << 1 = 0010 // second bit
0001 << 2 = 0100 // third bit
Or is used to set individual bits:
0000 | 0100 = 0100
And is used to retrieve bits:
0111 & 0001 = 0001
This is how bitsets work.
Example:
unsigned int x = 0;
x |= 1 << 4; // set 5th bit
x |= 1 << 3; // set 4th bit
x |= 0x3; // set first 2 bits - 0x3 = 0011
unsigned int b = true;
x |= b << 7; // set 8th bit to value of b
if (x & (1 << 2)) { // check if 3rd bit is true
// ...
}
b = (x >> 3) & 1; // set b to value of 4th bit
Here is a way to count number of bits, along with other helpful algorithms :
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.