NOIP学习之字符串:75.最长最短单词

测试链接
总时间限制: 1000ms 内存限制: 65536kB
描述
输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一个连续的字母构成,空格和逗号都是单词间的间隔。

试输出第1个最长的单词和第1个最短单词。

输入
一行句子。
输出
两行输出:
第1行,第一个最长的单词。
第2行,第一个最短的单词。
样例输入
I am studying Programming language C in Peking University
样例输出
Programming
I
提示
如果所有单词长度相同,那么第一个单词既是最长单词也是最短单词。
定义函数 int sscanf (const char *str,const char * format,…);
函数说明
sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。 返回0表示失败 否则,表示正确格式化数据的个数 例如:sscanf(str,"%d%d%s", &i,&i2, &s); 如果三个变成都读入成功会返回3。 如果只读入了第一个整数到i则会返回1。证明无法从str读入第二个整数。
定义太抽象了,我们还是先来看一下常见的用法吧:
(1)sscanf("zhoue3456 ", “%4s”, str); //取指定长度的字符串
printf(“str=%s\n”, str); //str=“zhou”;
(2)sscanf(“zhou456 hedf”, “%[^ ]”, str); //取到指定字符为止的字符串,取遇到空格为止字符串
printf(“str=%s\n”, str); //str=zhou456;
(3)sscanf(“654321abcdedfABCDEF”, “%[1-9a-z]”, str); //取仅包含指定字符集的字符串
printf(“str=%s\n”, str); //str=654321abcded,只取数字和小写字符
(4)sscanf(“BCDEF123456abcdedf”, “%[^a-z]”, str); //取到指定字符集为止的字符串
printf(“str=%s\n”, str); // str=BCDEF123456, 取遇到大写字母为止的字符串
(5)int a,b,c;
sscanf(“2015.04.05”, “%d.%d.%d”, &a,&b,&c); //取需要的字符串
printf(“a=%d,b=%d,c=%d”,a,b,c); // a=2015,b=4,c=5
通过上面这几个例子相信大家对sscanf的用法会有一个直观的理解了,下面我们再来看一下更复杂一些的例子:
(6)给定一个字符串“abcd&helloKaTeX parse error: Expected 'EOF', got '&' at position 12: why”,现在我想取出&̲与之间的字符串怎么办呢
sscanf(“abcd&hello w h y " , " why", "%*[^&]&%[^ ]”, str );printf(“str=%s\n”,str); //str=“hello”
其中%[]类似于一个正则表达式,如[a-z]表示读取所有a-z的字符,[a-z]表示读取所有非小写字母的字符。那么在这里%*[&]表示先过滤掉abcd,然后以&隔开,后面还剩hello w h y why,然后将 之前非$的字符提取到str中。
(7)给定一个字符串“what, time”,如果我想仅保留time,那该怎么办呢?(,后面有个空格)
sscanf(“what, time”, “%*s%s”, str );printf(“str=%s\n”,str); //str=“time”
其中%s表示第一个被匹配到的字符串what,被过滤掉了,如果没有空格,则结果为NULL。其实“what, time”被空格分割成了两个字符串"what,“和"time”.
然而有人会问,C语言中的scanf和sscanf有什么区别和联系呢?OK,sscanf和scanf确实很类似,两者都是用于输入。只是后者以屏幕stidin为输入源,而前者是以字符串为输入源,仅此而已。
函数原型:int scanf( const char format [,argument]… );
其中的format可以是一个或多个 {%[
] [width] [{h | l | I64 | L}]type | ’ ’ | ‘/t’ | ‘/n’ | 非%符号},注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
width:宽度,一般可以忽略,用法如: const char sourceStr[] = “hello, world”; char buf[10] = ; sscanf(sourceStr, “%5s”, buf); //%5s,只取5个字符
cout << buf<< endl; 
结果为:hello
{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。 
type :这就很多了,就是%s,%d之类。 
特别的: %
[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值。
如: const char sourceStr[] = “hello, world”; char buf[10] = ; 
sscanf(sourceStr, “%*s%s”, buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
 cout << buf<< endl; 结果为:world 
支持集合操作: %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
 %[aB’] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性

#include<iostream>
#include<cstring>
#include<cstdio>
int main()
{
    int i=0,maxLen=-1,minLen=-1,len;
    char a[20500],t[200],maxStr[200],minStr[200];
    
    gets(a);
    
	//扫描整个字符串,把逗号变为空格
	while(a[i]!='\0')
    {
        if(a[i]==',') a[i]=' ';
        i++;
    }
    
    i=0;
    while(a[i]!='\0')
    {
        if(a[i]!=' ')
        {
            sscanf(a+i,"%s",t); //扫描字符串,遇到非空格字符a[i],则用sscanf从地址a+i输入一个字符串t。(t就是一个单词)
           
            len=strlen(t);
            if(maxLen==-1||minLen==-1)
            {
                maxLen=minLen=len;
                strcpy(maxStr,t);
                strcpy(minStr,t);
            }
       		else
            {
                if(len>maxLen) 
				{ 
					maxLen=len; 
					strcpy(maxStr,t); 
				}
                if(len<minLen)
				{ 	
					minLen=len; 
					strcpy(minStr,t); 
				}
            }
            
            i=i+len;
        }
        else i++;        
    }
    printf("%s\n%s\n",maxStr,minStr);
    return 0;
}
发布了80 篇原创文章 · 获赞 0 · 访问量 761

猜你喜欢

转载自blog.csdn.net/wlxiong/article/details/104490133