在Linq处理临时计算

时间:2009-10-17 12:00:15

标签: c# linq-to-objects

解决面试问题时

问题 当它乘以2到9之间的整数时,需要以这种方式找到一个六位数字,当它的数字反转时给出原始的六位数字。

示例:

假设我乘以219978 * 4我得到879912,当反向879912时我会得到219978.

我用它解决了

for (long l = 100000; l < 999999; l++)
{
 var num = l.ToString();

for (int i = 3; i < 9; i++)
{
  var mul = l * i;
  string str = mul.ToString();
  char[] splitDigits = str.ToCharArray();
  string reversedDigit =
  new  string(splitDigits.Reverse().ToArray());

  if (reversedDigit.CompareTo(num) == 0)
    {
      Console.WriteLine("{0} * {1}= {2},
       when multiplied {3} ", num, i, mul,reversedDigit);

    }

 }
}

最初的任务是使用linq来解决它。我在处理临时计算方面有点混乱,例如

当我使用

   var = from l in Enumerable.Range(100000,999999)
         from i in Enumerable.Range(3,9)

在linq中处理像var num = l.ToString()等临时计算的方法是什么。在Linq中我很困惑我完成它。感谢帮助。

2 个答案:

答案 0 :(得分:5)

您想要let ...

    // NOTE: buggy; see below
    var qry =  from l in Enumerable.Range(100000, 999999)
               from i in Enumerable.Range(3, 9)
               let s = l.ToString()
               let t = (l * i).ToString()
               where s.Reverse().SequenceEqual(t)
               select new { l, i };

    var a = qry.First();
    Console.WriteLine("an answer...");
    Console.WriteLine("{0} x {1} = {2}", a.l, a.i, a.l * a.i);

    Console.WriteLine("all answers...");
    foreach (var row in qry)
    {
        Console.WriteLine("{0} x {1} = {2}", row.l, row.i, row.l * row.i);
    }

第一个答案(请注意,9的包含取自原始版本的代码,但可能需要使用Range(3,8)代替):

109989 x 9 = 989901

优化版本(和正确的范围):

    var qry =  from l in Enumerable.Range(100000, 999999 - 100000)
               let s = l.ToString()
               let sReversed = new string(s.Reverse().ToArray())
               let wanted = int.Parse(sReversed)
               from i in Enumerable.Range(3, 8 - 3) 
               where l * i == wanted
               select new { l, i };

这会减少创建的字符串数量,使用整数相等,并正确使用范围(Range的第二个参数是计数,而不是结尾)。

答案 1 :(得分:1)

这是另一个解决方案,它将问题语句与一些帮助方法相匹配(为了清晰起见)(可以移动到原始的linq查询中):

    private static IEnumerable<int> SixDigitNumbers = Enumerable.Range(100000, (999999 - 100000));
    private static IEnumerable<int> Multipliers = Enumerable.Range(2, 8);

    static void Main(string[] args)
    {

        var Solutions = from OriginalNumber in SixDigitNumbers
                              from Multiplier in Multipliers
                              let MultipliedNumber = (OriginalNumber * Multiplier)
                              where MultipliedNumber < 999999 && ResultIsNumericPalindrome(OriginalNumber, Multiplier)
                              select new { MultipliedNumber, OriginalNumber, Multiplier };


        var AllSolutions = Solutions.ToList();

    }

    private static string Reverse(string Source)
    {
        return new String(Source.Reverse().ToArray());
    }

    private static bool ResultIsNumericPalindrome(int Original, int Multiplier)
    {
        return (Original.ToString() == Reverse((Original * Multiplier).ToString()));
    }

以下是所有解决方案:

{MultipliedNumber = 989901,OriginalNumber = 109989,Multiplier = 9}
{MultipliedNumber = 879912,OriginalNumber = 219978,Multiplier = 4}

小心使用Enumerable.Range - 我看到有人回答这个问题,错误地排除了问题陈述中要求的两个号码。