前篇:
2.回文串问题
这是个很经典的问题,解法也不止一种。最直接的就是直接利用字符串特性来解决。
思路就是将字符串和其长度作为参数,然后双指针遍历查看是否对应的元素是否相等。进行循环的条件应该是左指针小于小指针。
答案:
int palindrome(char* str, int length) {
int left = 0;
int right = length - 1;
while (left < right)
{
if (*(str + left) != *(str + right)) {
return 0;
}
else {
left++;
right--;
}
return 1;
}
}
验证:
#define _CRT_SECURE_NO_WARNINGS l
#include <stdio.h>
#include <string.h>
int palindrome(char* str, int length) {
int left = 0;
int right = length - 1;
while (left < right)
{
if (*(str + left) != *(str + right)) {
return 0;
}
else {
left++;
right--;
}
return 1;
}
}
int main() {
char str[1024] = { 0 };
printf("输入字符串\n");
scanf("%s", str);
int length = strlen(str);
int num = palindrome(str, length);
printf("%s是否是回文串\n%s", str, num == 0 ? "否" : "是");
}
执行结果:
是回文串的情况
不是回文串的情况
3.返回栈中结点个数
栈顶指针一直指向栈顶,也就是栈中目前最后一个元素,顺序栈的底层其实就是一个数组,那么这个栈顶其实就跟索引一样。它的值加1就是栈中的所有结点个数。
//返回栈中的结点个数
int StackSize(SeqStack* s) {
printf("栈中结点个数为");
//栈空
if (isEmpty(s))
{
return 0;
}
int a = s->top ;
a++;
return a;
}
验证:
//返回栈中的结点个数
int StackSize(SeqStack* s) {
printf("栈中结点个数为");
//栈空
if (isEmpty(s))
{
return 0;
}
int a = s->top ;
a++;
return a;
}
int main() {
SeqStack* s= InitStack();
printf("入栈前判断栈是否为空\n");
int verdict = isEmpty(s);
printf("%s为空\n",verdict == 0 ? "是" : "否");
printf("进行入栈\n");
for (int i = 0; i < MAXSIZE; i++)
{
printf("请输入值\n");
int a;
scanf_s("%d",&a);
Push(s, a);
}
printf("添加元素后的栈\n");
showstack(s);
printf("\n入栈后判断栈是否为空\n");
int vern = isEmpty(s);
printf("%s为空\n", vern == 1 ? "是" : "否");
printf("进行出栈\n");
ElemType num= PoP(s);
printf("%d\n", num);
printf("删除元素后的栈\n");
showstack(s);
int a= StackSize(s);
printf("栈中结点个数为%d",a);
}
执行结果:
4.将十进制数转换为二进制数
规规矩矩地进行除以2操作,取余就是对应二进制数位的值,除以2的商为下一次循环二进制位的值的确定做准备,直到除到商成0为止。
代码:
#define N 100
void transform(int num) {
//创建一个数组记录二进制数
int a[N];
//相当于数组的指针
int i = 0;
if (num==0)
{
printf("0");
}
printf("%d对应的二进制数是\n", num);
while (num>0)
{
//二进制数只有0和1,奇数对2取余就是1,偶数对2取余就是0
a[i] = num % 2;
i++;
//num除2进行下一个二进制位的取值
num = num / 2;
}
//因为i一直指向待插入的位置,所以遍历时需要先进行减1
for ( i --; i >=0; i--)
{
printf("%d", a[i]);
}
}
验证:
#include <stdio.h>
#define N 100
void transform(int num) {
//创建一个数组记录二进制数
int a[N];
//相当于数组的指针
int i = 0;
if (num==0)
{
printf("0");
}
printf("%d对应的二进制数是\n", num);
while (num>0)
{
//二进制数只有0和1,奇数对2取余就是1,偶数对2取余就是0
a[i] = num % 2;
i++;
//num除2进行下一个二进制位的取值
num = num / 2;
}
//因为i一直指向待插入的位置,所以遍历时需要先进行减1
for ( i --; i >=0; i--)
{
printf("%d", a[i]);
}
}
int main() {
int num;
printf("请输入一个十进制数\n");
scanf_s("%d",&num);
transform(num);
}
5.有效括号
利用栈的特点,将左括号全部压进栈,遇到右括号时弹出栈顶元素,弹出前先进行判空操作,如果为空直接返回0,如果不为空再进行后续操作:如果匹配就继续进行循环,如果不匹配就直接返回0。循环完成后仍然要进行一次判空操作,不为空说明未匹配完,直接返回0。
代码:
int isVaild(SeqStack *s,char a[],int m) {
for (int i = 0; i < m; i++)
{
char res = a[i];
//遇到左括号就将其入栈
if (res == '{' || res == '[' || res == '(') {
Push(s, res);
}
//遇到右括号就进行弹出,在弹出前先要检查栈是否为空
else if (res == '}' || res == ']' || res == ')')
{
if (s->top == -1)
{
return 0;
}
char bra = PoP(s);
//匹配情况有三种,当有一种情况符合时就直接进行下次循环,否则返回0
if ((res == '}' && bra == '{') || (res == ']' && bra == '[') || (res == ')' && bra == '('))
{
continue;
}
else
{
return 0;
}
}
}
//循环完后检查是否栈为空,如果不为空就证明括号没匹配完,返回0
if (s->top!=-1)
{
return 0;
}
return 1;
}
验证:
//有效括号
int isVaild(SeqStack *s,char a[],int m) {
for (int i = 0; i < m; i++)
{
char res = a[i];
//遇到左括号就将其入栈
if (res == '{' || res == '[' || res == '(') {
Push(s, res);
}
//遇到右括号就进行弹出,在弹出前先要检查栈是否为空
else if (res == '}' || res == ']' || res == ')')
{
if (s->top == -1)
{
return 0;
}
char bra = PoP(s);
//匹配情况有三种,当有一种情况符合时就直接进行下次循环,否则返回0
if ((res == '}' && bra == '{') || (res == ']' && bra == '[') || (res == ')' && bra == '('))
{
continue;
}
else
{
return 0;
}
}
}
//循环完后检查是否栈为空,如果不为空就证明括号没匹配完,返回0
if (s->top!=-1)
{
return 0;
}
return 1;
}
int main() {
SeqStack* s = InitStack();
char a[MAXSIZE] = { '{','(','[',']','[',']',')','}'};
int b=isVaild(s, a,MAXSIZE);
printf("是否为有效括号\n");
printf("%s", b == 1 ? "是" : "否");
}
执行结果: