【牛客网】最后一个字符

题目描述

正在挑战一个CrackMe的你,把需要填写的前面几位密码都正确猜出了,可是这最后一位密码,好像藏得有点深。CrackMe的作者还挑衅般的在里面藏了个.tar.gz文件,解压缩出来,里面写道 你要的最后一个字符就在下面这个字符串里,这个字符是下面整个字符串中第一个只出现一次的字符。(比如,串是abaccdeff,那么正确字符就是b了) 然而下面给出来的字符串好像太长太长了,单靠人力完全无法找出来。 于是,你需要写一个程序代劳了。输入文件体积较大,请使用一些快速的输入输出手段,不推荐使用cin/cout,对Java并不推荐使用Scanner直接读写。
输入描述:
第一行,一个正整数T(T≤20)  ,表示输入数据组数。
之后T行,每行一个字符串S。( 1≤S 的长度≤1000000 ,保证字符串中出现的字符的ASCII码在[0x21,0x7F)范围内,即均为可显示的非空白符,同时保证一定有解)
输出描述:
一共T 行,每行一个字符C ,表示所给的相应字符串中第一个只出现一次的字符。
输入例子:
2
abaccdeff
testonline
输出例子:
b
s

首先,不用cin/cout,当然采用scanf函数了。由于已知字符范围,可以以hash的方法建立一个count数组,遍历一遍字符串,找到每个字符出现的次数。再对字符串进行第二次遍历,找到第一个只出现一次的字符。

          

#include <string>
#include<iostream>
#include<vector>
#include<algorithm>
#include <stdlib.h>
#include <stdio.h>
#define MAX 100000
using namespace std;


int main()
{
    int T;
    cin >> T;
    char str[1000000];
    string s;
    for (int i = 0; i < T; i++)
    {

        scanf("%s", str);
        s = str;
        //cin >> s;
        int n = 0x7F - 0x21;
        int count[94];
        for (int j = 0; j < n; j++)
            count[j] = 0;
        for (int j = 0; j < s.length(); j++)
        {
            count[s[j] - 0x21]++;
        }
        for (int j = 0; j < s.length(); j++)
            if (count[s[j] - 0x21] == 1)
            {
                cout << s[j] << endl; break;
            }
    }
    return 0;
}
注意点:
一、关于scanf

          在VS 2013 中编译scanf 函数,编译时便会提示如下错误:

error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

         原因是Visual C++ 2012 使用了更加安全的 run-time library routines 。新的Security CRT functions(就是那些带有“_s”后缀的函数),解决方案可以参考:http://www.cnblogs.com/gb2013/archive/2013/03/05/SecurityEnhancementsInTheCRT.html。

         另外,下面的代码是无法将字符串读入s的,需使用字符数组,在拷贝到string类型的变量中。

string s;
scanf("%s",&s);

 





posted @ 2016-08-12 16:42  翎飞蝶舞  阅读(281)  评论(0编辑  收藏  举报