ZOJ 3481. Expand Tab
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4278
题意:
给出一些文本片段,把文本中的 Tab 字符根据配置,替换成一定数量的空格。
配置分为两种,一种是只提供一个 ts 值,则需要缩进到的位置是一个等比数列。另一种是提供一个 ts 的有限集合,指定一些给定 ts 值,在逻辑上这个集合是无限的,当列位置超出集合中的数字时,后续的 tabstop 位置为连续的以 1 个空格进行递增。
即:
{ T } 在逻辑上相当于 { T, T * 2, T * 3, T * 4, ...... };
{ T1, T2, ..., Tk } 在逻辑上相当于 { T1, T2, ..., Tk, Tk + 1, Tk + 2, Tk + 3, ...... };
分析:
本题目本身是比较简单的。但是值得注意的是:
(1)当给定一个 ts 序列时,ts 序列的数字无序且可能重复(如果去重,可能会导致数组中只剩下一个数字,这时候不能当做等比数列来处理。如果不去重就不必在意这个问题)。所以不能假设序列有序,可以对这个序列进行一次排序。
(2)当只提供一个 ts 值,这时为等比数列。最开始我使用了类似图像的行对齐公式来计算 stop 位置,结果这在一些情况下,结果会多考虑一个 ts 值。实际上的索引为 iCol 的列的 tabstop 值,公式仅仅是 (iCol / ts + 1) * ts 即可。由于我在这里编码心态过急,犯下这个低级失误,导致我不断的 PE N 次,差点崩溃。回到家里我慢慢查看这些步骤才找到这个错误。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h> typedef struct _TabStop {
int count;
int ts[];
char delimit[];
} TABSTOP, *LPTABSTOP; //解析配置信息
void ParseTabStop(char *line, LPTABSTOP pTS); //获取 tab stop 位置
int GetStopCol(int iCol, LPTABSTOP pTS); //排序用的比较函数
int cmp(const void* p1, const void* p2); TABSTOP g_TS; int main()
{
int i, T, col, stopCol;
char line[], *p; scanf("%ld\n", &T);
for(i = ; i < T; i++) {
gets(line);
memset(&g_TS, , sizeof(TABSTOP));
ParseTabStop(line, &g_TS); while(true) {
gets(line); if(strcmp(line, g_TS.delimit) == ) {
gets(line); /*case结尾的空行*/
printf("\n");
break;
} col = ;
p = line;
while(*p) {
if(*p == '\t') {
stopCol = GetStopCol(col, &g_TS);
while(col < stopCol) {
printf(" ");
++col;
}
}
else {
printf("%c", *p);
++col;
} ++p;
}
printf("\n");
}
}
return ;
} //解析 tabstop 配置
void ParseTabStop(char *line, LPTABSTOP pTS)
{
/*expand tab-stops-configuration <<delimiting-identifier*/ char *p = line + ;
char ch;
int index = ; while(*p) {
ch = *p; if(ch >= '' && ch <= '')
pTS->ts[index] = pTS->ts[index] * + (*p - '');
else if(ch == ',')
++index;
else if(ch == '<') {
strcpy(pTS->delimit, p + );
break;
}
++p;
} pTS->count = index + ;
qsort(pTS->ts, pTS->count, sizeof(int), cmp);
} //获取当前列的 tabstop 位置
int GetStopCol(int iCol, LPTABSTOP pTS)
{
int i;
if(pTS->count == ) {
return (iCol / pTS->ts[] + ) * pTS->ts[];
}
else {
if(pTS->ts[pTS->count-] <= iCol)
return iCol + ; for(i = ; i < pTS->count; i++) {
if(iCol < pTS->ts[i])
return pTS->ts[i];
}
}
return iCol + ;
} int cmp(const void* p1, const void* p2)
{
int *pX1 = (int*)p1;
int *pX2 = (int*)p2;
return *pX1 - *pX2;
}
ZOJ_3481_cpp
补充:
当然,如果不对序列进行排序,也是可以的。区别只是在获取 tabstop 位置时,每次都要完整的线性遍历这个集合(在有序的情况下可以提前结束遍历,或者进一步的用二分查找快速定位),尝试找到满足条件 ts > iCol 的所有 ts 中的最小值即可。
ZOJ 3481. Expand Tab的更多相关文章
- vim设置tab为4空格
vim的最基础设置 vim的设置需要编辑~/.vimrc文件,更改已有设置或者在后面添加相应的设置. 设置tab为4字符 # ts: tabstop set ts=4 将tab展开为空格 # expa ...
- storysnail的Linux串口编程笔记
storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...
- 我的ubuntu配置
每次装系统都是非常蛋疼的过程,新装的系统还是要配置一下的 首先安装google拼音 sudo apt-get install fcitx fcitx-googlepinyin 然后按装numix主题 ...
- Linux串口编程详解(转)
串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...
- linux串口编程总结
串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...
- linux串口编程参数配置详解(转)
1.linux串口编程需要的头文件 #include <stdio.h> //标准输入输出定义#include <stdlib.h> //标准函数 ...
- vim 小技巧
cd - 返回刚才访问的目录shift+# 在vi中查找相同的关键字vi 中o在当前游标位置后插入一行 O在当前位置前插入一行0 $到行未 行首shift+s 删除一行,并且进入insert mode ...
- Linux下串口編程遇到的接收数据错误及原因(0x0d,0x11接收错误)
摘要:Linux下串口编程遇到的接收数据错误及原因 来源:https://dotblogs.com.tw/k/2012/07/24/73572 近日在调试串口的时候发现,另一设备向我ARM板的串口发送 ...
- linux串口编程参数配置详解
1.linux串口编程需要的头文件 #include <stdio.h> //标准输入输出定义 #include <stdlib.h> //标准函 ...
随机推荐
- 因特网服务的类型(协议),目前最流行的类型是 http协议
在学习超链接中,在HTML上点击QQ图标时会 自动的启动自己本地QQ客户端,其方法是使用了超链协议 一些常用协议如下: file资源是本地计算机上的文件.格式file:/// ftp通过 FTP访问资 ...
- CodeForces 239A. Triangle
Link: http://codeforces.com/contest/407/problem/A 给定直角三角形的2个直角边a,b.求在直角坐标系中,是否存在对应的直角三角形,使得三个定点都在整点 ...
- 合并果子 2004年NOIP全国联赛普及组
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆 ...
- 深度|OpenAI 首批研究成果聚焦无监督学习,生成模型如何高效的理解世界(附论文)
本文经机器之心(微信公众号:almosthuman2014)授权转载,禁止二次转载,原文. 选自 Open AI 作者:ANDREJ KARPATHY, PIETER ABBEEL, GREG BRO ...
- iOS_Quartz2D之涂鸦板
响应者对象:继承了UIResponder的对象 触摸事件:一根或多根手指: 开始触摸: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent ...
- myeclipse激活时cracker2015.jar打不开
myeclipse激活时cracker2015.jar打不开 可能是jdk版本的问题 这是我用的myeclipse版本 myeclipse-2016-ci-7-offline-installer-wi ...
- Oracle 物理备份--rman
Oracle 物理备份--rman 1.直接在服务器,打开命令行,输入: rman target/ 2.配置参数也一同备份 configure controlfile autobackup on; 如 ...
- Oracle 使用SqlPlus管理
Oracle 使用SqlPlus 安装,一键安装,很简单.安装过程,一定要记住密码 一.登陆sqlplus 连接本地服务器,可以直接,打开cmd: 可以直接不用登陆,如果登陆需要输入用户名.密码. s ...
- 基于Netty的私有协议栈的开发
基于Netty的私有协议栈的开发 书是人类进步的阶梯,每读一本书都使自己得以提升,以前看书都是看了就看了,当时感觉受益匪浅,时间一长就又还回到书本了!所以说,好记性不如烂笔头,以后每次看完一本书都写一 ...
- DELL_LCD错误提示代码
代码 文本 原因E1000 Failsafe voltage error. Contact support.(故障保护电压错误.请联络支持人员.) 查看系统事件记录以了解严重故障事件.E1114 Am ...