zoukankan      html  css  js  c++  java
  • 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


  • 相关阅读:
    stl测试
    noip2017逛公园
    比赛
    莫队算法
    noi.ac 第五场第六场
    重排DL
    bzoj2870
    异象石(就是sdio宝藏那题)
    Genius ACM
    模板复习
  • 原文地址:https://www.cnblogs.com/XBWer/p/2554441.html
Copyright © 2011-2022 走看看