Splitting strings

来源:互联网 发布:手机上淘宝电脑版网页 编辑:程序博客网 时间:2024/05/21 10:41

// Splitting strings.
// CS 509 Advanced Programming II, Fall 2002.

#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cassert>
#include <iostream>
#include <cctype>
#include "stopwatch.h"

typedef std::vector<std::string> strvec;
typedef std::string::size_type   str_indx;
const str_indx eostr = std::string::npos;

// Split a string at space characters into words; Koenig and Moo, page 88.

strvec
split(const std::string & str) {

  strvec ret;
  str_indx i = 0;

  while (i != str.size()) {
    while ((i != str.size()) and std::isspace(str[i]))
      ++i;

    str_indx j = i;
    while ((j != str.size()) and !std::isspace(str[j]))
      ++j;

    if (i != j) {
      ret.push_back(str.substr(i, j - i));
      i = j;
      }
    }

  return ret;
  }


// Split a string, using string member functions.

strvec
split1(const std::string & str) {

  strvec ret;
  str_indx i = 0;
  const char * const space = " /t/n";

  while (true) {
    i = str.find_first_not_of(space, i);
    if (i == eostr) break;

    const str_indx j = str.find_first_of(space, i);

    ret.push_back(str.substr(i, j - i));
    i = j;
    }

  return ret;
  }


// Split a string using generic algorithms and iterators, Koenig and Moo, page
// 152.


static bool
isnotspace(char c) {
  return !std::isspace(c);
  }


template < typename Out >
void split2(const std::string & str, Out oi) {

  typedef std::string::const_iterator str_citer;

  str_citer i = str.begin();

  while (true) {
    i = find_if(i, str.end(), isnotspace);
    if (i == str.end()) break;

    const str_citer j = find_if(i, str.end(), isspace);

    *oi++ = std::string(i, j);
    i = j;
    }
  }

// Split a string using string streams, iterators, and generic algorithms.

strvec
split3(const std::string & str) {

  std::istringstream iss(str);
  strvec words;

  std::copy(std::istream_iterator<std::string>(iss),
    std::istream_iterator<std::string>(),
    std::back_inserter(words));

  return words;
  }


// Split a string using string streams, iterators, and the range constructor.

strvec
split4(const std::string & str) {

  std::istringstream iss(str);

  return strvec(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>());
  }

   
// Split a string using string streams and a generic range constructor.

template < class Ctype >
Ctype
split5(const std::string & str) {

  std::istringstream iss(str);

  return Ctype(std::istream_iterator<std::string>(iss),
       std::istream_iterator<std::string>());
  }

   
static void
chk(const strvec & w1, const strvec & w2) {
  if (w1 != w2) {
    std::copy(w1.begin(), w1.end(),
      std::ostream_iterator<std::string>(std::cout));
    std::cout << "/n";
    std::copy(w2.begin(), w2.end(),
      std::ostream_iterator<std::string>(std::cout));
    std::cout << "/n";
    exit(EXIT_FAILURE);
    }
  }
   

#define time_it(_str, _f) /
  do { stopwatch sw; /
       sw.start(); /
       for (unsigned i = 0; i < iter_cnt; i++) const strvec wds = _f(_str); /
       sw.stop(); /
       fprintf(stderr, "%s %d %g/n", #_f, _str.size()/4, static_cast<double>(sw.elapsed())/static_cast<double>(iter_cnt)); } while (false)


static void
time_them(void) {

  const std::string ten = "000 001 002 003 004 005 006 007 008 009 ";
  const unsigned iter_cnt = 20;
  std::string s;

  for (unsigned i = 0; i < 10; i++) {
    s += ten + ten;
    time_it(s, split);
    time_it(s, split1);
    time_it(s, split3);
    time_it(s, split4);

    stopwatch sw;

    sw.start();
    for (unsigned i = 0; i < iter_cnt; i++) {
      strvec wds;
      split2(s, std::back_inserter(wds));
      }
    sw.stop();
    fprintf(stderr, "%s %d %g/n", "split2", s.size()/4,
    static_cast<double>(sw.elapsed())/static_cast<double>(iter_cnt));

    sw.start();
    for (unsigned i = 0; i < iter_cnt; i++) {
      strvec wds = split5<strvec>(s);
      }
    sw.stop();
    fprintf(stderr, "%s %d %g/n", "split5", s.size()/4,
    static_cast<double>(sw.elapsed())/static_cast<double>(iter_cnt));
    }
  }

static void
check_them(void) {
  std::string s;

  while (std::getline(std::cin, s)) {
    strvec words = split(s);
    chk(words, split1(s));
   
    strvec wds;
    split2(s, std::back_inserter(wds));
    chk(words, wds);
   
    chk(words, split3(s));
    chk(words, split4(s));
    }
  }

int main() {
  time_them();
  }


// $Log: split-string.cc,v $
// Revision 1.1  2002/10/31 21:42:06  rclayton
// Initial revision
//

原创粉丝点击