我目前正在用C编写代码,它从整个ASCII可用字符中选择符号和数字。 作为程序员的初学者,我经常做
if ((i > 25 && i < 50) || (i > 100 && i < 200)) { contents }
变量i
在25~50,100~200(不包括)之间,以适应条件。
如果我想设置多个范围,如32~64(! to @
)和91~96([ to `
)和123~126({ to ~
)那么会有更好的范围(意思是更短或更简单的代码)或者我应该坚持使用这种方法,继续按照上面的代码添加每个范围?
答案 0 :(得分:14)
答案 1 :(得分:2)
您可以编写一个函数来检查该值是否属于任何给定范围:
struct Range {
int min;
int max;
};
bool in_ranges(int character, struct Range *ranges, size_t num_ranges) {
for(size_t i = 0; i < num_ranges; ++i) {
if(ranges[i].min < character && character < ranges[i].max)
return true;
}
return false;
}
int main() {
struct Range rngs[] = {{25,50}, {100,200}};
bool at_sign_si_in_range = in_ranges('@', rngs, 2);
return 0;
}
它使编辑范围更加简单并提高了可读性。 此外,如果您继续在条件子句中编写所有范围,如示例所示,请考虑检查范围,如
lower_bound < value && value < upper_bound
它看起来像数学符号(x < a < y
),看起来也更容易阅读。
答案 2 :(得分:1)
如果使用单字节字符,则可以使用标志数组获得更好的性能,设置单个位或整个字节以指示其中一个范围内的字符值。
如果您正在为支持SSE 4.2指令的Intel处理器编写代码,您可能需要考虑使用PCMPISTRI或类似代码,它可以在一条指令中将多达16个单字节字符与多达8个不同的范围进行比较。
答案 3 :(得分:1)
我的回答是&#34;它取决于&#34;。 :)
如果var defaultBounds = new google.maps.LatLngBounds(new google.maps.LatLng(south, west), new google.maps.LatLng(north, east));
和来自isalpha()
的朋友做了你想做的事,那么绝对使用它们。
但如果不是......
如果你只有两个范围,就像你的示例代码段一样,我觉得它看起来太乱了。如果还有更多,可以将范围测试放在(内联)函数中,以减少一次可见的布尔值:
ctype.h
(如果您认为需要保存屏幕区域,请将其命名为if (in_range(val, a1, b1) || in_range(val, a2, b2) || ... )
。)
如果范围可能在运行时更改,或者有很多范围,请将限制放在B(n,a,b)
中并循环显示其中的数组。如果真的有很多,请对列表进行排序,并使用它做一些聪明的事情,比如在下限(或其他)上进行二元搜索。但是对于少数人来说,我不会打扰。
如果允许值的总范围很小(如值为0..255的无符号字符),但是单独的&#34;范围的数量&#34;很大(&#34;所有那些具有素数值&#34;),然后制作值的表(位图),并对其进行测试。以您喜欢的方式生成表格。 (struct
可能就像这样实现)
isalpha()
答案 4 :(得分:0)
你可以在宏或内联函数中隐藏l<x && x<h
的重复,但我发现它很少值得 - 它不像Python l<x<h
语法那样可读,并且很快就会失控一旦你开始拥有所有包容性边界可能性的宏。要么最终得到一个可笑的长命名约定(between_inc_inc
,between_inc_exc
,......哪一种方法可以将检查放在首位)或者让读者想知道你的范围检查(“{ {1}} ...它是between(i, 50, 100)
范围吗?一个[,)
一个?(检查代码)nope它是[,]
“),如果你正在寻找它,这很可怕一个错误。
OTOH,我知道滥用“单字母宏”,我确切地定义了它们需要的位置和方式,并且在之后立即未定义。虽然它们可能看起来很难看,但关键在于它们非常本地并完全按需要做,所以没有浪费时间查找它们,没有神秘的参数,它们可以分解出大量重复计算
在你的情况下,如果列表很长,我可以
(,)
(永远不要在标题中这样做!)
可读性的一个好处就是使用字符文字而不是ASCII数字:例如,如果你想要a-z范围,请#define B(l, h) ((l)<i) && (i<(h)) ||
if(B(25,50) B(100,200) B(220, 240) 0)
...
#undef B
。
您似乎想要排除按字母顺序排列和不可打印的字符:您可以使用
执行此操作'a'<=i && i<='z'
答案 5 :(得分:0)
您可以编写如下函数:
public class MainActivity extends Activity {
Button button,btnAdd,btnSub;
EditText val1,val2;
double num1,num2,res;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
val1 = (EditText) findViewById(R.id.txtVal1);
val2 = (EditText) findViewById(R.id.txtVal2);
btnAdd = (Button) findViewById(R.id.btnSum);
btnSub = (Button) findViewById(R.id.btnDiff);
btnAdd.setOnClickListener(new OnClickListener(){
public void onClick(View view) {
num1 = Double.parseDouble(val1.getText().toString());
num2 = Double.parseDouble(val2.getText().toString());
res = num1 + num2;
Toast.makeText(MainActivity.this, String.valueOf(res), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
然后您可以使用此功能并保持代码清洁和简单。
答案 6 :(得分:0)
class RangeCollection
{
std::vector<int> ranges;
public:
void AddRange(int lowerBound, int upperBound)
{
vector.push_back(lowerBound);
vector.push_back(upperBound);
}
bool IsInRange(int num)
{
for(int i=0; i<ranges.size()-1; i+=2)
{
if(num>ranges[i] && num<ranges[i+1])return true;
}
return false;
}
};
您可以调用AddRange添加任意数量的范围,然后您可以检查数字是否在范围内。
RangeCollection rc;
rc.AddRange(20,25);
rc.IsInRange(22);//returns true