HDOJ1106 分解字符串、转化及排序问题总结[sscanf()函数+strtok()函数+atoi()函数]

排序

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 20954    Accepted Submission(s): 5495


Problem Description
输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。

你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。

 
Input
输入包含多组测试用例,每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。  

输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。
 
Output
对于每个测试用例,输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。
 
Sample Input
0051231232050775
 
Sample Output
0 77 12312320
 
Source
 
Recommend
Eddy
 
 

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 }
 
 
注意几种特殊的数据,搞了半天,有失有得。
  • 512351234     以5打头
  • 2345555523   多个5连续在一起
  • 124523335     以5结尾
 

 
 
[转]

总结:学到了下面这个结构(以某个特殊字符串为分割符分隔一个串)

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;

 

  }







            If you have any questions about this article, welcome to leave a message on the message board.



Brad(Bowen) Xu
E-Mail : maxxbw1992@gmail.com


原文地址:https://www.cnblogs.com/XBWer/p/2554441.html