我有一个8位移位值的枚举。我希望能够确定任何两个值之间的距离。如果值只是增加整数,这将很简单。这就是我现在所拥有的。
typedef NS_ENUM(NSInteger, TestEnum) {
TestEnumValue1 = 1 << 0,
...
TestEnumValue8 = 1 << 7
};
TestEnum left = TestEnumValue8;
TestEnum right = TestEnumValue3;
TestEnum high = MAX(left, right);
TestEnum low = MIN(left, right);
int distance = 0;
int maximumEnum = 8;
int cumulativeResult = high;
for (int i = 0; i < maximumEnum; i++)
{
cumulativeResult = cumulativeResult / 2;
if (cumulativeResult == low)
{
distance = i;
break;
}
}
NSLog (@"Distance is %d", distance);
以上似乎运作良好,但这是最好的方法吗?
答案 0 :(得分:2)
忽略使用枚举是否合适,请尝试:
TestEnum left = TestEnumValue8;
TestEnum right = TestEnumValue3;
TestEnum high = MAX(left, right);
TestEnum low = MIN(left, right);
int distance = 0;
while (low < high) {
low <<= 1;
distance++;
}
NSLog (@"Distance is %d", distance);
请注意,仅当left
和right
设置了一个“标记”时,此方法才有效。
答案 1 :(得分:1)
这是一个潜在的解决方案:添加两个(正)整数并计算一位之间的零位。加法的可交换性消除了确定哪个操作数更大的繁琐需求。
int distance;
int k = left + right;
int started = 0;
while (k > 1) {
if (!started && (k & 1)) {
started = 1;
distance = 0;
}
if (started) distance++;
k >>= 1;
}
printf("%d\n", distance);
答案 2 :(得分:1)
我把一些令人讨厌的东西混在一起,但是哪种工作方式允许使用枚举值,这些值不是连续的2次幂。 以下是&#39; enum&#39;定义,实际的枚举值在DEFINE_MYENUM(x,y)语句中定义:
#include <cmath>
#include <map>
class Value {
public:
virtual operator int() const = 0;
int getIndex() const { return index; }
static const Value& fromValue(int val)
{
return *(getReverseMap().find(val)->second);
}
protected:
int index;
static int getNextIndex() {
static int curIndex = 0;
return curIndex++;
}
static std::map<int, Value*>& getReverseMap() {
static std::map<int, Value*> reverseMap = std::map<int, Value*>();
return reverseMap;
}
};
template<int y> class ValueImpl : Value {
public:
ValueImpl() {
index = Value::getNextIndex();
Value::getReverseMap()[y] = this;
}
virtual operator int() const override { return y; }
};
#define DEFINE_MYENUM(NAME, VALUE) const ValueImpl<VALUE> NAME
class MyEnumDefs {
public:
DEFINE_MYENUM(Value1, 2);
DEFINE_MYENUM(Value2, 4);
DEFINE_MYENUM(Value3, 8);
DEFINE_MYENUM(Value4, 16);
DEFINE_MYENUM(Value5, 20);
DEFINE_MYENUM(Value6, 25);
int distance(const Value& x, const Value& y) {
return std::abs(x.getIndex() - y.getIndex());
}
int distance(int x, int y) {
const Value& xx = Value::fromValue(x);
const Value& yy = Value::fromValue(y);
return distance(xx, yy);
}
};
#undef DEFINE_MYENUM
class MyEnum {
public:
static MyEnumDefs& inst() {
static MyEnumDefs internalInst = MyEnumDefs();
return internalInst;
}
};
#define MyEnum MyEnum::inst()
以下是测试代码:
int main(int argc, const char * argv[])
{
int a = MyEnum.Value1;
int b = MyEnum.Value2;
int c = MyEnum.Value3;
int d = MyEnum.Value4;
int e = MyEnum.Value5;
int f = MyEnum.Value6;
printf("a b c d e f: %d %d %d %d %d %d\n", a, b, c, d, e, f);
printf("Distance b d: %d\n", MyEnum.distance(b, d));
printf("Distance d b: %d\n", MyEnum.distance(d, b));
printf("Distance e f: %d\n", MyEnum.distance(e, f));
return 0;
}
输出:
a b c d e f: 2 4 8 16 20 25
Distance b d: 2
Distance d b: 2
Distance e f: 1
显然这并不完美,例如语法MyEnum.XXX而不是XXX或MyEnum :: XXX,缺乏使用&#39; MyEnum&#39;作为一种类型等...但认为它是一个很好的开始可能是非常整洁:)