这里CSV格式,就是一种用','分割的字符串格式。进入正文前,偶先讲件小事情。
公司发上年的XX奖,一封notes邮件发来,收件人竟有几百人之多。偶有心统计一下具体人数,想瞅瞅这茫茫人海中是否有个叫smileonce的人的份子,怎么办?盯着屏幕细细的数么?
偶才没有那么笨呢,当然不会浪费那么多时间。不然公司雇偶干活岂不是太花冤枉钱么?:)
coder当然有coder的方法了,那就是花1分钟时间,用program来搞定。(1分钟,别不信,其实我已经把时间估计的很充裕了。)
notes收件人的格式是:
zhang3@xxx.net,li4@xxx.net,wang5@xxx,net,...,wanyan108@xxx.net,xiahou210@xxx.net
就是这么一个长字符串,偶把它copy到剪贴板里面先。
然后偶祭起法宝PythonWin:
>>> str = "zhang3@xxx.net,li4@xxx.net,wang5@xxx,net,...,wanyan108@xxx.net,xiahou210@xxx.net"
>>> lst = str.split(',')
>>> print "The count of person is : %i" % len(lst)
The count of person is : 766
>>> #assign my name to x
>>> x = smileonce@xxx.net
>>> if x in lst:
... print "%s is in the list, index is: %i" % ( x, lst.index(x))
... else:
... print "Sorry, %s is NOT in the list !" % x
...
Sorry, smileonce@xxx.net is NOT in the list !
好遗憾呀,又没有发成财!:p
(本文例子一半为虚构,如有雷同绝对是巧合!)
好了,讲到这里,估计偶也不用说怎么操作CSV了,那都是同样的小儿科。偶想说的是,语言本无孰优孰略,关键在于你能不能游刃有余!
-------------
乾坤一笑 写于2005年5月16日 转载请标明出处和原文链接
--------------------next---------------------
#include
#include
using namespace std;
int main( void )
{
const char str[] = "zhang3@xxx.net,smileonce@xxx.net,li4@xxx.net,wang5@xxx,wanyan108@xxx.net,xiahou210@xxx.net";
// lst = str.split(',')
// print "The count of person is : %i" % len(lst)
cout << "The count of person is : " << count( str, str+sizeof(str)/sizeof(str[0])-1, ',' )+1 << endl;
// x = smileonce@xxx.net
const char substr[] = "smileonce@xxx.net";
// if x in lst:
const char* p = search( str, str+sizeof(str)/sizeof(str[0])-1, substr, substr+sizeof(substr)/sizeof(substr[0])-1 );
if( p != str+sizeof(str)/sizeof(str[0]) )
//print "%s is in the list, index is: %i" % ( x, lst.index(x))
cout << substr << " is in the list, index is: " << count( str, p, ',' ) << endl;
else
//print "Sorry, %s is NOT in the list !" % x
cout << "Sorry, " << substr << " is NOT in the list !" << endl;
return 0;
}
--------------------next---------------------
其实你想过没有,无论是Python还是jsp的split,其实都有一个问题,即使split的返回值类型只存储各个substr在sourcestr中的索引,那么如果在sourcestr非常巨大的情况下,耗费的内存也是不可小视的,并且它们是冗余的。
如果使用C语言函数strtok,不但只需要遍历一次,而且不消耗大量的内存。
#include
#include
using namespace std;
int main( void )
{
char str[] = "zhang3@xxx.net,smileonce@xxx.net,li4@xxx.net,wang5@xxx,wanyan108@xxx.net,xiahou210@xxx.net";
char substr[] = "smileonce@xxx.net";
size_t sum = 0;
size_t index = -1;
for( char* token=strtok(str,","); token!=0; ++sum, token=strtok(0,",") )
if( strcmp(token,substr) == 0 ) index = sum+1;
cout << "The count of person is : " << sum << endl;
if( index != -1 )
cout << substr << " is in the list, index is: " << index << endl;
else
cout << "Sorry, " << substr << " is NOT in the list !" << endl;
return 0;
}
--------------------next---------------------
#include
#include
#include
using namespace std;
using namespace boost;
int main()
{
string str = "zhang3@xxx.net,smileonce@xxx.net,li4@xxx.net,wang5@xxx,wanyan108@xxx.net,xiahou210@xxx.net";
string substr = "smileonce@xxx.net";
char_separator sep(",");
typedef tokenizer > char_token;
char_token tokens(str, sep);
int index = -1;
int sum = 0;
for (char_token::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
std::cout << sum << ": " << *tok_iter << "\n";
if( *tok_iter == substr)
index = sum;
sum++;
}
cout << "The count of person is : " << sum << endl;
if( index != -1 )
cout << substr << " is in the list, index is: " << index << endl;
else
cout << "Sorry, " << substr << " is NOT in the list !" << endl;
return 0;
}
//cl /GX /MD /I"D:\boost\boost_1_32_0" token.cpp
--------------------next---------------------
谢谢各位给出对比程序,受益非浅!
回答星星的疑问:偶并非不会用C写,偶只是不想在解决这种小事浪费时间(初步判断,偶1分钟内用C搞不定,要调试;而这种场合用Python只需要几十秒钟就可以解决问题,并且可以保证不会隐藏的bug)
另外,Python的运行效率确实很低,比java还低。所以它常应用于不要求运行效率,但急需开发效率的场合。
如,今天,偶在偶的C代码里面添加一个复杂的数组,用于定义一个128Mb的ROM的地址分配,以16×64K为一个block,来生成具有128个元素的地址序列。基本如下:
int addr = {
{ 0x0000000, 0x0010000, 0x0020000, ...},
....
}
这个东西如果用手写不知需要多少时间,用copy/paste的方法又容易改错,用C编码生成它又太大材小用浪费时间去调试。这时候偶就用Python,写3个循环嵌套来生成这个数组的代码。基本上不用花多少时间,也是1分钟左右搞定。:)
当然,Python之强大也不仅局限于此,不过因为我也是边学边卖,所以估计也是越用越熟,慢慢把Python的长处逐步发挥出来。
--------------------next---------------------
boost 只要编译器支持,只看文档,不看具体实现,其实用起来相当顺手,有点script的味道。可惜俺用的vc6太差了,很多不支持。
我觉得大部分c++程序员有个毛病就是总想看是如何实现的,结果看boost看得头晕也不甚明白,说实话有些boost库没有很深的模板功底确实是天书一般,而且对编译器要求甚高,可能也影响了它的使用范围。
不过毕竟boost不一般,这些c++社区中的精英们写出来的东西我还是很信任的,有时候就当自己是个白痴,直接用就是了。你知道python底层是如何实现split的吗?估计不知道。因此你也可以不要知道boost/tokenizer是如何实现的。难的糊涂!
split可能不会被标准化,毕竟只要有个iterator range,直接调用std::copy + back_inserter 就可以将它置入一个容器中。
--------------------next---------------------
阅读(612) | 评论(0) | 转发(0) |