有没有办法在c ++中编写一个switch语句来处理范围。 案例0-10做一个, 案例20-40做b, 案例40-80做c, 等等 我可以使用一堆if if if语句写出来,但想知道是否有更有效的方法。
答案 0 :(得分:2)
实际上,你可以通过C中的预处理器滥用来做到这一点(尽管可能不是在C ++中,由于C ++中的P99有些错误,我相信可以通过足够的毅力来克服)。
请参阅以下示例,使用P99:
#include "p99.h"
#define P99_SWITCH_RANGE(from, to) P99_FOR(from, P99_MINUS(to, from), P99_SWITCH_RANGE_GLUE_HELPER, P99_SWITCH_RANGE_CASE_LABEL_MAKER_HELPER)
#define P99_SWITCH_RANGE_GLUE_HELPER(from, i, past, cur) past: cur
#define P99_SWITCH_RANGE_CASE_LABEL_MAKER_HELPER(from, x, i) case P99_ADD(from, i)
int main(int argc, const char *argv[]) {
int x;
scanf("%i", &x);
switch (x) {
P99_SWITCH_RANGE(20, 30):
{
puts("between 20 and 30");
}
default: {
puts("not between 20 and 30");
}
}
}
请注意,此示例包含在内,右侧为独占。我相信您可以修改宏以使其符合您的任何方式,所以至少这是一个不错的起点。
答案 1 :(得分:1)
我可以使用一堆if if if语句写出来,但想知道是否有更有效的方法。
没有。没有更有效的方法。更不用说switch
语句实际上不应该用于范围。
答案 2 :(得分:1)
您可以使用地图映射键来标准功能:
#include <iostream>
#include <map>
#include <functional>
using namespace std;
int main()
{
std::map<int, std::function<void()>> dispatcher;
// case (-inf, 10]
dispatcher[10] = []() {cout << 10;};
// case (10, 50]
dispatcher[50] = []() {cout << 50;};
// case (50, 100]
dispatcher[100] = []() {cout << 100;};
(dispatcher.lower_bound(1)->second)();
(dispatcher.lower_bound(10)->second)();
(dispatcher.lower_bound(11)->second)();
(dispatcher.lower_bound(50)->second)();
(dispatcher.lower_bound(51)->second)();
return 0;
}
输出10105050100
答案 3 :(得分:1)
如果您担心效率,可以将范围映射到值,然后切换它们:
int range_to_value(int x)
{
if (x > 0 && x < 10) return 0;
if (x > 20 && x < 40) return 1;
// ...
}
void switch_range(int x)
{
switch( range_to_value(x) )
{
case 0: cout << 0; break;
case 1: cout << 1; break;
}
}
switch_range(1); // output 0
switch_range(9); // output 0
switch_range(22); // output 1
范围映射可能是内联的,但每次都会计算。最有效的将是大型开关,无论你如何编写它(手动,生成器,预处理器),因为它最终将成为一个大的跳转表。
答案 4 :(得分:-2)
试试这个:
case 0 ... 10:
case 20 ... 40:
case 41 ... 80:
等。