数据结构--链表--判断一个字符串是否为回文串(单向链表,双向链表)
回文串为首尾对称的字符串:
如a,aba,abba等
单链表思路
1.将字符读入链表
2.找到链表中点
3.将链表从中点断开成2条,将后半条反转
4.比较两条链表是否相等(比较次数以少的为准(长度为奇数时))
双向链表思路
1.将字符读入链表
2.找到链表尾节点
3.从首尾依次向中间比较
(双向链表可以双向移动,代码上更简洁,见下面)
单链表C++代码实现
//
// Created by mingm on 2019/3/13.
//
#include <iostream>
#include <math.h>
using namespace std;
struct Node //节点
{char data;Node* next;Node():next(NULL){}Node(char &ch):data(ch),next(NULL){}~Node(){}
};
class SLinkedList //链表
{Node* p_head;
public:SLinkedList() //构造函数{p_head = new Node; //带头链表
// cout << "new 1" << endl;}~SLinkedList(){ erase(); } //析构函数void erase(){Node *del_tempNode, *tempNode;del_tempNode = p_head;while(del_tempNode != NULL) {tempNode = del_tempNode -> next;delete del_tempNode;
// cout << "delete 1" << endl;del_tempNode = tempNode;}}void set_head(Node* p){p_head = p;}Node* get_head(){return p_head;}size_t get_len() //求链表长度{size_t len = 0;Node* p = p_head;while(p){len++;p = p->next;}return len;}void delHeadSentinel() //删除链表表头哨兵{Node* del = p_head;p_head = p_head->next;delete del; //删除链表的表头哨兵
// cout << "delete head 1" << endl;}Node* reverse() //链表反转{if(p_head == NULL || p_head->next == NULL)return NULL;else{Node *prevNode, *nextNode, *tempNode;prevNode = p_head;nextNode = prevNode->next;prevNode->next = NULL;while(nextNode != NULL){tempNode = nextNode->next;nextNode->next = prevNode;prevNode = nextNode;nextNode = tempNode;}p_head = prevNode;return p_head;}}Node* findMiddle() //查找链表中点{size_t len = get_len();Node* tempNode = p_head;size_t n = ceil(double(len)/2);for(size_t i = 1; i < n; ++i){tempNode = tempNode->next;}return tempNode;}
};int main()
{while(true){cout << "-----------------------------------" << endl;char ch;cin.clear();cout << "enter a word, is it a palindrome ?" << endl;if((ch = cin.get()) && ch == '\n'){cout << "empty word !" << endl;continue;}SLinkedList charList, backHalfOfList; //链表(前半部分链表),后半部分链表Node* tempNode = charList.get_head();while(ch != '\n') //把单词存进链表charList{Node* newNode = new Node(ch);
// cout << "new insert 1" << endl;tempNode->next = newNode;tempNode = newNode;ch = cin.get();}charList.delHeadSentinel(); //链表表头删除backHalfOfList.delHeadSentinel(); //把空表头哨兵节点删除Node* endOfFrontList = charList.findMiddle(); //链表的中点是前一半的结束节点Node* backListHead = endOfFrontList->next; //中点的下一个节点是后半部分的开始endOfFrontList->next = NULL; //把前半部分链表断开backHalfOfList.set_head(backListHead); //把后半部分的链表表头地址设置好backHalfOfList.reverse(); //后半部分链表反转size_t n = backHalfOfList.get_len(); //求后半部分链表长度Node *frontList = charList.get_head(); //找到前半部分的开头Node *backList = backHalfOfList.get_head(); //后半部分的开头(反转后的)bool answer = false;if(backList == NULL) //如果后半部分为空,说明只有一个字符answer = true;else{for(size_t i = 0; i < n; ++i) //比较数据是否相同{if(frontList->data != backList->data){answer = false;break;}else{answer = true;frontList = frontList->next;backList = backList->next;}}}if(answer)cout << "the word is a palindrome." << endl;elsecout << "the word is not a palindrome." << endl;char conti;cout << "continue to check? (y/n)" << endl;cin >> conti;cin.get();if(conti == 'y' || conti == 'Y'){continue;}elsebreak;}return 0;
}
Valgrind检查结果
双向链表C++代码实现
//
// Created by mingm on 2019/3/16.
//
#include <iostream>
#include <math.h>
using namespace std;
struct Node //节点
{char data;Node *prev, *next;Node():prev(NULL),next(NULL){}Node(char &ch):data(ch),prev(NULL),next(NULL){}~Node(){}
};
class SLinkedList //链表
{Node* p_head;
public:SLinkedList() //构造函数{p_head = new Node; //带头链表
// cout << "new 1" << endl;}~SLinkedList(){ erase(); } //析构函数void erase(){Node *del_tempNode, *tempNode;del_tempNode = p_head;while(del_tempNode != NULL) {tempNode = del_tempNode -> next;delete del_tempNode;
// cout << "delete 1" << endl;del_tempNode = tempNode;}}void set_head(Node* p){p_head = p;}Node* get_head(){return p_head;}Node* get_tail() //求链表尾节点{Node* p = p_head;if(p_head == NULL)return NULL;while(p->next){p = p->next;}return p;}void delHeadSentinel() //删除链表表头哨兵{Node* del = p_head;p_head = p_head->next;p_head->prev = NULL;delete del; //删除链表的表头哨兵
// cout << "delete head 1" << endl;}
};int main()
{while(true){cout << "-----------------------------------" << endl;char ch;cin.clear();cout << "enter a word, is it a palindrome ?" << endl;if((ch = cin.get()) && ch == '\n'){cout << "empty word !" << endl;continue;}SLinkedList charList; //链表Node* tempNode = charList.get_head();while(ch != '\n') //把单词存进链表charList{Node* newNode = new Node(ch);
// cout << "new insert 1" << endl;tempNode->next = newNode; //前面节点后指针指向后面newNode->prev = tempNode; //后面节点前置指针指向前面tempNode = newNode;ch = cin.get();}charList.delHeadSentinel(); //链表空表头删除Node *front = charList.get_head(); //定义一个从头开始的指针Node *back = charList.get_tail(); //定义一个从尾部开始的指针bool answer = false;if(front == back) //说明只有一个字符answer = true;else{while(front != back) //比较数据是否相同{if(front->data != back->data){answer = false;break;}else{answer = true;front = front->next;back = back->prev;}}}if(answer)cout << "the word is a palindrome." << endl;elsecout << "the word is not a palindrome." << endl;char conti;cout << "continue to check? (y/n)" << endl;cin >> conti;cin.get();if(conti == 'y' || conti == 'Y'){continue;}elsebreak;}return 0;
}
Valgrind检查结果
数据结构--链表--判断一个字符串是否为回文串(单向链表,双向链表)相关推荐
- c语言判断回文字符串递归,用递归实现判断一个字符串是否为回文串
//用递归实现判断一个字符串是否为回文串 import java.util.Scanner; public class Palindrome { //判断是否为回文串 in型参数代表字符串起止位置 p ...
- c语言用递归法判断回文字符串,递归方式判断一个字符串是否为回文字符串
/* * 递归方式判断一个字符串是否为回文字符串 */ public class PartitionTest{ public static void main(String[] args) { Str ...
- 判断一个字符串是否为“回文”
编写一个程序,判断一个字符串是否为"回文"(顺读和倒读都一样的字符串称为"回文"),并分析算法的时间复杂度 #include <stdio.h> # ...
- c语言程序判断一个字符串是否是回文数,详解判断回文字符串和回文数算法的C语言代码!...
一.判断一个字符串是否为回文字符串 #include #include #include //包含strlen #define YES 1 #define NO 0 #define uchar un ...
- Php判断一个字符串是否回文,PHP:判断一个字符串是否为回文字符串
所谓回文字符串,兴许有很多人并不知晓是什么意思.其实呢,回文字符串就是从左往右看和从右往左看是一样的,就如同"CDDC"这样的例子.这么说,不知道大家明白没有.废话呢,也就不多说了 ...
- 回文指的是一个字符串从前面读和从后面读都一样,编写一个算法判断一个字符串是否为回文。
回文指的是一个字符串从前面读和从后面读都一样,编写一个算法判断一个字符串是否为回文. 要求: 1)采用链栈实现算法: 2)从键盘输入一个字符串,输出判断结果. 算法思路: 根据栈的后进先出的特点,编写 ...
- 判断一个字符串是否是回文
[问题描述] 编写一个程序,判断一个字符串是否为"回文"(顺读和倒读都一样的字符串称为"回文"). [输入形式] 长度小于100的任意字符串 [输出形式] 如果 ...
- 用C语言去判断一个字符串是否为回文字符串(简单明了)
C语言判断回文字符串呀 hello,小伙伴们.好久没写文章了,今天我们来写一下如何用C语言判断字符串是不是回文字符串呢. 大致思路:将字符串逆序赋给另一个字符串,然后比较这两个字符串是否相同.(其实也 ...
- 判断一个字符串是否为回文的递归算法
//编译器:GCC 4.2.1 运行环境:Redflag Linux 6.0 Desktop //如果在VC++下编译可能要加入string和algorithm两个头文件并修改函数返回值类型 #inc ...
最新文章
- Wcf 双工通信的应用
- 到底什么是极简主义?
- net如何判断浏览器的类别
- cocos2d-x调度器原理,mainloop的Update
- js如何保证iframe里的内容,显示在父窗口
- 1加6投屏_1加6投屏_6月的早餐,1杯牛奶加燕麦,营养健康又美味,饱腹感很强...
- 使用jmeter测试接口
- 前端实现PDF分页与Vue中的render函数
- 抖音JAVA工程师_字节跳动抖音社招后台开发工程师面经
- openvino踩坑记(ImportError: DLL load failed while importing ie_api)
- 实战演习(四)——网络流量系统分析简介
- 年均科研经费 4000 万,教授没有发论文压力,不必教课,这才是神仙科研生活!...
- 搭建风控系统道路上踩过的坑合集
- Unity3D-粒子光圈
- Java并发编程之(二)管程
- C/C++ 无法解析的外部符号解决方案
- OSX 软件选择之编辑器
- 在debian系统下安装R以及Rstudio的经历
- 服务器自动关闭远程打印服务,服务器远程打印机设置
- 【SharePoint】SharePoint 文档库中html文件打开后直接通过浏览器访问,而不是直接下载
热门文章
- 如何用css和HTML结合画熊,结合伪元素实现的纯CSS3高级图形绘制
- linux 编译查看链接库详情,Linux环境下的编译,链接与库的使用
- s5pv210——nandflash和inand的基础理论
- 【作品】超级玛丽射击版
- 12 哈希表相关类——Live555源码阅读(一)基本组件类
- xcode 4.2开发 ——navigation controller 添加按钮
- 博客园配置windows live writer,实现本地代码高亮
- 关于Python的应用发布技术
- ptmalloc,tcmalloc和jemalloc内存分配策略研究
- hadoop fs 基本命令