在字符数组上迭代时检查两个条件

本文关键字:两个 条件 检查 数组 字符 迭代 | 更新日期: 2023-09-27 17:57:36

在学习了C#编程语言的基础知识后,我现在正试图解决我在现实世界中的第一个问题:编写一个程序,在给定字符串的情况下,找到其最长的子字符串,该字符串包含至少一个大写字母,但没有数字(然后显示该最长子字符串的长度)这可能是可接受密码的两个限定条件,例如。。。

下面的代码都是我自己写的,这意味着可能存在性能问题,但这是以后要考虑的。我陷入了必须确保子字符串中没有数字的地步。代码中的注释显示了我在编写程序时的想法。。。

我想,首先我应该检查提取的子字符串中是否有大写字母,如果有,那么我可以将符合条件的子字符串存储在列表中,然后脱离循环。但现在我想知道如何在同一个子字符串中同时检查无数字条件?

我试图保持它的简洁(正如我所说,我刚刚开始编写比几行更长的程序!)所以我认为使用嵌套循环来检查!char.IsNumber(letter)中的每个字符可能不是最佳的。或者我应该先检查一下是否没有数字,然后看看是否至少有一个大写字母?

我对如何实现这两个限制感到困惑,所以我希望能为解决这个问题提供一些帮助。如果您有任何意见建议,我也将不胜感激。例如,可以将我的子字符串存储在列表中吗?我应该做一本字典吗?我的所有可能的子字符串提取嵌套循环是最优的吗?

p.s.有些部分尚未完成;例如,我仍然要实现最后一步,找到最长的子字符串并向用户显示其长度。。。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PasswordRestriction
{
    class Program   /// Write a program that, given a string, finds the longest substring that is a valid password and returns its length.
    {
        static void Main(string[] args)
        {
            // Ask the user for an alphanumeric string.
            Console.WriteLine("Enter a string of alphanumeric values:");
            // Receive the user input as string.
            string password = Console.ReadLine();
            // Print the length of the longest qualifying substring of the user string.
            Console.WriteLine("Length of the longest qualifying substring:'n" + Solution(password).Length );
            // Prevent the console window from closing.
            Console.ReadLine();
        }

        /// The method that exracts the longest substring that is a valid password.
        /// Note that a substring is a 'contiguous' segment of a string.
        public static string Solution(string str)
        {
            // Only allow non-empty strings.
            if ( String.IsNullOrEmpty(str) )
            {
                return "";
            }
            else
            {
                // Only allow letters and digits.
                if ( str.All(char.IsLetterOrDigit) )
                {
                    // A list for containing qualifying substrings.
                    List<string> passwordList = new List<string>();
                    // Generate all possible substrings. Note that
                    // string itself is not a substring of itself!
                    for (int i = 1; i < str.Length; i++)
                    {
                        for (int j = 0; j <= (str.Length-i); j++)
                        {
                            string subStr = str.Substring(j, i);
                            Console.WriteLine(subStr);
                            bool containsNum = false;
                            bool containsUpper = false;
                            // Convert the substrings to arrays of characters with ToCharArray.
                            // This method is called on a string and returns a new character array.
                            // You can manipulate this array in-place, which you cannot do with a string.
                            char[] subStrArray = subStr.ToCharArray();
                            // Go through every character in each substring.
                            // If there is at least one uppercase letter and
                            // no digits, put the qualifying substring in a list.
                            for (int k = 0; k < subStrArray.Length; k++)
                            {
                                char letter = subStrArray[k];
                                if ( char.IsNumber(letter) )
                                {
                                    containsNum = true;
                                    break;
                                }
                                if ( char.IsUpper(letter) )
                                {
                                    containsUpper = true;
                                }
                                if ( containsUpper && (containsNum == false) && (k == subStrArray.Length - 1) )
                                {
                                    Console.WriteLine("Found the above legit password!");
                                    passwordList.Add(subStr);
                                }
                            }
                        }
                    }
                    //Find the longest stored string in the list.
                    //if (passwordList.Count != 0)
                    //{
                        string maxLength = passwordList[0];
                        foreach (string s in passwordList)
                        {
                            if (s.Length > maxLength.Length)
                            {
                                maxLength = s;
                            }
                        }
                    //}
                    // Return the qualifying substring.
                    return maxLength;
                }
                else
                {
                    return "aaaaaaaaaa";
                }
            }
        }
    }
}

在字符数组上迭代时检查两个条件

Linq的一个好问题

  • 不包含数字-数字上的Split
  • 至少一个大写字母-Where+Any
  • 最长(非最短)OrderByDescending
  • 最长(仅一个)-FirstOrDefault

实施

string source = ....
var result = source
  .Split('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
  .Where(line => line.Any(c => c >= 'A' && c <= 'Z')) // or char.IsUpper(c)
  .OrderByDescending(line => line.Length)
  .FirstOrDefault(); // null if there're no such substrings at all

作为Linq答案的替代方案,如果我理解正确,我会这样做,替换str.All条件的内容:

string qualifier;
string tempQualifier;
bool containsUpper = false;
for (int i = 0; i < str.Length(); i++) {
    tempQualifier += str[i];
    if (char.IsNumber(str[i])) {
        if (containsUpper) {
            if (tempQualifier.Length > qualifier.Length && tempQualifier.Length != str.Length) {
                qualifier = tempQualifier;
            }
            containsUpper = false;
        }
        tempQualifier = "";
    } else if (char.IsUpper(str[i])) {
        containsUpper = true;
    }
}
return qualifier;

这将遍历字符串,构建子字符串,直到它遇到一个数字。如果子字符串包含一个大写字母,并且比以前的任何限定符都长,那么它将被存储为新的限定符(也假设它不是所提供字符串的长度)。如果我犯了任何错误(我不精通C#),我深表歉意。

这比Linq的答案要长得多,但我认为你可以方便地看到这个过程的分解,这样你就可以更好地理解它。