C#之用栈实现字母消除

这几天工作比较忙,今天整理下前两天完成的一个算法题。题目要求如下:

/牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?
输入
abbc
输出
ac
示例2
输入
abba
输出
0
示例3
输入
bbbbb
输出
b

补充:题目当然是不限制语言的,我工作中用到C#,所以我选择用C#。

思路1:用循环解决这个问题,这个是我最开始的思路。

1.首先是输入一长串字符串,把它传入char类型的一维数组(这里要注意的一点是不要直接使用静态一维数组,静态的是没有没办法进行删除元素操作的,我们传到动态数组里完成这个过程)。

2.然后满足条件的话从第二个值开始遍历,与第一个的值开始对比。如果满足条件就把两个值一起从数组里删除,然后再从新的数组里第二个值开始遍历,否则输出。

相信各位发现了我这里描述的时候产生的一个问题,就是遍历的次数过于多了,这样会导致数据多的时候输出超时,不是很建议这样做。但是像我这样新手学习的过程,循环比栈是要先接触的,所以可以先尝试这样看看,下面是我画的大致流程图。

Created with Raphaël 2.3.0 开始 满足遍历条件 开始遍历 和前面值相同 删除这两个元素,返回遍历初值 结束遍历,输出 继续遍历 yes no yes no
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApp7
{
    class DemoMain
    {
        static void Main(string[] args)
        {
            // 输入
            string input = Console.ReadLine();
            // 传入动态数组,并设置为字符char类型
            ArrayList arr = new ArrayList(input.ToCharArray());
            //从第二个开始遍历,第一个没有比对的对象
            int i = 1;
            while (i < arr.Count) {
                //当遍历到的元素与前一个相等时,我们给循环赋初值,重新遍历
                if (arr[i].ToString() == arr[i - 1].ToString())
                {
                    arr.RemoveAt(i);        // c#删除动态数组元素的方法
                    arr.RemoveAt(i - 1);
                    i = 1;
                }
                else {
                    i++;                    // 不等的时候递增
                }
            }
            if(arr.Count == 0)
            {
                Console.WriteLine(0);       // 当没有剩下的元素时输出0
            }
            else
            {
                foreach(char res in arr) Console.Write(res);    // 直接输出动态数组会输出类型,所以把它放进一个list输出
            } 
            Console.ReadKey();              //等待键盘操作
        }

    }
}

思路2:利用栈来解决,栈遵循后入先出原则

  1. 首先我们将第一个数放入栈中,然后第二个值与栈顶元素比对,如果一样就将栈顶元素出栈,不一样就入栈。
  2. 入栈后的最后一个元素会成为栈顶元素,继续与它的下一个元素比对。顺带一提,栈的优点就是读取速度快,所以这里不会出现超时问题。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoStack
{ 
    class DemoMain
    {
        static void Main(string[] args)
        {
                //Push(object obj)	向栈中添加元素,也称入栈
                //object Peek()   用于获取栈顶元素的值,但不移除栈顶元素的值
                //object Pop()    用于移除栈顶元素的值,并移除栈顶元素
                //Clear() 从 Stack 中移除所有的元素
                //Contains(object obj)    判断某个元素是否在 Stack 中
                //object[] ToArray()  复制 Stack 到一个新的数组中


                // 输入
                string input = Console.ReadLine();
                // 建栈
                Stack<char> st = new Stack<char>();
                //第一个元素入栈
                st.Push(input[0]);
                //ArrayList arr = new ArrayList(input);
                int i = 1;
                while (i < input.Length)
                {   
                	//从第二个元素开始遍历,满足条件就出栈
                    if (st.Count!=0 && st.Peek()== input[i])
                    {   
                        st.Pop();
                        i++;
                    }
                    else 
                    {
                        //不满足的话接下来的一个元素入栈,放在栈顶和它之后的元素比较
                        st.Push(input[i]);
                        i++; }
                	}

                if (st.Count == 0) 
                { 
                    Console.Write(0); 
                }

                else
                {
                    string res = "";
                    while (st.Count != 0)
                    {
                        res = st.Peek() + res;
                        st.Pop(); //每取一个就删除一个,否则会一直循环
                    }
                    Console.Write(res);
                }
                Console.ReadKey();
            }
        }
    }
}

感谢观看,各位有意向走C#这个方向的可以加入我新创的C#新手交流群,互帮互助,互相学习。学习群号781462455,或者扫码进入。在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值