用C++的string::size()和string::length()返回值做比较
2016-03-16 14:17
453 查看
楼主今天在自己实现kmp算法的c++代码时,发现了一个问题。我先把代码贴上来。
请注意第39行,我原来写的循环条件是如注释一样的。后来发现无论如何循环都只跑一遍,然后就退出了,不能得到正确的结果,思前想后都不知道到底是哪里出了问题。然后才将
这个时候我就猜可能是
The number of bytes in the string.
size_t is an unsigned integral type (the same as member type string::size_type).
瞬间明白了:
并由此推导出:当它的返回值和一个有符号数比较时,有符号数会被隐式转换成无符号数。(不是取绝对值,而是对将最高为(MSB)当成数字处理,不再表示符号)
KMP算法里,游标j可能为-1,因此当判断条件
我做的实验如下:
打印的内容也充分地说明了这一点,同时还说明了
-1
4294967295
K > i true
test.size() > i false
slen > 0 true
llen > 0 true
slen > -1 true
llen > -1 true
test.size() > 0 true
test.length() > 0 true
test.size() > -1 false
test.length() > -1 false
提醒自己:不要将string类型的size()和length()方法的返回值直接用来比较,可能会产生预计之外的情况
//kmp search #include <iostream> #include <vector> using namespace std; vector<int> GetNext(string pattern) { vector<int> next(pattern.size(), -1); int i = 0; int j = -1; while(i < pattern.size()) { if(j == -1 || pattern[i] == pattern[j]) { i++; j++; if(pattern[i] != pattern[j]) next[i] = j; else next[i] = next[j]; } else { j = next[j]; } } return next; } int KmpSearch(string text, string pattern) { if(text.size() <= 0 || pattern.size() <= 0) return -1; vector<int> next = GetNext(pattern); int i = 0; int j = 0; int slen = text.size(); int plen = pattern.size(); while(i < slen && j < plen)//while(i < text.size() && j < pattern.size()) { if(j == -1 || text[i] == pattern[j]) { i++; j++; } else { j = next[j]; } } if(j == pattern.size()) return i-j; return -1; } int main(int argc, char const *argv[]) { string txt = "BBCAAAAB ABCDAB ABCDABCDABDE"; string pat = "ABCDABD"; cout << "index = " << KmpSearch(txt, pat) << endl; return 0; }
请注意第39行,我原来写的循环条件是如注释一样的。后来发现无论如何循环都只跑一遍,然后就退出了,不能得到正确的结果,思前想后都不知道到底是哪里出了问题。然后才将
text.size()替换成了一个
signed int型的数字,这才解决了问题。
这个时候我就猜可能是
string::size()的返回值的问题,跑去cpp reference string::size()查看,赫然发现这样一句话:
The number of bytes in the string.
size_t is an unsigned integral type (the same as member type string::size_type).
瞬间明白了:
string::size()返回的是一个无符号的整数。
并由此推导出:当它的返回值和一个有符号数比较时,有符号数会被隐式转换成无符号数。(不是取绝对值,而是对将最高为(MSB)当成数字处理,不再表示符号)
KMP算法里,游标j可能为-1,因此当判断条件
j < text.size()中的j为-1时,它的二进制补码为0xFFFFFFFF,而作为无符号数它被转化为了4294967295,因此没有按我本来的意思执行。
我做的实验如下:
//test for string::size() and string::length() #include <iostream> int main(int argc, char const *argv[]) { string test("abcd"); int slen = test.size(); int llen = test.length(); signed int i = -1; unsigned int K = 4294967295; int minus_one = 0xFFFFFFFF; cout << minus_one << endl; cout << 0xFFFFFFFF << endl; if(K >= i) cout << "K > i true" << endl; else cout << "K > i false" << endl; if(test.size() > i) cout << "test.size() > i true" << endl; else cout << "test.size() > i false" << endl; if(slen > 0) cout << "slen > 0 true" << endl; else cout << "slen > 0 false" << endl; if(llen > 0) cout << "llen > 0 true" << endl; else cout << "llen > 0 false" << endl; if(slen > -1) cout << "slen > -1 true" << endl; else cout << "slen > -1 false" << endl; if(llen > -1) cout << "llen > -1 true" << endl; else cout << "llen > -1 false" << endl; if(test.size() > 0) cout << "test.size() > 0 true" << endl; else cout << "test.size() > 0 false" << endl; if(test.length() > 0) cout << "test.length() > 0 true" << endl; else cout << "test.length() > 0 false" << endl; //pay attention to the following lines if(test.size() > -1) cout << "test.size() > -1 true" << endl; else cout << "test.size() > -1 false" << endl; if(test.length() > -1) cout << "test.length() > -1 true" << endl; else cout << "test.length() > -1 false" << endl; return 0; }
打印的内容也充分地说明了这一点,同时还说明了
string::length()的行为与
string::size()是完全相同的。
-1
4294967295
K > i true
test.size() > i false
slen > 0 true
llen > 0 true
slen > -1 true
llen > -1 true
test.size() > 0 true
test.length() > 0 true
test.size() > -1 false
test.length() > -1 false
提醒自己:不要将string类型的size()和length()方法的返回值直接用来比较,可能会产生预计之外的情况
相关文章推荐
- C++二目运算符重载
- C++基本内置类型
- 重大发现: windows下C++ UI库 UI神器-SOUI(转载)
- leetcode_189_Rotate Array(easy)(C++)
- 使用C++实现工厂模式
- iOS OC语言: Block底层实现原理
- java的引用和c++的指针有什么区别
- C语言ASM汇编内嵌语法【转】
- C++标准库之stack(各函数及其使用全)
- C++的深拷贝与浅拷贝
- C、C++等语言常见符号作用总结
- 公司技术管理角度看C++游戏程序员发展
- C语言#自动生成四则运算的编程
- 通过模板的特化实现 简单的类型萃取 实现memcppy时候对于特殊类型如string类的拷贝。
- java与c++程序在编译和运行上有什么区别
- 【C++】《C++标准程序库》小结第六章(容器)
- C语言学习笔记
- 线程池原理及创建(C++实现)
- C++标准库之vector(各函数及其使用全)
- 重新学习《C++Primer5》第15章-面向对象程序设计