C++分割函数
这是我自己写的一个分割 string 类型的函数,现在在编译期不会出现问题,但是运行时会出问题,请问是什么原因,该怎么改{:10_254:}vector<string> split(string x, char fenge = ' ') {vector<string> ans;
for(int i=0; i<x.length(); ++i) {
/*cout << "i:" << i << endl;
cout << "ans: ";
for(int j=0; j<ans.size(); ++j) {
cout << ans << " ";
}
cout << endl;
*/
if(i == 0 || char(x) == fenge) {
ans.push_back(string());
if(ans.size() > 1 && ans == string()) {
ans.erase(ans.begin() + ans.size()-2);
}
}
else {
if(('a' <= x <= 'z' || 'A' <= x <= 'Z')) {
int s = ans.size()-1;
ans.insert(s, (const char *)x);
// cout << "ans:" << ans << endl;
}
}
}
return ans;
} 编译器首先很不满意
warning: cast to 'const char *' from smaller integer type 'std::basic_string<char>::value_type'
(aka 'char') [-Wint-to-pointer-cast]
ans.insert(s, (const char *)x);
^~~~~~~~~~~~~~~~~~
warning: comparison of integers of different signs: 'int' and 'std::basic_string<char>::size_type'
(aka 'unsigned long long') [-Wsign-compare]
for(int i=0; i<x.length(); ++i) {
~^~~~~~~~~~~
warning: result of comparison of constant 90 with expression of type 'bool' is always true
[-Wtautological-constant-out-of-range-compare]
if(('a' <= x <= 'z' || 'A' <= x <= 'Z')) {
~~~~~~~~~~~ ^~~~
warning: result of comparison of constant 122 with expression of type 'bool' is always true
[-Wtautological-constant-out-of-range-compare]
if(('a' <= x <= 'z' || 'A' <= x <= 'Z')) {
~~~~~~~~~~~ ^~~~
4 warnings generated.
然后我总觉得自己不是在读 C++ 代码而是一种别的语言,感觉很陌生,看不懂思路 写一写注释,说一说这个代码的实现思路
dolly_yos2 发表于 2023-2-16 21:03
编译器首先很不满意
然后我总觉得自己不是在读 C++ 代码而是一种别的语言,感觉很陌生,看不懂思路
为什么我的Dev-c++只有一个Warning{:10_282:} 本帖最后由 tommyyu 于 2023-2-16 21:46 编辑
人造人 发表于 2023-2-16 21:29
写一写注释,说一说这个代码的实现思路
vector<string> split(string x, char fenge = ' ') {
vector<string> ans;
for(int i=0; i<(int)x.length(); ++i) {
/*cout << "i:" << i << endl;
cout << "ans: ";
for(int j=0; j<ans.size(); ++j) {
cout << ans << " ";
}
cout << endl;
*/
if(x.c_str() == fenge) { //如果遇到要分割的字符,则在返回的列表中增加一个空字符串
if(i == 0 || char(x) != fenge)
ans.push_back(string());
}
else { //如果不是要分割的字符
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { // 如果是字母
int s = ans.size()-1; //添加到返回的列表中的最后一个字符串中
ans.insert(s, (const char *)x.c_str());
// cout << "ans:" << ans << endl;
}
}
}
return ans;
} dolly_yos2 发表于 2023-2-16 21:03
编译器首先很不满意
然后我总觉得自己不是在读 C++ 代码而是一种别的语言,感觉很陌生,看不懂思路
又改了一下vector<string> split(string x, char fenge = ' ') {
vector<string> ans;
for(int i=0; i<(int)x.length(); ++i) {
/*cout << "i:" << i << endl;
cout << "ans: ";
for(int j=0; j<ans.size(); ++j) {
cout << ans << " ";
}
cout << endl;
*/
if(x.c_str() == fenge) { //如果遇到要分割的字符,则在返回的列表中增加一个空字符串
if(i == 0 || char(x) != fenge)
ans.push_back(string());
}
else { //如果不是要分割的字符
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { // 如果是字母
int s = ans.size()-1; //添加到返回的列表中的最后一个字符串中
ans.insert(s, (const char *)x.c_str());
// cout << "ans:" << ans << endl;
}
}
}
return ans;
} tommyyu 发表于 2023-2-16 21:45
又改了一下
这个 insert 就极为别扭,里面的类型转换确定没问题吗?
看看 std::string::push_back 能不能用 tommyyu 发表于 2023-2-16 21:44
我也看不懂你在做什么
说一说这个代码的实现思路
dolly_yos2 发表于 2023-2-16 21:54
这个 insert 就极为别扭,里面的类型转换确定没问题吗?
看看 std::string::push_back 能不能用
vector<string> split(string x, char fenge = ' ') {
vector<string> ans;
for(int i=0; i<(int)x.length(); ++i) {
/*cout << "i:" << i << endl;
cout << "ans: ";
for(int j=0; j<ans.size(); ++j) {
cout << ans << " ";
}
cout << endl;
*/
if(x.c_str() == fenge) { //如果遇到要分割的字符,则在返回的列表中增加一个空字符串
if(i == 0 || char(x) != fenge)
ans.push_back(string());
}
else { //如果不是要分割的字符
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { // 如果是字母
int s = ans.size()-1; //添加到返回的列表中的最后一个字符串中
ans.push_back(x.c_str());
// cout << "ans:" << ans << endl;
}
}
}
return ans;
}
现在运行完的结果还是
--------------------------------
Process exited after 3.907 seconds with return value 3221225477
请按任意键继续. . . 人造人 发表于 2023-2-16 21:56
我也看不懂你在做什么
说一说这个代码的实现思路
遍历字符串中的每一个字符
判断当前字符是不是分隔符
如果是,添加一个新的字符串,但是如果自己的上一个字符也是分隔符的话,就不添加新字符串
如果不是,
如果是一个字母的话,就在列表中的最后一个字符串的最后加入这个字符。
如果不是字母,就不进行操作。 tommyyu 发表于 2023-2-16 22:00
遍历字符串中的每一个字符
判断当前字符是不是分隔符
如果是,添加一个新的字符串,但是如果自己 ...
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> split(const std::string &x, char fenge = ' ') {
std::vector<std::string> ans;
//for(int i = 0; i < (int)x.length(); ++i) {
for(size_t i = 0; i < x.length(); ++i) {
if(x.c_str() == fenge) { // 如果遇到要分割的字符,则在返回的列表中增加一个空字符串
if(i == 0 || char(x) != fenge) ans.push_back(std::string());
} else { // 如果不是要分割的字符
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { // 如果是字母
int s = ans.size() - 1; // 添加到返回的列表中的最后一个字符串中
ans.insert(s, (const char *)x.c_str()); // 这是什么?
}
}
}
return ans;
}
std::ostream &operator<<(std::ostream &os, const std::vector<std::string> &v) {
bool flag = false;
for(const auto &i: v) {
if(flag)
os << std::endl;
flag = true;
os << i;
}
return os;
}
int main() {
{
std::vector<std::string> v = split("12345", '.');
std::cout << v << std::endl;
}
std::cout << "**************************" << std::endl;
std::cout << split(".12345", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("12.345", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("12345.", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split(".1.23.45.", '.') << std::endl;
return 0;
}
人造人 发表于 2023-2-16 22:01
将字符加入最后一个字符串中 tommyyu 发表于 2023-2-16 22:09
将字符加入最后一个字符串中
你这个思路太复杂了
sh-5.1$ cat main.cpp
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> split(const std::string &x, char fenge = ' ') {
//std::vector<std::string> ans;
std::vector<std::string> ans(1); // 如果没有分隔符呢?
for(size_t i = 0; i < x.length(); ++i) {
//if(x.c_str() == fenge) {
if(x == fenge) {
//if(i == 0 || char(x) != fenge) ans.push_back(std::string()); // x 的类型是什么?
if(i == 0 || x != fenge) ans.push_back(std::string());
} else {
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { // 如果是字母
//int s = ans.size() - 1; // 添加到返回的列表中的最后一个字符串中
size_t s = ans.size() - 1; // 添加到返回的列表中的最后一个字符串中
//ans.insert(s, (const char *)x.c_str()); // 这是什么?
ans.push_back(x); // 是吧?
}
}
}
return ans;
}
std::ostream &operator<<(std::ostream &os, const std::vector<std::string> &v) {
bool flag = false;
for(const auto &i: v) {
if(flag)
os << std::endl;
flag = true;
os << i;
}
return os;
}
int main() {
std::cout << "**************************" << std::endl;
std::cout << split("abcdefg", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split(".abcdefg", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("abcdefg.", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split(".abcdefg.", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("ab.cde.fg", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("..ab..cde..fg..", '.') << std::endl;
return 0;
}
sh-5.1$ ./main
**************************
abcdefg
**************************
abcdefg
**************************
abcdefg
**************************
abcdefg
**************************
ab
cde
fg
**************************
ab
cde
fg
sh-5.1$
我感觉还是我这个思路清晰
你那个太多的if else组合,要做到没有遗漏,没有重复,这并不容易
像你的那个if else就没有考虑到没有分隔符的情况
太多的if else就很容易出问题,因为那么多的条件组合起来,你很难考虑到所有情况,很容易遗漏一些情况,就像没有分隔符的情况,你就没有考虑到
所以还是尽量避免太多的if else组合
sh-5.1$ cat main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
std::vector<std::string> split(const std::string &str, char sep) {
std::vector<std::string> result;
std::string::const_iterator b = str.begin();
while(1) {
std::string::const_iterator e = std::find(b, str.end(), sep);
result.push_back(std::string(b, e));
if(e == str.end()) break;
b = e + 1;
}
return result;
}
std::ostream &operator<<(std::ostream &os, const std::vector<std::string> &v) {
bool flag = false;
for(const auto &i: v) {
if(flag) os << std::endl;
flag = true;
os << i;
}
return os;
}
int main() {
{
std::vector<std::string> v = split("12345", '.');
std::cout << v << std::endl;
}
std::cout << "**************************" << std::endl;
std::cout << split(".12345", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("12.345", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("12345.", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split(".1.23.45.", '.') << std::endl;
return 0;
}
sh-5.1$ ./main
12345
**************************
12345
**************************
12
345
**************************
12345
**************************
1
23
45
sh-5.1$
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
string SPLIT(string str, char c, int i = 1) {
vector <string> results;
istringstream temp(str);
string token;
while (getline(temp, token, c)) { results.push_back(token); }
return results;
}
int main(void) {
cout << SPLIT("haha/fafa/dada/rara", '/', 2) << endl;
return 0;
}fafa #include <iostream>
#include <string>
#include <vector>
std::vector<std::string> split(const std::string &x, char fenge = ' ') {
//std::vector<std::string> ans;
std::vector<std::string> ans(1); // 不对,不是没有分隔符的情况,是第一个字符不是分隔符的情况
// 都说了,太多的if else组合,很难保证没有遗漏掉一些情况
// 你这个思路太复杂了
// 到目前为止,我依然无法保证没有漏掉一些情况
// 除非我把所有能够想到的可能全部枚举出来,然后一个一个去试,看看是不是符合要求
// 这个工作量可不小,我无法在大脑中直接完成这件事
// 而我的那个代码,我就可以在大脑中直接跑出结果
// 我用大脑跑了一遍程序,没有问题,然后又写代码,让计算机去跑一些边界值,然后也没发现问题
//std::vector<std::string> ans(1); // 如果没有分隔符呢?
for(size_t i = 0; i < x.length(); ++i) {
//if(x.c_str() == fenge) {
if(x == fenge) {
//if(i == 0 || char(x) != fenge) ans.push_back(std::string()); // x 的类型是什么?
if(i == 0 || x != fenge) ans.push_back(std::string());
} else {
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { // 如果是字母
//int s = ans.size() - 1; // 添加到返回的列表中的最后一个字符串中
size_t s = ans.size() - 1; // 添加到返回的列表中的最后一个字符串中
//ans.insert(s, (const char *)x.c_str()); // 这是什么?
ans.push_back(x); // 是吧?
}
}
}
return ans;
}
std::ostream &operator<<(std::ostream &os, const std::vector<std::string> &v) {
bool flag = false;
for(const auto &i: v) {
if(flag)
os << std::endl;
flag = true;
os << i;
}
return os;
}
int main() {
std::cout << "**************************" << std::endl;
std::cout << split(".abcdefg", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("abcdefg.", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split(".abcdefg.", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("ab.cde.fg", '.') << std::endl;
std::cout << "**************************" << std::endl;
std::cout << split("..ab..cde..fg..", '.') << std::endl;
return 0;
}
没看懂。。。。。
vector<string> ans; //这是一个容器嵌套,ans内的每个值都是一个string
if(i == 0 || char(x) == fenge) { //这里是想写i == 0 || (char)(x) == fenge 么? 可能更好的写法是 i== 0 || x.at(i) == fenge
ans.push_back(string()); //放进去一个空串?
if(ans.size() > 1 && ans == string()) { //这行没看懂
ans.erase(ans.begin() + ans.size()-2);
}
}
没有测试,楼主自己再完善一下吧
vector<string> ans;
ans.push_back("");
for(int i = 0; i < x.size(); ++i){
if(x.at(i) == fenge){
if(x.at(i + 1) == fenge){ //丢掉连续的
continue;
}else{
ans.push_back("");
}
}else{
ans.append(1, x.at(i));
}
}
本帖最后由 jhq999 于 2023-2-17 16:45 编辑
//纯分割
#include <bits/stdc++.h>
using namespace std;
vector<string> split(string x, char fenge = ' ')
{
vector<string> ans;
int i=0,j=0;
while(x)
{
if(fenge==x)
{
if(i&&fenge!=x)
{
ans.push_back(x.substr(j,i-j));
}
j=i+1;
}
i+=1;
}
if(fenge!=x)
{
ans.push_back(x.substr(j,i-j));
}
return ans;
}
//只留字母
vector<string> split(string x, char fenge = ' ')
{
vector<string> ans;
int i=0,j=0;
string s="";
while(x)
{
if(fenge==x)
{
if(i&&fenge!=x)
{
ans.push_back(s);
s="";
}
j=i+1;
}
else if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z'))
{
s+=x.substr(i,1);
}
i+=1;
}
if(fenge!=x)
{
ans.push_back(s);
}
return ans;
} 人造人 发表于 2023-2-16 22:29
我感觉还是我这个思路清晰
你那个太多的if else组合,要做到没有遗漏,没有重复,这并不容易
像你的那个i ...
{:10_282:}看不懂 傻眼貓咪 发表于 2023-2-16 22:32
{:10_257:}看来还是要尽量使用c++的内置函数
页:
[1]