免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: SybaseLU
打印 上一主题 下一主题

关于list容器的remove() [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-08-13 18:11 |只看该作者
特化了一下remove函数,貌似是最好的解决办法了

  1. //main.cpp

  2. #include <iostream>
  3. #include <fstream>
  4. #include <list>
  5. #include <iterator>
  6. #include <functional>
  7. #include <cstdlib>
  8. #include <cstring>

  9. using namespace std;

  10. template <typename T>
  11. class List : public list<T>
  12. {
  13. public:
  14.         void remove(const char  * const & value)
  15.         {
  16.                 iterator first = begin();
  17.                 iterator last = end();
  18.                 iterator m_prev = first;
  19.                 while (first != last)
  20.                 {
  21.                         iterator next = first;
  22.                         ++next;
  23.                         if (strcmp(*first ,value) == 0)
  24.                                 erase(first);
  25.                         else
  26.                                 m_prev = first;
  27.                         first = next;
  28.                 }
  29.         }
  30. };



  31. int main(void)
  32. {
  33.         char ss[][10] = {"aaaa", "bbbb", "cccc"};
  34.         List<char*> S;
  35.         for(int i=0; i<=2; i++) {
  36.                 S.push_back(ss[i]);
  37.         }
  38.         S.remove("aaaa");
  39.         copy(S.begin(), S.end(), ostream_iterator<char*>(cout, "\n"));
  40.         system("pause");
  41.         return 0;
  42. }
复制代码

论坛徽章:
0
12 [报告]
发表于 2007-08-13 18:43 |只看该作者
重载【特化】remove()这不为一个“好的”解决办法。
两者的char* 为什么又这样的区别呢?

  1. main()
  2. {
  3.         char* as = "aaa";
  4.         char* bs = "bbb";
  5.         char* cs  = "aaa";

  6.         char context[][5] = {
  7.                 "aaa",
  8.                 "bbb",
  9.                 "aaa"
  10.         };

  11.         list<char*> S;
  12.         list<char*>::iterator j;

  13.         for (int k=0; k<3; k++)
  14.                 S.push_back(context[k]);

  15.         printf("context:\n");
  16.         for(j=S.begin(); j != S.end(); ++j) cout << *j << " ";
  17.         cout << endl;

  18.         S.remove("aaa");
  19.       for(j=S.begin(); j != S.end(); ++j) cout << *j << " ";
  20.         cout << endl;

  21.         S.clear();
  22.         printf("local:\n");
  23.         S.push_back("aaa");
  24.         S.push_back("bbb");
  25.         S.push_back("aaa");
  26.         for(j=S.begin(); j != S.end(); ++j) cout << *j << " ";
  27.         cout << endl;

  28.         S.remove("aaa");
  29.         for(j=S.begin(); j != S.end(); ++j) cout << *j << " ";
  30.         cout << endl;

  31. return 0;
复制代码

结果:

  1. [ Source]$ ./a.out
  2. context:
  3. aaa bbb aaa
  4. aaa bbb aaa
  5. local:
  6. aaa bbb aaa
  7. bbb
  8. [Source]$
复制代码

标准的STL也不行,反过来试试tiny STL

  1.   ....
  2. x.push_back("aaa");
  3. x.push_back("bbb");
  4. x.push_back("aaa");

  5.    for (xi = x.begin(); xi != x.end(); ++xi)
  6.              printf("strIte:%s\n", (*xi.node).data);

  7.    x.remove("aaa");

  8.     while (1)
  9.         {
  10.                 if (!x.eof())
  11.                         printf("pop:%s\n", x.pop_back());
  12.                 else {
  13.                         printf("Is empty\n");
  14.                         break;
  15.                 }
  16.         }
  17.    ...
复制代码

结果:

  1. strIte:aaa
  2. strIte:bbb
  3. strIte:aaa
  4. pop:bbb
  5. Is empty
  6. ==========char*==============
复制代码

居然也可以了,为什么?

[ 本帖最后由 SybaseLU 于 2007-8-13 18:47 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2007-08-13 19:05 |只看该作者
还有一种方法, 实现一个tiny AString只实现operator==()

  1. class AString
  2. {
  3.     AString(const char* as) { strncpy(m_string, as, strlen(as)+1); }
  4.    ~AString() {}

  5.    operator==(const char* as) { return (strcmp(m_string, as) == 0) }
  6.    char m_string[xxxx];
  7. }
复制代码

论坛徽章:
0
14 [报告]
发表于 2007-08-14 01:10 |只看该作者
原帖由 SybaseLU 于 2007-8-13 10:16 发表
main()
{

        char* as = "aaaaaa";
        char* bs = "bbbbbb";
        char* cs  = "aaaaaa";

        list S;
        list::iterator j;
        S.push_back(as);
        S.push_back ...

  1. if (*first == value) erase(first);
复制代码


*first先做重载运算符*调用返回的是之前被push_back的地址
所以实质上这里只比较了地址而已
编译器"聪明的"把相同的常量字串放到了同样的地方,即相同字串只有一份拷贝
所以比较结果会满足你的语意要求
但你这样写不能保证移植性哦

如下的情况一定是你不愿意看到的哈
所以还是用string吧

  1. #include <iostream>
  2. #include <list>
  3. using namespace std;

  4. int main()
  5. {

  6.         char* as = "aaaaaa";
  7.         char* bs = "bbbbbb";
  8.         char* cs  = "aaaaaa";
  9.         char ds[] ="aaaaaa";

  10.         list<char*> S;
  11.         list<char*>::iterator j;
  12.         S.push_back(as);
  13.         S.push_back(bs);
  14.         S.push_back(cs);
  15.         S.push_back(ds);

  16.         for(j=S.begin(); j != S.end(); ++j) cout << *j << " ";
  17.         cout << endl;

  18.         S.remove("aaaaaa");
  19.         for(j=S.begin(); j != S.end(); ++j) cout << *j << " ";
  20.         cout << endl;

  21.         return 0;
  22. }
复制代码

[ 本帖最后由 huntrsky 于 2007-8-14 01:11 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP