ZOJ 3481. Expand Tab

简介:   题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4278     题意:   给出一些文本片段,把文本中的 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[500];
    char delimit[1024];
} 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[1024], *p;

    scanf("%ld\n", &T);
    for(i = 0; i < T; i++) {
        gets(line);
        memset(&g_TS, 0, sizeof(TABSTOP));
        ParseTabStop(line, &g_TS);

        while(true) {
            gets(line);

            if(strcmp(line, g_TS.delimit) == 0) {
                gets(line); /*case结尾的空行*/
                printf("\n");
                break;
            }

            col = 0;
            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 0;
}

//解析 tabstop 配置
void ParseTabStop(char *line, LPTABSTOP pTS)
{
    /*expand tab-stops-configuration <<delimiting-identifier*/

    char *p = line + 7;
    char ch;
    int index = 0;

    while(*p) {
        ch = *p; 

        if(ch >= '0' && ch <= '9')
            pTS->ts[index] = pTS->ts[index] * 10 + (*p - '0');
        else if(ch == ',')
            ++index;
        else if(ch == '<') {
            strcpy(pTS->delimit, p + 2);
            break;
        }
        ++p;
    }

    pTS->count = index + 1;
    qsort(pTS->ts, pTS->count, sizeof(int), cmp);
}

//获取当前列的 tabstop 位置
int GetStopCol(int iCol, LPTABSTOP pTS)
{
    int i;
    if(pTS->count == 1) {
        return (iCol / pTS->ts[0] + 1) * pTS->ts[0];
    }
    else {
        if(pTS->ts[pTS->count-1] <= iCol)
            return iCol + 1;

        for(i = 0; i < pTS->count; i++) {
            if(iCol < pTS->ts[i])
                return pTS->ts[i];
        }
    }
    return iCol + 1;
}

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 中的最小值即可。

目录
相关文章
|
网络协议 Ubuntu Linux
Linux 动态/静态配置ip网卡信息
Linux 动态/静态配置ip网卡信息
494 0
|
Oracle Java 关系型数据库
实时计算 Flink版操作报错合集之本地打成jar包,运行报错,idea运行不报错,是什么导致的
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
246 6
|
Java 应用服务中间件
面对海量网络请求,Tomcat线程池如何进行扩展?
【10月更文挑战第4天】本文详细探讨了Tomcat线程池相较于标准Java实用工具包(JUC)线程池的关键改进。首先,Tomcat线程池在启动时即预先创建全部核心线程,以应对启动初期的高并发请求。其次,通过重写阻塞队列的入队逻辑,Tomcat能够在任务数超过当前线程数但未达最大线程数时,及时创建非核心线程,而非等到队列满才行动。此外,Tomcat还引入了在拒绝策略触发后重新尝试入队的机制,以提高吞吐量。这些优化使得Tomcat线程池更适应IO密集型任务,有效提升了性能。
面对海量网络请求,Tomcat线程池如何进行扩展?
ruoyi-nbcio使用minio相关配置与应用
ruoyi-nbcio使用minio相关配置与应用
423 0
ruoyi-nbcio使用minio相关配置与应用
|
存储 Kubernetes 调度
k8s常见的排错指南Node,svc,Pod等以及K8s网络不通问题
k8s常见的排错指南Node,svc,Pod等以及K8s网络不通问题
4823 1
|
定位技术 项目管理
高效项目管理,五款工具引领革命
项目管理工具如甘特图和WBS至关重要。甘特图助于时间管理、资源分配及展示任务间的依赖关系,尤其Zoho Projects提供的甘特图功能强大且易用。WBS则将项目目标逐步分解为可操作的小任务,提高管理效率。结合使用这两种工具能让项目管理更为高效有序。
104 0
|
JSON 网络架构 数据格式
SpringMVC -- REST风格开发,RESTful快速开发、RESTful注解开发
SpringMVC -- REST风格开发,RESTful快速开发、RESTful注解开发
162 2
|
数据挖掘 索引 Python
Python实现固定效应回归模型实现因果关系推断(二)
Python实现固定效应回归模型实现因果关系推断(二)
1315 1
Python实现固定效应回归模型实现因果关系推断(二)
|
Java 关系型数据库 MySQL
JSP高校学生积分管理系统myeclipse开发mysql数据库bs框架java编程jdbc
JSP 高校学生积分管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用java语言开发,系统主要采用B/S模式开发。
175 0
|
XML 存储 JSON
SSM 之 SpringMVC(下)
SSM 之 SpringMVC(下)
146 0
SSM 之 SpringMVC(下)