微软校招编程题"Beautiful String"的状态机解法

昨天碰巧看到一道微软校招的编程题,题目大意如下:

如果一个字符串包括三组或者更多组的连续升序字母,每组长度相等,那么我们就称这个字符串是Beautiful String

如下是一些Beautiful String的例子:
abc、cde、aabbcc、aaabbbccc
这些不是Beautiful String:
abd、cba、aabbc、zab
输入一个只含有小写字母的字符串,如果它含有一个Beautiful的子串,就输出YES,否则输出NO

输入:
第一行是案例个数,之后的每一行是一个数字,一个字符串,数字表示字符串长度,长度小于10MB

输出:
YES或者NO

很容易想到可以用一个指针依次往前扫描,看是否符合Beautiful的条件,当出现不匹配时,从上次扫描起点的下一个位置开始新的尝试。这种判断过程可以用一个状态机来描述,我之前一直有一种模糊的想法,利用goto来实现不同状态的跳转,现在有这个题作为背景,正好可以试验一下这种想法,代码如下:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int n, length;
    char * str;
    char *p;
    char * p_bak;
    int count[3];
    char pre;
    scanf("%d", &n);
    while (n--)
    {
        scanf("%d", &length);
        str = (char*)malloc(sizeof(char) * (length + 1));
        scanf("%s", str);
        p = str;
        count[0] = 0;
        count[1] = 0;
        count[2] = 0;
        p_bak = p;
        goto SECTION_0;
    REWIND:
        count[0] = 0;
        count[1] = 0;
        count[2] = 0;
        p = ++p_bak;
        goto SECTION_0;
    SUCCESS:
        printf("YES\n");
        free(str);
        continue;
    FAIL:
        printf("NO\n");
        free(str);
        continue;
    SECTION_0:
        pre = *p;
    SECTION_A:
        if (*p == ‘\0‘)
            goto FAIL;
        if (*p == pre)
        {
            ++p;
            ++count[0];
            goto SECTION_A;
        }
        else if (*p == pre + 1)
        {
            goto SECTION_B;
        }
        else
        {
            goto REWIND;
        }
    SECTION_B:
        if (*p == ‘\0‘)
        {
            goto FAIL;
            goto FAIL; //向苹果致敬(●‘?‘●),参见 http://coolshell.cn/articles/11112.html
        }
        if (*p == pre + 1)
        {
            ++p;
            ++count[1];
            goto SECTION_B;
        }
        else if (*p == pre + 2)
        {
            goto SECTION_C;
        }
        else
        {
            goto REWIND;
        }
    SECTION_C:
        if (count[0] != count[1])
            goto REWIND;
        if (*p == ‘\0‘)
            goto FINAL_CHECK;
        if (count[2] == count[1])
            goto SUCCESS;
        if (*p == pre + 2)
        {
            ++p;
            ++count[2];
            goto SECTION_C;
        }
    FINAL_CHECK:
        if (count[2] != count[1])
            goto REWIND;
        else
            goto SUCCESS;
    }
    return 0;
}

从没写过这种就像汇编一样的面条代码,写完之后感觉整个人都要坏掉了,当然,一次AC。

(用C实现状态机应该可以利用switch case等功能来实现状态跳转,而不用goto,以后有时间再重构吧。)

时间: 2024-10-15 14:26:08

微软校招编程题"Beautiful String"的状态机解法的相关文章

网易秋招校招编程题

网易内推面试凉了,再战正式批笔试,选择和简答略难,编程题很良心,基本就是模拟.找规律,略加思考就能解出来的题目,本弱鸡只有在良心网易笔试才能AK. 1.翻转翻转 这题一开始没思路,ac了后两题后再回来思考,发现只需要判断某个位置周围有几个点,就代表了那个位置会被别的点翻转几次,那么如何求周围有几个点呢? 简单的把位置分成3类: 一类是四个顶点:每个顶点会被翻转4次(加上自己翻转一次). 第二类是四条边(不含顶点):边上的点会被翻转6次. 第三类就是中间部分:中间的每个点会被翻转9次. 因此翻转9

腾讯2016校招编程题【PHP实现】

