非字母字符上的 C++ 拆分字符串
c++ splitting string on non alphabetic characters
我正在逐行读取文件,我想拆分非字母字符,如果可能的话,同时删除所有非字母字符,这样我就不必稍后再做。
我想使用 isalpha
,但无法弄清楚如何将其与 str.find() 或类似函数一起使用,因为这些函数通常将单个分隔符作为字符串。
while(getline(fileToOpen,str))
{
unsigned int pos= 0;
string token;
//transform(str.begin(),str.end(),str.begin(),::tolower);
while (pos = str.find_first_not_of("abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM"))
{
token = str.substr(0, pos);
//transform(str.begin(),str.end(),str.begin(),::tolower);
Node<t>* ptr=search(token,root);
if (ptr!=NULL)
{
ptr->count++;
cout<<token<<" already in tree.Count "<<ptr->count<<"n";
}
else
{
insert(token,root);
cout<<token<<" added to tree.n";
}
ptr=NULL;
str.erase(0, pos);
}
}
我的最新尝试不起作用...我能找到的所有例子都是基于str.find("single delimiter")
这对我没有好处。
找到了使用isalpha
的方法
template<typename t>
void Tree<t>::readFromFile(string filename)
{
string str;
ifstream fileToOpen(filename.c_str());
if (fileToOpen.is_open())
{
while(getline(fileToOpen,str))
{
unsigned int pos= 0;
string token;
//transform(str.begin(),str.end(),str.begin(),::tolower);
while (pos = find_if(str.begin(),str.end(),aZCheck)!=str.end()!=string::npos)
{
token = str.substr(0, pos);
transform(token.begin(),token.end(),token.begin(),::tolower);
Node<t>* ptr=search(token,root);
if (ptr!=NULL)
{
ptr->count++;
// cout<<token<<" already in tree.Count "<<ptr->count<<"n";
}
else
{
insert(token,root);
cout<<token<<" added to tree.n";
}
ptr=NULL;
str.erase(0, pos);
}
}
fileToOpen.close();
}
else
cout<<"Unable to open file!n";
}
template<typename t>
inline bool Tree<t>::aZCheck(char c)
{
return !isalpha(c);
}
但是问题仍然存在,字符串被拆分为单个字符而不是单词,并且 isalpha 认为空格是否有效?
#include <algorithm>
#include <cctype>
...
template<typename t>
void Tree<t>::readFromFile(std::string filename)
{
std::string str;
std::ifstream fileToOpen(filename.c_str());
if (fileToOpen.is_open())
{
for (std::string::iterator pos, prev; std::getline(fileToOpen, str); )
{
for (pos = std::find_if(str.begin(), str.end(), isalpha); pos != str.end();
pos = std::find_if(prev, str.end(), isalpha))
{
prev = std::find_if_not(pos, str.end(), isalpha);
std::string token(pos, prev);
std::transform(token.begin(), token.end(), token.begin(), ::tolower);
Node<t>* ptr = search(token, root);
if (ptr != NULL)
{
ptr->count++;
// cout<< token << " already in tree.Count "<<ptr->count<<"n";
}
else
{
insert(token, root);
cout << token << " added to tree.n";
}
}
}
fileToOpen.close();
}
else
cout<<"Unable to open file!n";
}
在线演示
另外,既然你说你想节省时间,如果你的插入函数做一些额外的事情,这将有利于你,即在树中找不到值,如果它在树中找不到,并将位置的计数器设置为 1。如果值在树中,只需递增计数器即可。这将使您免于进行 2 次迭代,因为您的树可能不平衡
试试这个测试用例。两个问题。
1 - 当在截断(或开始
)后的字符串开头找到分隔符时,Pos 为 0这导致它突破了时间。请改用npos
作为条件检查。
2 - 擦除时必须将位置推进到分隔符之外,否则
它一遍又一遍地找到同一个。
int pos= 0;
string token;
string str = "Thisis(asdfasdfasdf)and!this)))";
while ((pos=str.find_first_not_of("abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM"))!= string::npos )
{
if ( pos != 0 )
{
// Found a token
token = str.substr(0, pos);
cout << "Found: " << token << endl;
}
else
{
// Found another delimiter
// Just move on to next one
}
str.erase(0, pos+1); // Always remove pos+1 to get rid of delimiter
}
// Cover the last (or only) token
if ( str.length() > 0 )
{
token = str;
cout << "Found: " << token << endl;
}
输出>>
Found: Thisis
Found: asdfasdfasdf
Found: and
Found: this
Press any key to continue . . .
相关文章:
- C++将向量的向量拆分为向量的N个子向量
- 如何拆分文件中.txt字母并使用c ++使用数组进行扑克?
- OpenCV 4.1.2 - 从网络摄像头获取帧并将其拆分
- 使用 C++ 将命令行参数拆分为参数/向量
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 如何在C++中将数字拆分为数字
- 在线程之间拆分任务总是值得的吗?
- 将字符串拆分为标记,并将标记拆分为两个单独的数组
- 在 c++ 中拆分类和标头中的继承,错误
- 在矢量内拆分 deques
- 拆分重叠段
- 我还可以添加什么来按空格或空格正确拆分C++字符串?
- 通过空行提升拆分字符串
- 给定一个大小为 N 的数组 S,检查是否可以将序列拆分为两个序列
- 如何按多个括号类型拆分字符串,但仍将括号保留在C++?
- 将 Boost.Spirit.X3 解析器拆分为多个 TU
- 将字符串拆分为等长 c++ 的部分
- 将执行循环拆分为多个线程 (1-N-1-N-1..)
- 使用范围拆分string_view
- 将 std::大小为 m 的向量拆分为大小为 n 的向量