zoukankan      html  css  js  c++  java
  • hdu 2072 1106学一波字符串分割,C语言与C++两种方法

      hdu2072题意:输出给定字符串中的单词数(一个句子中可能有两个相同的单词),这里的思想是把每个单词取出来,放入set(这个集合容器中不允许有相同的元素)中,最后输出该集合的大小即可。

      现在的问题就是怎么分割字符串,这里介绍一个C++STL里面的工具——stringstream,其被称之为字符串流,

      <这里扩展一点>:

      istringstream类用于执行C++风格的串流的输入操作。
      ostringstream类用于执行C风格的串流的输出操作。
      strstream类同时可以支持C风格的串流的输入输出操作。

    可以将一个字符串以C风格流的形式输出,输出的时候会在空格的位置停顿。下面说明一下怎么定义:

        1、使用stringstream 变量名(要分割的字符串);

      2、stringstream 变量名;  变量名.str(要分割的字符串);

      3、stringstream 变量名;  变量名 << 要分割的字符串;  // 第二句的位置不可以换。

      使用的时候先定义一个中间变量(类似迭代器一样去存取出来的字符串)使用while (字符串流 >> 中间变量)  while循环中对取出的字符串进行入集合的操作。(while里面的条件的前后的顺序也是不可以颠倒的,原因类似cin、cout)

      这里需要注意一个问题:stringstream不会主动释放内存,所以如果在一个程序中重复使用一个字符串流的时候需要清空一下;使用变量名.str(""); 或者 变量名.clear();

      上代码吧还是,一直看文字稍显枯燥,一看代码就精神了:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <string>
     4 #include <sstream>
     5 #include <set>
     6 using namespace std;
     7 
     8 int main() {
     9     string str;
    10     while (1) {
    11         getline(cin, str);
    12         if (str[0] == '#') break;
    13         
    14         set<string> ans;
    15         string a;
    16         stringstream ss(str);
    17         /*
    18         stringstream ss;
    19         ss << str;
    20         */
    21         /*
    22         stringstream ss;
    23         ss.str(str);
    24         */
    25         while(ss >> a)
    26             ans.insert(a);
    27         cout << ans.size() << endl;
    28     }
    29     return 0;
    30 }    
    hdu2072单词数

      hdu1106排序:题意:以5为分隔符,从一串数字中提取出单个数字,排序输出.(要考虑到前导0和好几个5连续出现的时候)。

      解法一使用C++STL中的stringstream实现,因为stringstream是以空格表示一个字符串结束的,所以可以加载到字符串流的之前进行预处理(将数字串中5替换为空格)。然后再使用上面学到的stringstream方法进行提出子串、转换为数字、存到一维数组里面、排序(可以使用C++STL中的sort函数,也可以使用冒泡、选择、快排、插入排序、二分排序等方法)、输出即可。具体细节见代码:

     1 /*
     2  *   > File Name: HDU1106.cpp
     3  *   > Author: Ddlm2wxm
     4  *   > Mail: Ddlm2wxm@163.com 
     5  *   > Created Time: 2017/4/11 16:10:22
     6   *****************************************/
     7 
     8 #include <iostream>
     9 #include <algorithm>
    10 #include <string>
    11 #include <cstring>
    12 #include <cstdio>
    13 #include <sstream>
    14 using namespace std;
    15 
    16 int main() {
    17     string s;
    18     int a[1010];
    19     while (cin >> s) {
    20         int len = s.length(), k = 0;
    21         for (int i = 0; i < len; ++i) {
    22             if (s[i] == '5') {
    23                 s[i] = ' ';
    24             }
    25         }
    26         stringstream ss(s);
    27         string res;
    28         while (ss >> res) {
    29             int len1 = res.length();
    30             int num = 0;
    31             for (int i = 0; i < len1; ++i) {
    32                 num = num*10 + (res[i]-'0');
    33             }
    34             a[k++] = num;
    35         }
    36         sort (a, a + k);
    37         for (int i = 0; i < k; ++i) {
    38             if (i) {
    39                 printf(" ");
    40             }
    41             printf ("%d", a[i]);
    42         }
    43         cout << endl;
    44     }
    45     return 0;
    46 }
    hdu1106排序(stringstream)

      解法二:使用C语言string.h中的strtok函数:

      语法:

        char *strtok(char *s, const char *delim);
      功能:Parse S into tokens separated by characters in DELIM.If S is NULL, the saved pointer in SAVE_PTR is used as the next starting point.
         (以delim中的字符串为分界符,将s分割为一个一个的子串)
      返回值:
        1、从s开始的位置开始分割,到字符串结束的时候返回NULL;
        2、每找到一个子串就退出,当再次调用strtok函数的时候从上一次停下来的位置继续寻找,知道字符串的末尾,返回NULL。
      注意:strtok会破坏原字符串的结构

      对于这道题来说,毫无疑问就是用"5"为分隔符,取出一个子串,使用atoi函数转换为整数(头文件stdlib.h传入参数为字符串指针类型,这里扩展一个atol函数,是将字符串转换为长整型),存到一个数组里面排序输出即可。
     1 /*
     2  *   > File Name: HDU1106.cpp
     3  *   > Author: Ddlm2wxm
     4  *   > Mail: Ddlm2wxm@163.com
     5  *   > Created Time: 2017/4/11 16:10:22
     6   *****************************************/
     7 #include <stdio.h>
     8 #include <string.h>
     9 #include <stdlib.h>
    10 
    11 int cmp(const void *a, const void*b) {
    12     return *(int*)a-*(int*)b;
    13 }
    14 
    15 int main() {
    16     int n, i, cnt;
    17     int b[1100];
    18     char a[1100], *p;
    19     while(~scanf("%s", a)) {
    20         cnt = 0;
    21         p = strtok(a, "5");
    22         while(p != NULL) {
    23             b[cnt++] = atoi(p);
    24             p = strtok(NULL,"5");
    25         }
    26         qsort(b,cnt,4,cmp);
    27         printf("%d",b[0]);
    28         for(i=1; i<cnt; i++)
    29             printf(" %d",b[i]);
    30         printf("
    ");
    31     }
    32     return 0;
    33 }
    hdu1106排序


    --------------------------------------------------------------------------------------------------

      再加一点笔记:

      除了在string.h下的strtok之外,鄙人认为其他比较方便的还有:

       1、strpbrk: char *strpbrk( const char *str1, const char *str2 );

         函数返回一个指针,它指向字符串str2中任意字符在字符串str1 首次出现的位置,如果不存在返回NULL。

       2、strchr:char *strchr( const char *str, char ch );

         函数返回一个指针,它指向字符ch 在字符串str首次出现的位置,如果匹配失败,返回NULL。

       3、strstr: char *strstr( const char *str1, const char *str2 );

         函数返回一个指针,它指向字符串str2 首次出现于字符串str1中的位置,如果没有找到,返回NULL。

       4、strtok: char *strtok( char *str1, const char *srt2 );

         函数返回字符串str1中紧接“标记”的部分的指针, 字符串str2是作为标记的分隔符。如果分隔标记没有找到,函数返回NULL。为了将字符串转换成标记,第一次调用str1 指向作为标记的分隔符。之后所以的调用str1都应为NULL。(第二次调用的时候str1位置给NULL就会接着上一次的位置分割)

       先总结这些,再有学习到会更新。

  • 相关阅读:
    tushare包使用案例
    Matplotlib模块:绘图和可视化
    pandas使用
    django 表操作
    元数据Meta
    django关系类型字段
    django项目模型字段
    django项目mysite 2
    django安装使用xadmin
    GCC版本中没有GLIBCXX_3.4.15错误
  • 原文地址:https://www.cnblogs.com/Ddlm2wxm/p/6694264.html
Copyright © 2011-2022 走看看