C++ 从字符指针(C+;+;)获取迭代器

C++ 从字符指针(C+;+;)获取迭代器,c++,pointers,iterator,c++-standard-library,stl-algorithm,C++,Pointers,Iterator,C++ Standard Library,Stl Algorithm,我正在挑战自己编写一个回文测试程序,只使用SL算法、迭代器等。我还想编写程序来处理原始字符串。下面,我在copy\u if算法中使用原始指针pal,但是,我如何定义一个迭代器到这里,即使用类似begin(pal)和end(pal+size) #包括 #包括 #包括 使用名称空间std; bool isPalindrome(const char*pal){ 如果(!pal){return(false);} int size=strlen(pal); 字符串pal_raw; 原材料储备(尺寸); /

我正在挑战自己编写一个回文测试程序,只使用SL算法、迭代器等。我还想编写程序来处理原始字符串。下面,我在
copy\u if
算法中使用原始指针
pal
,但是,我如何定义一个迭代器到这里,即使用类似
begin(pal)
end(pal+size)

#包括
#包括
#包括
使用名称空间std;
bool isPalindrome(const char*pal){
如果(!pal){return(false);}
int size=strlen(pal);
字符串pal_raw;
原材料储备(尺寸);
//仅将字母字符(无空格、标点符号等)复制到pal_raw中
复制if(pal,pal+大小,背面插入器(pal\U raw),
[](字符项){返回isalpha(项);}
);
//测试是否为回文,忽略大写
bool same=相等(开始(pal_raw)、结束(pal_raw)、rbegin(pal_raw)、rend(pal_raw),
[](char item1,char item2){返回tolower(item1)=tolower(item2);}
);
返回相同的值;
}
int main(){
“稻草?不,太愚蠢了。我把煤烟涂在疣上。”;
bool same=isPalindrome(pal);
返回0;
}

额外的问题:是否可以通过从
equal()
中增加迭代器“in-place”来消除
copy_if()
的需要,即当
时!IsAlgor(item)< /C> > 

< P>迭代器实现指针的概念,当涉及C++库算法时。而且,正如你发现的,采用迭代器的C++库算法完全可以接受指针。这是相同的概念

当您已经有了指针开始时,就没有某种迭代器可以转换为指针

的确

std::begin(arr)

在平面阵列上定义。但是,你猜怎么着:它们返回指向数组开头和结尾的指针,而不是某种迭代器类

但是,您不能使用
std::begin()
std::end()
,因为在您需要使用它时,在函数内部,数组已经衰减为
字符*
std::begin()
std::end()
在实际数组上工作,而不是在衰减的指针上工作


如果坚持使用迭代器,则应将
std::string
传递给回文函数,而不是
char*
std::string
实现了一个
begin()
和一个
end()
方法,该方法返回一个
std::string::iterator
,您可以使用该方法。

如果我要这样做,并且我想使它适用于不同的类型,我会模板化该方法-例如:

template<class ITER_T>
bool isPalindrome(ITER_T begin, ITER_T end) {
   // check for palindrome generically between begin and end
}
不必要地检查每个字符两次,如果字符串是回文。。。效率不高。在这种情况下,使用“手动”循环可能会更好(不确定是否有std算法)


如果您想使begin(arr)/end(arr)在重载函数中工作,那么无论如何都需要对其进行模板化,如下所示:

template<size_t N>
bool isPalindrome(const char (&arr)[N]) {
...
模板
bool isPalindrome(常量字符(&arr)[N]){
...
但是,对于每个不同的数组大小,都会得到单独的实例化,因此最好使用迭代器进行模板化,并且对于任何字符数组大小,都只得到一个实例化


因此,为了回答“额外问题”,确实可以通过直接迭代数组来避免创建临时字符串(即动态内存分配):

template<typename ITER_T>
bool isPalindrome(ITER_T begin, ITER_T end) {
    while (begin < end) {
        if (tolower(*begin++) != tolower(*--end))
            return false;
    }
    return true;
}
bool same = isPalindrome(begin(pal), end(pal));
模板
bool isPalindrome(国际热核试验堆开始,国际热核试验堆结束){
while(开始<结束){
如果(tolower(*begin++)!=tolower(*--end))
返回false;
}
返回true;
}
bool same=isPalindrome(开始(pal),结束(pal));
要测试
isalpha
我留给您练习。提示:您可以在等式检查之前进行测试,并适当地增加/减少开始/结束(提示#2:我想到的解决方案将使用
继续
关键字)


同样,它可以处理与char不同的任意类型,然后可以使用type traits通过模板专门化抽象出isalpha/tolower调用。

为什么不使用
std::string
而不是char数组?@NathanOliver我已经为
std::string
编写了一个重载,我也希望能够也可以处理字符数组。指针已经是迭代器。字符数组/指针可以转换为字符串,因此您不需要为它指定特殊的函数。@GregBrown--我已经为std::string编写了一个重载,希望也能够处理字符数组。--那么这是一个单行函数--只需调用
std::string
version从带有转换字符数组的char*版本转换为
std::string
。它甚至可以与
wstring
vector
(当然假设后者包含ASCII字符)。只要在您的上下文中对元素类型调用
std::tolower
。是的,对
tolower()的调用
可以通过类型特征抽象出来,因此它将返回不支持“小写”转换的类型的标识(例如
vector
检查任意整数数组的回文)@ Axalas,我还没有涵盖类型特征,如果它有大写的话,它能防止回文返回true吗?而且,就像你说的那样,如果算法只检查每个字符一次,它会更有效。但是,由于它的后端)很难做,不一定在中间。(想象一个字符串,其中前半个字符是空格)-我知道我无论如何都会删除所有的空格,但我正在努力找到一个解决方案,避免任何额外的复制/删除,而是通过增加迭代器跳过非alpha字符
equal(begin(pal_raw), end(pal_raw), rbegin(pal_raw), rend(pal_raw), ...
template<size_t N>
bool isPalindrome(const char (&arr)[N]) {
...
template<typename ITER_T>
bool isPalindrome(ITER_T begin, ITER_T end) {
    while (begin < end) {
        if (tolower(*begin++) != tolower(*--end))
            return false;
    }
    return true;
}
bool same = isPalindrome(begin(pal), end(pal));