【问题标题】:An algorithm for a number divisible to n可被 n 整除的数的算法
【发布时间】:2014-03-01 07:30:49
【问题描述】:

首先,用户给出一个数字 (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);

【问题讨论】:

  • 我没有得到你的问题
  • 例如你给5,答案应该是5的系数,应该由数字0和9组成。
  • 当前代码是否有问题,如果有任何问题,请在您的帖子中提及。
  • 是这个数字只包含0 & 9 不允许任何其他数字或其他数字.....
  • 为什么答案不是0?它可以被 5 整除,并且不包含除 0 和 9 之外的任何数字。或者 0 和 9 都必须是输出的一部分?在那种情况下,3 的输出也会是 90 吗?

标签: c#


【解决方案1】:

如果您乐于使用纯粹的功能,那么这很有效:

Func<IEnumerable<long>> generate = () =>
{
    Func<long, IEnumerable<long>> extend =
        x => new [] { x * 10, x * 10 + 9 };

    Func<IEnumerable<long>, IEnumerable<long>> generate2 = null;
    generate2 = ns =>
    {
        var clean = ns.Where(n => n > 0).ToArray();
        return clean.Any()
            ? clean.Concat(generate2(clean.SelectMany(extend)))
            : Enumerable.Empty<long>();
    };

    return generate2(new[] { 9L, });
};

Func<long, long?> f = n =>
    generate()
        .Where(x => x % n == 0L)
        .Cast<long?>()
        .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) 在 138 毫秒内在我的计算机上返回结果。

【讨论】:

  • 我用超快的功能修改了我的答案。
【解决方案2】:

你可以试试这个方法:

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;
}

关于上面sn-p中奇怪的空for循环,只是语法糖,让代码更短一些。相当于跟着while循环:

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

【讨论】:

  • 我收到错误“!isValid(x * counter)”的“有一些无效参数”。for 循环如何为空但有 {}?
  • 关于for 循环,查看我的更新。关于错误,我没有得到那个错误,在这里工作正常。此示例中的 isValid 函数需要 int 参数,请确保 xcounter 在您的代码中都是 int
【解决方案3】:

使用这个简单的代码

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;
}

【讨论】:

  • 请拿走你的测试数据,导致我的代码产生错误的答案。
  • 您的代码,正如它所代表的那样,产生的结果是0,而不是预期的90
  • 没错,变量 'i' 大部分初始化为 '1' 而不是 '0'。代码回收,测试一下。
【解决方案4】:

我的第一个解决方案性能很差,因为将数字转换为字符串并查找字符“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<long>();
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

900,909,990,999

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

。 . .

【讨论】:

    【解决方案5】:

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

    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();
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-10-01
      • 2016-06-02
      • 1970-01-01
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      相关资源
      最近更新 更多