Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 20954 Accepted Submission(s): 5495
My code:
1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 int data[100005]; 7 char str[100005]; 8 9 int main() 10 { 11 int i; 12 int count; 13 int num; 14 int flag; 15 while(~scanf("%s",str)) 16 { 17 flag=0; 18 count=0; 19 num=0; 20 memset(data,0,sizeof(data)); 21 for(i=0;i<strlen(str);i++) 22 { 23 if((str[i]-'0')==5&&(str[i-1]-'0')!=5) 24 { 25 num=0; 26 count++; 27 } 28 if((str[i]-'0')!=5) 29 { 30 data[count]+=((str[i]-'0')%10); 31 if((str[i+1]-'0')!=5&&(i+1<strlen(str))) 32 data[count]*=10; 33 num++; 34 } 35 } 36 if((str[0]-'0')==5) 37 flag=1; 38 if((str[strlen(str)-1]-'0')==5) 39 { 40 sort(data,data+(count)); 41 printf("%d",data[flag]); 42 for(i=++flag;i<count;i++) 43 { 44 printf(" %d",data[i]); 45 } 46 } 47 else 48 { 49 sort(data,data+(count+1)); 50 printf("%d",data[flag]); 51 for(i=++flag;i<=count;i++) 52 { 53 printf(" %d",data[i]); 54 } 55 } 56 printf("\n"); 57 } 58 return 0; 59 }
总结:学到了下面这个结构(以某个特殊字符串为分割符分隔一个串)
p = strtok(a,"5");
while(NULL != p)
{
p = strtok(NULL,"5");
}
wa了两次后开始看论坛上朋友们的代码,最后找到竟然是错在了qsort上,定义cmp时中间的减号写成了大于号,和定义sort的比较函数不一样啊,这个以前本来是记得的,长时间不用还真的不行。。
另外还发现了一个朋友写的不错,用到了sscanf函数,使得程序很简单,自己也顺便了解了下sscanf,具体用法贴在“杂乱知识”里,他的代码也贴在下面,有兴趣的可以学习。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 int cmp(const void* a,const void* b){ return *(int*)a-*(int*)b;} 5 int main() 6 { 7 char a[1000]; 8 int b[1000],size,i; 9 char* p; 10 while(EOF!=scanf("%s",a)) 11 { 12 size=0; 13 p = strtok(a,"5"); 14 while(NULL != p) 15 { 16 b[size++] = atoi(p); 17 p = strtok(NULL,"5"); 18 } 19 qsort(b,size,sizeof(int),cmp); 20 for(i=0;i<size-1;i++) 21 printf("%d ",b[i]); 22 printf("%d\n",b[i]); 23 } 24 return 0; 25 }
补充:
sscanf()函数
http://baike.baidu.com/view/1364018.htm
几个例子:
1. 常见用法。
char buf[512] ;
sscanf("123456 ", "%s", buf);//此处buf是数组名,它的意思是将123456以%s的形式存入buf中!
printf("%s\n", buf);
结果为:123456
2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf("123456 ", "%4s", buf);
printf("%s\n", buf);
结果为:1234
3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
结果为:123456
4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
当输入:
sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf);
printf("%s\n",buf);
结果为:123456
5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中
sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
printf("%s\n", buf);
结果为:12DDWDFF
7、给定一个字符串"hello, world",仅保留world。(注意:","之后有一空格,%s遇空格停止,加*则是忽略第一个读到的字符串)
sscanf("hello, world", "%*s%s", buf);
printf("%s\n", buf);
结果为:world
%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
如果没有空格则结果为NULL。
sscanf的功能很类似于正则表达式, 但却没有正则表达式强大,所以如果对于比较复杂的字符串处理,建议使用正则表达式.
//-------------------------------------------------------
用它来分隔类似这样的字符串2006:03:18:
int a, b, c;
/*sscanf("2006:03:18", "%d:%d:%d", a, b, c); */ /*错误方法, 要在变量a,b,c前加上取地址符, modified by huanmie_09*/
sscanf("2006:03:18", "%d:%d:%d", &a, &b, &c);
以及2006:03:18 - 2006:04:18:
char sztime1[16] = "", sztime2[16] = "";
sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2);
但是后来,我需要处理2006:03:18-2006:04:18
仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。
我需要重新设计一个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统一的风格,我需要改动很多地方,把已有的sscanf替换成我自己的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满而入睡;一觉醒来,发现其实不必。
format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。
%[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。
所以那个问题也就迎刃而解了:
sscanf("2006:03:18 - 2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2);
在softmse (Jake) 的问题贴http://community.csd(去掉我)n.n(去掉我)et/Expert/topic/4843/4843294.xml?temp=.4321558中 ,给出了一个很cool的sscanf用例,而后通过学习,发现sscanf真棒,现做一总结。
原问题:
iios/12DDWDFF@122
获取/和@之间的字符串怎么做
C程序里面有什么函数吗?
代码:
#include <stdio.h>
int main()
{
const char* s = "iios/12DDWDFF@122";
char buf[20];
sscanf( s, "%*[^/]/%[^@]", buf );
printf( "%s\n", buf );
return 0;
}
结果为:12DDWDFF
strtok()函数
http://baike.baidu.com/view/1028553.htm
原型:
char *strtok(char *s, const char *delim);
功能:
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
atoi()函数
http://baike.baidu.com/view/653935.htm
C语言库函数名: atoi
功 能: 把字符串转换成整型数.
名字来源:array to integer 的缩写.
原型: int atoi(const char *nptr);
函数说明: 参数nptr字符串,如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。
头文件: #include <stdlib.h>
程序例:
1)
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int n;
char *str = "12345.67";
n = atoi(str);
printf("string = %s integer = %d\n", str, n);
return 0;
}
执行结果
string = 12345.67 integer = 12345
2)
#include <stdlib.h>
#include <stdio.h>
int main()
{
char a[] = "-100" ;
char b[] = "123" ;
int c ;
c = atoi( a ) + atoi( b ) ;
printf("c = %d\n", c) ;
return 0;
}
执行结果
c = 23
简单的实现atoi函数源代码:
#include <cctype>
int my_atoi(const char* p){
assert(p != NULL);
bool neg_flag = false;// 符号标记
int res = 0;// 结果
if(p[0] == '+' || p[0] == '-')
neg_flag = (*p++ != '+');
while(isdigit(*p)) res = res*10 + (*p++ - '0');
return neg_flag ?0 -res : res;
}