在c++链表中,使用递归还是迭代来分隔偶数和奇数长度的字符串更好?
Is it better to use recursion or iteration to separate the even and odd length strings in a C++ linked list?
早上好。在c++链表中使用递归或迭代来分离偶数和奇数长度的字符串更好吗?
更好意味着1)健壮性2)跨平台Windows/Linux/Unix可移植性3)最坏情况下运行时性能
cSinglyLinkedList* SeparateOddandEvenlLengthStrings(cSinglyLinkedList* list){
cSinglyLinkedList* Retval(NULL);
char* Temp(NULL);
if (list == NULL || list->Head == NULL){
return NULL;
}
if (list && list->Current && list->Current->Next == NULL){
return list;
}
if (list->Iterate()){
Temp = list->Current->String;
Retval = SeparateOddAndEvenLengthStrings(list);
if ((strlen(Temp) % 2) == 0){
Retval->Remove(Temp);
Retval->Add(Temp);
}
return Retval;
}
return NULL;
}
class cSinglyLinkedList {
private:
struct SinglyLinkedInfo{
SinglyLinkedInfo* Next;
char* String;
SinglyLinkedInfo(void){
Next = 0;
String= 0;
}
} Item;
SinglyLinkedInfo *Head, *Current;
int Count;
void ClearStrings(void);
public:
cSinglyLinkedList(void);
~cSinglyLinkedList(void);
bool Add(const char *string1);
void Remove(const char *string1);
bool RestartIterator(void);
bool Iterate(void);
int GetCount(void);
SinglyLinkedInfo* GetHead(void);
SinglyLinkedInfo* GetCurrent(void);
void Trace(const char *title_);
};
inline bool cSinglyLinkedList::RestartIterator(void) {
Current=Head;
return (Current!=0);
}
inline bool cSinglyLinkedList::Iterate(void) {
if (Current==0){
Current=Head;
} else if (Current){
Current = Current->Next;
}
return (Current!=0);
}
inline SinglyLinkedInfo *cSinglyLinkedList::GetHead(void) {
return Head;
}
inline SinglyLinkedInfo *cSinglyLinkedList::GetCurrent(void) {
return Current;
}
cSinglyLinkedList::cSinglyLinkedList(void) {
Head=Current=0;
Count=0;
}
cSinglyLinkedList::~cSinglyLinkedList(void) {
ClearStrings();
}
void cSinglyLinkedList::ClearStrings(void) {
SinglyLinkedInfo* nextCurrent;
Current=Head;
while (Current!=0) {
nextCurrent = Current->Next;
delete[] Current;
Current=nextCurrent;
}
Head=Current=0;
Count=0;
}
void cSinglyLinkedList::Remove(const char* string1_) {
SinglyLinkedInfo* Prev(NULL);
RestartIterator();
Current = Head;
while (Current!=0) {
if (strcmp(Current->String,string1_)==0){
if (Prev){
Prev->Next = Current->Next;
} else{
Head = Current->Next;
}
delete [] Current;
break;
}
Prev=Current;
Current=Current->Next;
}
RestartIterator();
Count -= 1;
}
bool cSinglyLinkedList::Add(const char *string1_){
SinglyLinkedInfo* newElement = (SinglyLinkedInfo*)new char[sizeof(SinglyLinkedInfo)];
memset(newElement, 'x0', sizeof(SinglyLinkedInfo));
newElement->String = new char[sizeof(char*)];
memcpy(newElement->String, &string1_, sizeof(char*));
newElement->String = (char*)string1_;
newElement->SinglyLinked = new cPCRE();
newElement->SinglyLinked->SetOptions(PCRE_CASELESS);
if (newElement->SinglyLinked->Compile(string1_) == 0){
return false;
}
if (Head==0) {
Head = newElement;
} else {
SinglyLinkedInfo* Temp(NULL);
Temp = Head;
while (Temp != 0 && Temp->Next != 0){
Temp = Temp->Next;
}
Temp->Next = newElement;
}
Count++;
return true;
}
void cSinglyLinkedList::Trace(const char *title_) {
int i=0;
if (title_!=0)
printf("%s:n",title_);
if (RestartIterator()) {
do {
printf(" %d: %sn",i++,GetString());
} while (Iterate());
}
}
尽管由于尾部调用优化,它最终可能无关紧要,但至少就c++而言,迭代方法处理链表更为惯用。与递归方法不同,迭代方法不会导致堆栈溢出,即使编译器不应用尾部调用优化。
不"有界"的递归[1]绝对是一件坏事。如果有人给你的函数输入莎士比亚全集(我指的是所有的书,而不是"莎士比亚全集",它大约有32个字符长),会发生什么?
无界递归的问题是,它会以一种你无法恢复的方式爆发,因为一旦堆栈被完全用完,任何人都无能为力,只能终止进程。你不能调用一个函数说"对不起,我的堆栈用完了",因为这会占用堆栈空间!
[1]或者你可以合理地说,这将是好的与给定数量的递归调用,例如一个合理平衡的二叉树可以在32个递归搜索40亿个条目的水平,所以如果您的数据库是不会超过几百万条目(还有防范病理情况下的所有节点都在一个链表的左边或者右边的树),那么你能说没关系。
根据我的经验,我可以说对于任何算法,迭代版本总是比递归版本快。递归版本也可能导致溢出,因为递归的长度是有限的。但是,递归实现的一个优点是,它们非常简单。
相关文章:
- C++ - 创建具有相同字符的特定大小的以 null 结尾的 c 样式字符串的更好方法
- 提取或(甚至更好)更改 char* 字符串的第一个符号
- MongoC ++驱动程序BSON构造:基于流与基于字符串解析.哪一个性能更好?
- 有没有更好的方法可以从静态和非静态函数返回相同的字符串文本
- 在 C++ 中执行此操作的视觉更好方法?标准::字符串
- 确保字符串只包含字母数字字符的更好方法
- 哪个是更好的字符串搜索算法?Boyer-Moore或Boyer Moore Horspool
- 有没有更好的方法来搜索文件中的字符串
- 什么表现更好 字符串::+= 或 sstream::<<
- 旧版 Win32 DLL 中的空终止字符串 C++ - 有没有更好的方法
- 有没有更好的方法从字符串创建目录?CPP,创建目录,字符串流,字符串
- 字符串到flywweights的字符串转换:更好的性能选项
- 将uint8的矢量转换为ascii十六进制字符串的更好方法
- 有没有更好(更有效)的方法来确定一个字符串是否可以由另一个字符串的字符组成
- 有没有比 char* 和循环更好的方法来计算字符串中的子字符串出现次数
- 什么更好:包括字符串类或使用字符数组?
- 字符串操作-需要更好的方式
- 如何将c++中的wchar字符串转换为更好支持的东西
- 通过hash_map<字符串 fnPtr>调用函数指针是否比C++中的多个 if/else if/else 语句更有效或更好?
- 什么时候使用常量字符串和常量字符串比使用常量字符串更好