一个可被n整除的数的算法

首先,用户给出编号的数字( n ),例如5
程序必须找到可以分成n (5)的最小数字。
这个数字只能由数字0和9组成,而不能包含任何其他数字。

例如,如果用户给5编程。 可分为5的数字是:

5, 10, 15, 20, 25, 30, ..., 85, 90, 95, ... 

但这里的90是可以分为5的最小数字,也是数字(0,9)。 所以5的答案必须是90。
并且9的答案是9,因为它可以被分成9并且由数字(9)组成。

我的代码

 string a = txtNumber.Text; Int64 x = Convert.ToInt64(a); Int64 i ,j=1,y=x; bool t = false; for (i = x + 1; t == false; i++) { if (i % 9 == 0 && i % 10 == 0 && i % x == 0) { j = i; for (; (i /= 10) != 0; ) { i /= 10; if (i == 0) t = true; continue; } } } lblAnswer.Text = Convert.ToString(j); 

如果你很乐意去纯粹的function,那么这是有效的:

 Func> generate = () => { Func> extend = x => new [] { x * 10, x * 10 + 9 }; Func, IEnumerable> generate2 = null; generate2 = ns => { var clean = ns.Where(n => n > 0).ToArray(); return clean.Any() ? clean.Concat(generate2(clean.SelectMany(extend))) : Enumerable.Empty(); }; return generate2(new[] { 9L, }); }; Func f = n => generate() .Where(x => x % n == 0L) .Cast() .FirstOrDefault(); 

因此,不是迭代所有可能的值并测试09和可分性,这只是生成09数字,然后只测试可见性。 这种方式要快得多。

我可以这样称呼它:

 var result = f(5L); // 90L result = f(23L); //990909L result = f(123L); //99999L result = f(12321L); //90900999009L result = f(123212L); //99909990090000900L result = f(117238L); //990990990099990990L result = f(1172438L); //null == No answer 

这些结果非常快。 f(117238L)在138ms内在计算机上返回结果。

你可以这样试试:

 string a = txtNumber.Text; Int64 x = Convert.ToInt64(a); int counter; for (counter = 1; !isValid(x * counter); counter++) { } lblAnswer.Text = Convert.ToString(counter*x); 

上面的代码通过逐步搜索x多个来工作,直到满足条件的result :“ 仅由0和或9位组成 ”。 通过仅搜索x多个,保证可被x整除。 所以其余的是检查结果候选者的有效性,在这种情况下使用以下isValid()函数:

 private static bool isValid(int number) { var lastDigit = number%10; //last digit is invalid, return false if (lastDigit != 0 & lastDigit != 9) return false; //last digit is valid, but there is other digit(s) if(number/10 >= 1) { //check validity of digit(s) before the last return isValid(number/10); } //last digit is valid, and there is no other digit. return true return true; } 

关于上面代码片段中的奇怪的空for循环,它只是语法糖,使代码更短。 它等于跟随while循环:

 counter = 1; while(!isValid(input*counter)) { counter++; } 

使用这个简单的代码

 int inputNumber = 5/*Or every other number, you can get this number from input.*/; int result=1; for (int i = 1; !IsOk(result,inputNumber); i++) { result = i*inputNumber; } Print(result); 

IsOk方法在这里:

 bool IsOk(int result, int inputNumber) { if(result%inputNumber!=0) return false; if(result.ToString().Replace("9",string.Empty).Replace("0",string.Empty).Length!=0) return false; return true; } 

我的第一个解决方案性能非常差,因为将数字转换为字符串并查找字符’9’和’0’。

新解决方案:

我的新解决方案具有非常好的性能,并且是使用广度优先搜索(BFS)以来的技术方法。

该解决方案的算法:

对于每个输入数字,测试9,如果是答案打印,否则将2个子编号(90和99)添加到队列,并继续直到找到答案。

 int inputNumber = 5;/*Or every other number, you can get this number from input.*/ long result; var q = new Queue(); q.Enqueue(9); while (true) { result = q.Dequeue(); if (result%inputNumber == 0) { Print(result); break; } q.Enqueue(result*10); q.Enqueue(result*10 + 9); } 

数字创建的痕迹:

9

90,99

900909990999

9000,9009,9090,9099,9900,9909,9990,9999

。 。 。

我为控制台编写了这个代码,并且我使用了goto命令,但它不是首选,但我不能只用于编写它。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace main { class Program { static void Main(string[] args) { Console.WriteLine("Enter your number"); Int64 x = Convert.ToInt64(Console.ReadLine()); Int64 y, j, i, k, z = x; x = x + 5; loop: x++; for (i = 0, y = x; y != 0; i++) y /= 10; for (j = x, k = i; k != 0; j /= 10, k--) { if (j % 10 != 9) if (j % 10 != 0) goto loop; } if (x % z != 0) goto loop; Console.WriteLine("answer:{0}",x); Console.ReadKey(); } } }