zoukankan      html  css  js  c++  java
  • 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[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
    ", &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("
    ");
                    break;
                }
    
                col = 0;
                p = line;
                while(*p) {
                    if(*p == '	') {
                        stopCol = GetStopCol(col, &g_TS);
                        while(col < stopCol) {
                            printf(" ");
                            ++col;
                        }
                    }
                    else {
                        printf("%c", *p);
                        ++col;
                    }
    
                    ++p;
                }
                printf("
    ");
            }
        }
        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 中的最小值即可。

  • 相关阅读:
    HEW MAP文件使用
    UltraEdit 脚本 实现查找替换
    PC软件与PLC串口通信 奇偶检验问题
    Halcon的应用程序 打开后 弹出没有帮助文件错误提示
    STM32f4 ARM Bootloader
    RAM
    知识整理--内存
    CentOS 5.x 多个ISO文件 安装方法(VMware)
    Modbus总结
    【CF1253A】Single Push【模拟】
  • 原文地址:https://www.cnblogs.com/hoodlum1980/p/3868503.html
Copyright © 2011-2022 走看看