首页 > 解决方案 > 如何在 C# 中构建一个将整数计算为 LIFO 集合的函数

问题描述

问题是:编写一个函数(AllExist),它接收一个非空堆栈stk(int)作为参数,如果堆栈中每个数字的所有第一个数字都显示为任何一个中的最后一个数字,它将返回true stk 的数量,否则返回 false。例如:对于stk(从上往下)122、251、565、12334、28、7,函数会返回true。1 、 2 、 5 和 7 出现在堆栈中任何数字的最后一位。

** clone 是一个函数,它返回与给定堆栈相同的堆栈。

我的建议:

public static bool AllExist(stack<int> stk)
{
  int x=0; int i; int z; bool bl; string str;
  stack <int> stk1=clone (stk);
  while (!stk1.IsEmpty())
  {
    i=stk1.Pop();
    while(i>=10)
    i/=10;
    x=x*10+i;
  }
 str=x.ToString();
 stack<int> stk2=Clone(stk);
 while(!stk2.IsEmpty())
 {
   z=stk2.Pop()%10;
   if (str.IndexOf(z.ToString())>-1)
     bl=true;
   bl=false;
 }
return bl;
}

** 这都是翻译,如有任何误解,请见谅。

谢谢你!

标签: c#stack

解决方案


开始时,始终将您要解决的问题分解为较小的问题并解决这些问题。如果你拆分得足够多,那么你真正要解决的问题实际上是一个很容易被验证为正确的衬里。

你需要什么?首先是一种提取整数最后一位数字的方法。好的,这很容易,任何数字的最后一位是除以的余数10

private static int ExtractLastDigit(this int i)
{
    return i % 10;
}

我们还需要一种提取第一位数字的方法。最简单的方法是缩小数字,以便我们正在寻找的数字是唯一剩下的数字。我们可以使用 Log10 做到这一点:

private static int ExtractFirstDigit(this int i)
{
    var scale = (int)Math.Log10(i);
    return (int)(i / Math.Pow(10, scale));
}

现在,有很多方法可以做到这一点。最容易理解的是建立两个集合;一个包含所有第一个数字,另一个包含所有最后一个数字,检查前者中的所有项目是否都存在于后者中。因为您将在后者中刻苦地搜索,所以如果输入集合足够大,将最后一位数字存储在搜索有效的集合中通常是一个好主意。该框架提供了这样的集合:HashSet<T>.

我将使用 linq,但使用经典循环构建集合相当简单。

var firstItems = inputStack.Select(i => i.ExtractFirstDigit());
var lastItems = new HashSet<int>(inputStack.Select(i => i.ExtractLastDigit()))

现在,使用逻辑运算符Alllinq 提供:

var validInput = firstItems.All(f => lastItems.Contains(f));

大致翻译为:

var validInput = true;

foreach (var first in firstItems)
{
    if (!lastItems.Contains(f))
    {
        validInput = false;
        break;
    }
}

你完成了。

有没有更有效的解决方案?当然可以,但你真的需要它们吗?如果答案是肯定的,请习惯于首先构建一个可行的解决方案,然后开始尝试使用可以衡量和测试的明确性能目标来优化它。如果您不这样做或者它已经达到了您的目标,那么您就有了一个易于理解和维护的有效解决方案。


推荐阅读