在学习了C#编程语言的基础知识/基础知识之后,我现在正试图解决我的第一个现实问题:编写一个程序,给定一个字符串,找到包含至少一个大写字母但没有数字(然后显示这个最长的子字符串的长度)。这可能是两个符合条件的 strong>可接受密码的条件,例如......
我自己编写了以下代码,这意味着可能存在性能问题,但这是供以后考虑的。我陷入了必须确保子字符串中没有数字的位置。我的代码中的注释显示了我在编写程序时的想法......
我想首先我应该检查一下提取的子字符串中是否有大写字母,如果有,那么我可以将该符合条件的子字符串存储在列表中然后突破循环。但现在我想知道如何在同一个子串中同时检查无数字条件?
我试图保持它整洁简单(正如我所说,我刚开始编写的程序超过几行!)所以我想做一个嵌套循环来检查!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";
}
}
}
}
}
答案 0 :(得分:4)
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
答案 1 :(得分:1)
作为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的答案要长得多,但我认为你看到这个过程失败以便你能更好地理解它是很方便的。