【问题标题】:Differentiating between two integers in a string区分字符串中的两个整数
【发布时间】:2017-11-12 18:52:32
【问题描述】:

我一直在处理一个问题,我想识别给定字符串中的所有素数整数(只能被 1 和自身整除的数字)。

我为这个问题编写的逻辑已经完成并且是正确的,但是在调试和测试代码时我遇到了一个有趣的场景。

假设我有以下字符串 This 15 i2s the45best str7ng 1n th3 w0r17ld

现在当上面的字符串通过我的程序运行时,它确定字符串中的素数是5, 2, 5, 7, 3, 7,这是正确的。但是,如果我希望我的程序检查15 是否为素数,而不是单独检查1 是否为素数,然后检查5 是否为素数,或者我想检查素数怎么办? 45 而不是 45

我还想将此问题扩展到一般长度大于 1 位的数字。

以下是完成我所描述的代码:

private static void Main(string[] args)
{
    string sentence = "This 15 i2s the45best str7ng 1n th3 w0r17ld";
    string primes = string.Empty;
    foreach(char c in sentence)
    {
        if (char.IsDigit(c))
        {
            if (isPrime(c - 48))
            {
                primes += c;
            }
        }
    }
    Console.WriteLine(primes.Length > 0 ? $"The prime numbers in\n\n\t{sentence}\n\nare {string.Join<char>(", ", primes)}" : $"There exist no primes in\n\n\t{sentence}");
    Console.ReadLine();
}

private static bool isPrime(int number)
{
    if(number == 3 || number == 2)
    {
        return true;
    }
    if(number % 2 == 0)
    {
        return false;
    }
    for(int i = 3; i < (int)Math.Sqrt(number); i++)
    {
        if(number % i == 0)
        {
            return false;
        }
    }
    return true;
}

【问题讨论】:

  • 显然,您必须编写一些将数字序列视为数字的代码。

标签: c# string primes


【解决方案1】:

让我们把问题分成两个较小的问题:

  1. Extract all integers from the string
  2. Check integer value if it is a prime one

第一个子任务可以借助正则表达式来解决:

  // IEnumerable<int> - we assume that all integers within the string are small enough.
  // If we can face an arbitrary integer sample12345678901234567890123456
  // BigInteger (instead of int) is the solution
  private static IEnumerable<int> ExtractIntValues(string source) {
    return Regex
     .Matches(source, "[0-9]+")
     .OfType<Match>()
     .Select(match => int.Parse(match.Value));
  }

第二个子任务可以实现为(您的代码略有优化)

  private static bool isPrime(int number) {
    if (number <= 1) // 0 and 1 are not primes
      return false;
    if (number % 2 == 0)
      return n == 2;

    int n = (int) (Math.Sqrt(number) + 0.5);

    for (int i = 3; i < n; i += 2) // we have to check odd divisors only
      if (number % i == 0)
        return false;

    return true;   
  } 

最后:

  string sentence = "This 15 i2s the45best str7ng 1n th3 w0r17ld";

  int[] primes = ExtractIntValues(sentence)
    .Where(number => IsPrime(number))
    .ToArray(); 

  Console.WriteLine($"string '{sentence}' contains {primes.Length} prime numbers: {string.Join(", ", primes)}"); 

【讨论】:

    【解决方案2】:

    你可以这样做:

    private static void Main(string[] args)
    {
        string sentence = "This 15 i2s the45best str7ng 1n th3 w0r17ld";
        List<int> primes = new List<int>();
        for (int i = 0; i < sentence.Length; i++)
        {  
            // iterate 'sentence' as long as the neighbour of the current character is a valid digit, then add these digits up to a string
            string nStr = string.Empty;
            while (char.IsDigit(sentence[i]))
            {
                nStr += sentence[i];
                i++;
            }
    
            // if a number was detected and it is a prime number, add it to our list
            if (!string.IsNullOrWhiteSpace(nStr))
            {
                int n = int.Parse(nStr);
                if (IsPrime(n))
                    primes.Add(n);
            }
        }
    
        Console.WriteLine(primes.Count > 0 ? $"The prime numbers in\n\n\t{sentence}\n\nare {string.Join(", ", primes.ToArray())}" : $"There exist no primes in\n\n\t{sentence}");
        Console.ReadLine();
    }
    
    public static bool IsPrime(int number)
    {
        if (number == 1)
            return false;
        if (number == 2)
            return true;
        if (number % 2 == 0)
            return false;
    
        var boundary = (int)Math.Floor(Math.Sqrt(number));
    
        for (int i = 3; i <= boundary; i += 2)
        {
            if (number % i == 0)
                return false;
        }
    
        return true;
    }
    

    请注意:
    我采用了另一个IsPrime 方法,因为你的方法有问题。在这里查看:IsPrime

    【讨论】:

    • (int)Math.Floor(Math.Sqrt(number));dangerous 代码:如果给定的p * pMath.Sqrt 返回的不是p,而是p - ε 怎么办?比如,Sqrt(25) == 4.9999999999999997 在某些平台上,FPU 等?
    猜你喜欢
    • 1970-01-01
    • 2017-09-07
    • 2013-05-24
    • 2023-03-10
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    相关资源
    最近更新 更多