2016腾讯春招的编程题 话不多说,直接上题!!! 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串.如何删除才能使得回文串最长呢?输出需要删除的字符个数 . 这道题是以回文为载体,考察两个字符间的最大子串,最大子串算法在表示字符串的关联度上用途很广泛. 而遮到题就是字符串的长度减去其和翻转字符串的长度的最大子串即可.最长子串的算法我一开始也是蒙的.这完全没没思路呀. 后来看到一篇blog,才明白最长子串,好的,最后我们形成代码 代码实现: function solution

19届第四范式测试开发工程师校招-编程题

编程题两道,第一道关于SQL的联合查询跟第二排序,第二道关于二维数组. 题目2: 给定一个空的int类型的二维数组array[n][m].按下面的填充规则,请编写一个函数将此二维数组填满并打印出来. 1 2 4 7 3 5 8 11 6 9 12 14 10 13 15 16 输入描述:输入的包括两个正整数,表示二维数组的大小n,m(1<=n,m<=10) 输出描述:打印结果,每行行末无空格. 例1:输入为4 4 输出为 1 2 4 7 3 5 8 11 6 9 12 14 10 13 15

携程2019校招编程题(3)

携程今年的机试题为20道选择+3编程 由于今天最后提交时第三题编程未通过,交卷之后想出来的解法这里记录一下. import java.util.ArrayList; import java.util.List; import java.util.Scanner; //携程3 public class LRU { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int size=Intege

今日头条2017校招编程题

贪心?瞎搞  先排个序,然后扫一遍,边扫边维护一个数组v   v的长度为3    设vs数组的最后一个是x 如果abs(a[i]-x)大于10 那么贪心的策略我就 添加个v+10相应的ans++. 然后注意一些细节就好了...  我代码写的好挫 /* *********************************************** Author :guanjun Created Time :2016/9/21 19:50:13 File Name :1001.cpp *******

京东2017校招编程题

1.进制均值 尽管是一个CS专业的学生,小B的数学基础很好并对数值计算有着特别的兴趣,喜欢用计算机程序来解决数学问题,现在,她正在玩一个数值变换的游戏.她发现计算机中经常用不同的进制表示一个数,如十进制数123表达为16进制时只包含两位数7.11(B),用八进制表示为三位数1.7.3,按不同进制表达时,各个位数的和也不同,如上述例子中十六进制和八进制中各位数的和分别是18和11,. 小B感兴趣的是,一个数A如果按2到A-1进制表达时,各个位数之和的均值是多少?她希望你能帮她解决这个问题? 所有的

网易2017校招编程题

内推挂了,继续再战! 1.分苹果: 小易去买苹果,有两种包装,一种一袋8个,一种一袋6个,小易要买n个苹果(不能多也不能少),输出袋子最少的购买方案下的袋子,若无法正好买到n个,则输出-1. 解:设8个一袋的买了pack8袋,6个一袋的买了pack6袋.想要总袋子数最少,那么肯定优先买8个一袋的,最多能买n/8袋,先另pack8=n/8,计算该情况下,pack6为多少能满足总苹果数为6,若无法满足,则减少pack8的数量,直到可以满足总量为n. #include<iostream> using

JavaScript编程题(含腾讯2016校招题)

作者:ManfredHu 链接:http://www.manfredhu.com/2016/04/02/15-veryGoodForUsing/ 声明:版权所有,转载请保留本段信息,否则请不要转载 几道觉得挺有意思的编程题,感觉做下来,自己对一些新方法的看法有了新的变化. 比如indexOf,reduce,Array.isArray,forEach这些方法,以前一看到兼容性是IE9+就有点害怕,项目中不敢用,导致后面越来越陌生,不过现在一想的话.其实只要用Polyfill或者提前fix掉就可以了

2017年校招全国统一模拟笔试(第二场)编程题集合-牛客网

 2017年校招全国统一模拟笔试(第二场)编程题集合-牛客网 链接:https://www.nowcoder.com/questionTerminal/276712b113c6456c8cf31c5073a4f9d7来源:牛客网 牛牛有两个字符串(可能包含空格),牛牛想找出其中最长的公共连续子串,希望你能帮助他,并输出其长度. 输入描述: 输入为两行字符串(可能包含空格),长度均小于等于50. 输出描述: 输出为一个整数,表示最长公共连续子串的长度. 输入例子: abcde abgde 输出例子