社区讨论

整点烂活:使用 Ragel 编写的快读

灌水区参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@m04wt9gs
此快照首次捕获于
2024/08/22 14:36
2 年前
此快照最后确认于
2025/11/04 22:46
4 个月前
查看原帖
这是一个普通的快读
CPP
long long read()
{
    long long x=0;bool flag(0);char ch=getchar();
    while(!isdigit(ch)) flag=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return flag?-x:x;
}
而这,是用 Ragel 生成的“快”读
CPP
long long read()
{
    
static const char _parser_actions[] = {
	0, 1, 0, 1, 1
};

static const char _parser_key_offsets[] = {
	0, 0, 3, 5, 7
};

static const char _parser_trans_keys[] = {
	45, 48, 57, 48, 57, 48, 57, 0
};

static const char _parser_single_lengths[] = {
	0, 1, 0, 0, 0
};

static const char _parser_range_lengths[] = {
	0, 1, 1, 1, 0
};

static const char _parser_index_offsets[] = {
	0, 0, 3, 5, 7
};

static const char _parser_trans_targs[] = {
	2, 3, 0, 3, 0, 3, 4, 0, 
	0
};

static const char _parser_trans_actions[] = {
	0, 0, 0, 1, 0, 3, 3, 0, 
	0
};

static const char _parser_eof_actions[] = {
	0, 0, 0, 3, 0
};

static const int parser_start = 1;
static const int parser_first_final = 3;
static const int parser_error = 0;

static const int parser_en_main = 1;




    bool flag = false;
    long long x = 0;
    char buf[32];
    char *p = buf;
    char *pe = p;
    int cs;

    do {
        *pe = getchar();
        pe++;
    } while (*(pe - 1) == '-' || isdigit(*(pe - 1)));

    const char *eof = pe;

    
	{
	cs = parser_start;
	}

    
	{
	int _klen;
	unsigned int _trans;
	const char *_acts;
	unsigned int _nacts;
	const char *_keys;

	if ( p == pe )
		goto _test_eof;
	if ( cs == 0 )
		goto _out;
_resume:
	_keys = _parser_trans_keys + _parser_key_offsets[cs];
	_trans = _parser_index_offsets[cs];

	_klen = _parser_single_lengths[cs];
	if ( _klen > 0 ) {
		const char *_lower = _keys;
		const char *_mid;
		const char *_upper = _keys + _klen - 1;
		while (1) {
			if ( _upper < _lower )
				break;

			_mid = _lower + ((_upper-_lower) >> 1);
			if ( (*p) < *_mid )
				_upper = _mid - 1;
			else if ( (*p) > *_mid )
				_lower = _mid + 1;
			else {
				_trans += (unsigned int)(_mid - _keys);
				goto _match;
			}
		}
		_keys += _klen;
		_trans += _klen;
	}

	_klen = _parser_range_lengths[cs];
	if ( _klen > 0 ) {
		const char *_lower = _keys;
		const char *_mid;
		const char *_upper = _keys + (_klen<<1) - 2;
		while (1) {
			if ( _upper < _lower )
				break;

			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
			if ( (*p) < _mid[0] )
				_upper = _mid - 2;
			else if ( (*p) > _mid[1] )
				_lower = _mid + 2;
			else {
				_trans += (unsigned int)((_mid - _keys)>>1);
				goto _match;
			}
		}
		_trans += _klen;
	}

_match:
	cs = _parser_trans_targs[_trans];

	if ( _parser_trans_actions[_trans] == 0 )
		goto _again;

	_acts = _parser_actions + _parser_trans_actions[_trans];
	_nacts = (unsigned int) *_acts++;
	while ( _nacts-- > 0 )
	{
		switch ( *_acts++ )
		{
	case 0:
	{
            if (*(p - 1) == '-')
                flag = true;
        }
	break;
	case 1:
	{
            x = x * 10 + (*(p - 1)) - '0';
        }
	break;
		}
	}

_again:
	if ( cs == 0 )
		goto _out;
	if ( ++p != pe )
		goto _resume;
	_test_eof: {}
	if ( p == eof )
	{
	const char *__acts = _parser_actions + _parser_eof_actions[cs];
	unsigned int __nacts = (unsigned int) *__acts++;
	while ( __nacts-- > 0 ) {
		switch ( *__acts++ ) {
	case 1:
	{
            x = x * 10 + (*(p - 1)) - '0';
        }
	break;
		}
	}
	}

	_out: {}
	}


    return flag ? -x : x;
}
是不是很大

回复

2 条回复,欢迎继续交流。

正在加载回复...